1 ------------------------------------------------------------------------------
3 -- GNAT RUN-TIME COMPONENTS --
5 -- SYSTEM.GENERIC_REAL_LAPACK --
9 -- Copyright (C) 2006, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 with Ada.Unchecked_Conversion; use Ada;
35 with Interfaces; use Interfaces;
36 with Interfaces.Fortran; use Interfaces.Fortran;
37 with Interfaces.Fortran.BLAS; use Interfaces.Fortran.BLAS;
38 with Interfaces.Fortran.LAPACK; use Interfaces.Fortran.LAPACK;
39 with System.Generic_Array_Operations; use System.Generic_Array_Operations;
41 package body System.Generic_Real_LAPACK is
43 Is_Real : constant Boolean :=
44 Real'Machine_Mantissa = Fortran.Real'Machine_Mantissa
45 and then Fortran.Real (Real'First) = Fortran.Real'First
46 and then Fortran.Real (Real'Last) = Fortran.Real'Last;
48 Is_Double_Precision : constant Boolean :=
49 Real'Machine_Mantissa =
50 Double_Precision'Machine_Mantissa
52 Double_Precision (Real'First) =
53 Double_Precision'First
55 Double_Precision (Real'Last) =
56 Double_Precision'Last;
60 function To_Double_Precision (X : Real) return Double_Precision;
61 pragma Inline_Always (To_Double_Precision);
63 function To_Real (X : Double_Precision) return Real;
64 pragma Inline_Always (To_Real);
68 function To_Double_Precision is new
69 Vector_Elementwise_Operation
71 Result_Scalar => Double_Precision,
72 X_Vector => Real_Vector,
73 Result_Vector => Double_Precision_Vector,
74 Operation => To_Double_Precision);
76 function To_Real is new
77 Vector_Elementwise_Operation
78 (X_Scalar => Double_Precision,
79 Result_Scalar => Real,
80 X_Vector => Double_Precision_Vector,
81 Result_Vector => Real_Vector,
82 Operation => To_Real);
84 function To_Double_Precision is new
85 Matrix_Elementwise_Operation
87 Result_Scalar => Double_Precision,
88 X_Matrix => Real_Matrix,
89 Result_Matrix => Double_Precision_Matrix,
90 Operation => To_Double_Precision);
92 function To_Real is new
93 Matrix_Elementwise_Operation
94 (X_Scalar => Double_Precision,
95 Result_Scalar => Real,
96 X_Matrix => Double_Precision_Matrix,
97 Result_Matrix => Real_Matrix,
98 Operation => To_Real);
100 function To_Double_Precision (X : Real) return Double_Precision is
102 return Double_Precision (X);
103 end To_Double_Precision;
105 function To_Real (X : Double_Precision) return Real is
117 A : in out Real_Matrix;
119 I_Piv : out Integer_Vector;
120 Info : access Integer)
126 access all BLAS.Real_Matrix (A'Range (1), A'Range (2));
127 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
129 sgetrf (M, N, Conv_A (A'Address).all, Ld_A,
130 LAPACK.Integer_Vector (I_Piv), Info);
133 elsif Is_Double_Precision then
136 access all Double_Precision_Matrix (A'Range (1), A'Range (2));
137 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
139 dgetrf (M, N, Conv_A (A'Address).all, Ld_A,
140 LAPACK.Integer_Vector (I_Piv), Info);
145 DP_A : Double_Precision_Matrix (A'Range (1), A'Range (2));
147 DP_A := To_Double_Precision (A);
148 dgetrf (M, N, DP_A, Ld_A, LAPACK.Integer_Vector (I_Piv), Info);
160 A : in out Real_Matrix;
162 I_Piv : Integer_Vector;
163 Work : in out Real_Vector;
165 Info : access Integer)
171 access all BLAS.Real_Matrix (A'Range (1), A'Range (2));
173 access all BLAS.Real_Vector (Work'Range);
174 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
175 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
177 sgetri (N, Conv_A (A'Address).all, Ld_A,
178 LAPACK.Integer_Vector (I_Piv),
179 Conv_Work (Work'Address).all, L_Work,
183 elsif Is_Double_Precision then
186 access all Double_Precision_Matrix (A'Range (1), A'Range (2));
188 access all Double_Precision_Vector (Work'Range);
189 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
190 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
192 dgetri (N, Conv_A (A'Address).all, Ld_A,
193 LAPACK.Integer_Vector (I_Piv),
194 Conv_Work (Work'Address).all, L_Work,
200 DP_A : Double_Precision_Matrix (A'Range (1), A'Range (2));
201 DP_Work : Double_Precision_Vector (Work'Range);
203 DP_A := To_Double_Precision (A);
204 dgetri (N, DP_A, Ld_A, LAPACK.Integer_Vector (I_Piv),
205 DP_Work, L_Work, Info);
207 Work (1) := To_Real (DP_Work (1));
217 (Trans : access constant Character;
222 I_Piv : Integer_Vector;
223 B : in out Real_Matrix;
225 Info : access Integer)
230 subtype A_Type is BLAS.Real_Matrix (A'Range (1), A'Range (2));
232 access all BLAS.Real_Matrix (B'Range (1), B'Range (2));
233 function Conv_A is new Unchecked_Conversion (Real_Matrix, A_Type);
234 function Conv_B is new Unchecked_Conversion (Address, B_Ptr);
236 sgetrs (Trans, N, N_Rhs,
238 LAPACK.Integer_Vector (I_Piv),
239 Conv_B (B'Address).all, Ld_B,
243 elsif Is_Double_Precision then
246 Double_Precision_Matrix (A'Range (1), A'Range (2));
248 access all Double_Precision_Matrix (B'Range (1), B'Range (2));
249 function Conv_A is new Unchecked_Conversion (Real_Matrix, A_Type);
250 function Conv_B is new Unchecked_Conversion (Address, B_Ptr);
252 dgetrs (Trans, N, N_Rhs,
254 LAPACK.Integer_Vector (I_Piv),
255 Conv_B (B'Address).all, Ld_B,
261 DP_A : Double_Precision_Matrix (A'Range (1), A'Range (2));
262 DP_B : Double_Precision_Matrix (B'Range (1), B'Range (2));
264 DP_A := To_Double_Precision (A);
265 DP_B := To_Double_Precision (B);
266 dgetrs (Trans, N, N_Rhs,
268 LAPACK.Integer_Vector (I_Piv),
281 (Uplo : access constant Character;
283 A : in out Real_Matrix;
285 Tau : in Real_Vector;
286 Work : out Real_Vector;
288 Info : access Integer)
294 access all BLAS.Real_Matrix (A'Range (1), A'Range (2));
295 subtype Tau_Type is BLAS.Real_Vector (Tau'Range);
297 access all BLAS.Real_Vector (Work'Range);
298 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
300 new Unchecked_Conversion (Real_Vector, Tau_Type);
301 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
304 Conv_A (A'Address).all, Ld_A,
306 Conv_Work (Work'Address).all, L_Work,
310 elsif Is_Double_Precision then
313 access all Double_Precision_Matrix (A'Range (1), A'Range (2));
314 subtype Tau_Type is Double_Precision_Vector (Tau'Range);
316 access all Double_Precision_Vector (Work'Range);
317 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
319 new Unchecked_Conversion (Real_Vector, Tau_Type);
320 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
323 Conv_A (A'Address).all, Ld_A,
325 Conv_Work (Work'Address).all, L_Work,
331 DP_A : Double_Precision_Matrix (A'Range (1), A'Range (2));
332 DP_Work : Double_Precision_Vector (Work'Range);
333 DP_Tau : Double_Precision_Vector (Tau'Range);
335 DP_A := To_Double_Precision (A);
336 DP_Tau := To_Double_Precision (Tau);
337 dorgtr (Uplo, N, DP_A, Ld_A, DP_Tau, DP_Work, L_Work, Info);
339 Work (1) := To_Real (DP_Work (1));
349 (Comp_Z : access constant Character;
351 D : in out Real_Vector;
352 E : in out Real_Vector;
353 Z : in out Real_Matrix;
355 Work : out Real_Vector;
356 Info : access Integer)
361 type D_Ptr is access all BLAS.Real_Vector (D'Range);
362 type E_Ptr is access all BLAS.Real_Vector (E'Range);
364 access all BLAS.Real_Matrix (Z'Range (1), Z'Range (2));
366 access all BLAS.Real_Vector (Work'Range);
367 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
368 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
369 function Conv_Z is new Unchecked_Conversion (Address, Z_Ptr);
370 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
373 Conv_D (D'Address).all,
374 Conv_E (E'Address).all,
375 Conv_Z (Z'Address).all,
377 Conv_Work (Work'Address).all,
381 elsif Is_Double_Precision then
383 type D_Ptr is access all Double_Precision_Vector (D'Range);
384 type E_Ptr is access all Double_Precision_Vector (E'Range);
386 access all Double_Precision_Matrix (Z'Range (1), Z'Range (2));
388 access all Double_Precision_Vector (Work'Range);
389 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
390 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
391 function Conv_Z is new Unchecked_Conversion (Address, Z_Ptr);
392 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
395 Conv_D (D'Address).all,
396 Conv_E (E'Address).all,
397 Conv_Z (Z'Address).all,
399 Conv_Work (Work'Address).all,
405 DP_D : Double_Precision_Vector (D'Range);
406 DP_E : Double_Precision_Vector (E'Range);
407 DP_Z : Double_Precision_Matrix (Z'Range (1), Z'Range (2));
408 DP_Work : Double_Precision_Vector (Work'Range);
410 DP_D := To_Double_Precision (D);
411 DP_E := To_Double_Precision (E);
413 if Comp_Z.all = 'V' then
414 DP_Z := To_Double_Precision (Z);
417 dsteqr (Comp_Z, N, DP_D, DP_E, DP_Z, Ld_Z, DP_Work, Info);
432 D : in out Real_Vector;
433 E : in out Real_Vector;
434 Info : access Integer)
439 type D_Ptr is access all BLAS.Real_Vector (D'Range);
440 type E_Ptr is access all BLAS.Real_Vector (E'Range);
441 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
442 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
444 ssterf (N, Conv_D (D'Address).all, Conv_E (E'Address).all, Info);
447 elsif Is_Double_Precision then
449 type D_Ptr is access all Double_Precision_Vector (D'Range);
450 type E_Ptr is access all Double_Precision_Vector (E'Range);
451 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
452 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
454 dsterf (N, Conv_D (D'Address).all, Conv_E (E'Address).all, Info);
459 DP_D : Double_Precision_Vector (D'Range);
460 DP_E : Double_Precision_Vector (E'Range);
463 DP_D := To_Double_Precision (D);
464 DP_E := To_Double_Precision (E);
466 dsterf (N, DP_D, DP_E, Info);
479 (Uplo : access constant Character;
481 A : in out Real_Matrix;
485 Tau : out Real_Vector;
486 Work : out Real_Vector;
488 Info : access Integer)
494 access all BLAS.Real_Matrix (A'Range (1), A'Range (2));
495 type D_Ptr is access all BLAS.Real_Vector (D'Range);
496 type E_Ptr is access all BLAS.Real_Vector (E'Range);
497 type Tau_Ptr is access all BLAS.Real_Vector (Tau'Range);
499 access all BLAS.Real_Vector (Work'Range);
500 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
501 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
502 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
503 function Conv_Tau is new Unchecked_Conversion (Address, Tau_Ptr);
504 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
507 Conv_A (A'Address).all, Ld_A,
508 Conv_D (D'Address).all,
509 Conv_E (E'Address).all,
510 Conv_Tau (Tau'Address).all,
511 Conv_Work (Work'Address).all,
516 elsif Is_Double_Precision then
519 access all Double_Precision_Matrix (A'Range (1), A'Range (2));
520 type D_Ptr is access all Double_Precision_Vector (D'Range);
521 type E_Ptr is access all Double_Precision_Vector (E'Range);
522 type Tau_Ptr is access all Double_Precision_Vector (Tau'Range);
524 access all Double_Precision_Vector (Work'Range);
525 function Conv_A is new Unchecked_Conversion (Address, A_Ptr);
526 function Conv_D is new Unchecked_Conversion (Address, D_Ptr);
527 function Conv_E is new Unchecked_Conversion (Address, E_Ptr);
528 function Conv_Tau is new Unchecked_Conversion (Address, Tau_Ptr);
529 function Conv_Work is new Unchecked_Conversion (Address, Work_Ptr);
532 Conv_A (A'Address).all, Ld_A,
533 Conv_D (D'Address).all,
534 Conv_E (E'Address).all,
535 Conv_Tau (Tau'Address).all,
536 Conv_Work (Work'Address).all,
543 DP_A : Double_Precision_Matrix (A'Range (1), A'Range (2));
544 DP_D : Double_Precision_Vector (D'Range);
545 DP_E : Double_Precision_Vector (E'Range);
546 DP_Tau : Double_Precision_Vector (Tau'Range);
547 DP_Work : Double_Precision_Vector (Work'Range);
549 DP_A := To_Double_Precision (A);
551 dsytrd (Uplo, N, DP_A, Ld_A, DP_D, DP_E, DP_Tau,
552 DP_Work, L_Work, Info);
558 Tau := To_Real (DP_Tau);
561 Work (1) := To_Real (DP_Work (1));
566 end System.Generic_Real_LAPACK;