OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [ada/] [a-ngrear.adb] - Blame information for rev 843

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT RUN-TIME COMPONENTS                         --
4
--                                                                          --
5
--                     ADA.NUMERICS.GENERIC_REAL_ARRAYS                     --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 2006-2009, Free Software Foundation, Inc.         --
10
--                                                                          --
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 3,  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.                                     --
17
--                                                                          --
18
-- As a special exception under Section 7 of GPL version 3, you are granted --
19
-- additional permissions described in the GCC Runtime Library Exception,   --
20
-- version 3.1, as published by the Free Software Foundation.               --
21
--                                                                          --
22
-- You should have received a copy of the GNU General Public License and    --
23
-- a copy of the GCC Runtime Library Exception along with this program;     --
24
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25
-- <http://www.gnu.org/licenses/>.                                          --
26
--                                                                          --
27
-- GNAT was originally developed  by the GNAT team at  New York University. --
28
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29
--                                                                          --
30
------------------------------------------------------------------------------
31
 
32
with System; use System;
33
with System.Generic_Real_BLAS;
34
with System.Generic_Real_LAPACK;
35
with System.Generic_Array_Operations; use System.Generic_Array_Operations;
36
 
37
package body Ada.Numerics.Generic_Real_Arrays is
38
 
39
   --  Operations involving inner products use BLAS library implementations.
40
   --  This allows larger matrices and vectors to be computed efficiently,
41
   --  taking into account memory hierarchy issues and vector instructions
42
   --  that vary widely between machines.
43
 
44
   --  Operations that are defined in terms of operations on the type Real,
45
   --  such as addition, subtraction and scaling, are computed in the canonical
46
   --  way looping over all elements.
47
 
48
   --  Operations for solving linear systems and computing determinant,
49
   --  eigenvalues, eigensystem and inverse, are implemented using the
50
   --  LAPACK library.
51
 
52
   package BLAS is
53
      new Generic_Real_BLAS (Real'Base, Real_Vector, Real_Matrix);
54
 
55
   package LAPACK is
56
      new Generic_Real_LAPACK (Real'Base, Real_Vector, Real_Matrix);
57
 
58
   use BLAS, LAPACK;
59
 
60
   --  Procedure versions of functions returning unconstrained values.
61
   --  This allows for inlining the function wrapper.
62
 
63
   procedure Eigenvalues (A : Real_Matrix; Values : out Real_Vector);
64
   procedure Inverse   (A : Real_Matrix; R : out Real_Matrix);
65
   procedure Solve     (A : Real_Matrix; X : Real_Vector; B : out Real_Vector);
66
   procedure Solve     (A : Real_Matrix; X : Real_Matrix; B : out Real_Matrix);
67
 
68
   procedure Transpose is new
69
     Generic_Array_Operations.Transpose
70
       (Scalar        => Real'Base,
71
        Matrix        => Real_Matrix);
72
 
73
   --  Helper function that raises a Constraint_Error is the argument is
74
   --  not a square matrix, and otherwise returns its length.
75
 
76
   function Length is new Square_Matrix_Length (Real'Base, Real_Matrix);
77
 
78
   --  Instantiating the following subprograms directly would lead to
79
   --  name clashes, so use a local package.
80
 
81
   package Instantiations is
82
 
83
      function "+" is new
84
        Vector_Elementwise_Operation
85
          (X_Scalar      => Real'Base,
86
           Result_Scalar => Real'Base,
87
           X_Vector      => Real_Vector,
88
           Result_Vector => Real_Vector,
89
           Operation     => "+");
90
 
91
      function "+" is new
92
        Matrix_Elementwise_Operation
93
          (X_Scalar      => Real'Base,
94
           Result_Scalar => Real'Base,
95
           X_Matrix      => Real_Matrix,
96
           Result_Matrix => Real_Matrix,
97
           Operation     => "+");
98
 
99
      function "+" is new
100
        Vector_Vector_Elementwise_Operation
101
          (Left_Scalar   => Real'Base,
102
           Right_Scalar  => Real'Base,
103
           Result_Scalar => Real'Base,
104
           Left_Vector   => Real_Vector,
105
           Right_Vector  => Real_Vector,
106
           Result_Vector => Real_Vector,
107
           Operation     => "+");
108
 
109
      function "+" is new
110
        Matrix_Matrix_Elementwise_Operation
111
          (Left_Scalar   => Real'Base,
112
           Right_Scalar  => Real'Base,
113
           Result_Scalar => Real'Base,
114
           Left_Matrix   => Real_Matrix,
115
           Right_Matrix  => Real_Matrix,
116
           Result_Matrix => Real_Matrix,
117
           Operation     => "+");
118
 
119
      function "-" is new
120
        Vector_Elementwise_Operation
121
          (X_Scalar      => Real'Base,
122
           Result_Scalar => Real'Base,
123
           X_Vector      => Real_Vector,
124
           Result_Vector => Real_Vector,
125
           Operation     => "-");
126
 
127
      function "-" is new
128
        Matrix_Elementwise_Operation
129
          (X_Scalar      => Real'Base,
130
           Result_Scalar => Real'Base,
131
           X_Matrix      => Real_Matrix,
132
           Result_Matrix => Real_Matrix,
133
           Operation     => "-");
134
 
135
      function "-" is new
136
        Vector_Vector_Elementwise_Operation
137
          (Left_Scalar   => Real'Base,
138
           Right_Scalar  => Real'Base,
139
           Result_Scalar => Real'Base,
140
           Left_Vector   => Real_Vector,
141
           Right_Vector  => Real_Vector,
142
           Result_Vector => Real_Vector,
143
           Operation     => "-");
144
 
145
      function "-" is new
146
        Matrix_Matrix_Elementwise_Operation
147
          (Left_Scalar   => Real'Base,
148
           Right_Scalar  => Real'Base,
149
           Result_Scalar => Real'Base,
150
           Left_Matrix   => Real_Matrix,
151
           Right_Matrix  => Real_Matrix,
152
           Result_Matrix => Real_Matrix,
153
           Operation     => "-");
154
 
155
      function "*" is new
156
        Scalar_Vector_Elementwise_Operation
157
          (Left_Scalar   => Real'Base,
158
           Right_Scalar  => Real'Base,
159
           Result_Scalar => Real'Base,
160
           Right_Vector  => Real_Vector,
161
           Result_Vector => Real_Vector,
162
           Operation     => "*");
163
 
164
      function "*" is new
165
        Scalar_Matrix_Elementwise_Operation
166
          (Left_Scalar   => Real'Base,
167
           Right_Scalar  => Real'Base,
168
           Result_Scalar => Real'Base,
169
           Right_Matrix  => Real_Matrix,
170
           Result_Matrix => Real_Matrix,
171
           Operation     => "*");
172
 
173
      function "*" is new
174
        Vector_Scalar_Elementwise_Operation
175
          (Left_Scalar   => Real'Base,
176
           Right_Scalar  => Real'Base,
177
           Result_Scalar => Real'Base,
178
           Left_Vector   => Real_Vector,
179
           Result_Vector => Real_Vector,
180
           Operation     => "*");
181
 
182
      function "*" is new
183
        Matrix_Scalar_Elementwise_Operation
184
          (Left_Scalar   => Real'Base,
185
           Right_Scalar  => Real'Base,
186
           Result_Scalar => Real'Base,
187
           Left_Matrix   => Real_Matrix,
188
           Result_Matrix => Real_Matrix,
189
           Operation     => "*");
190
 
191
      function "*" is new
192
        Outer_Product
193
          (Left_Scalar   => Real'Base,
194
           Right_Scalar  => Real'Base,
195
           Result_Scalar => Real'Base,
196
           Left_Vector   => Real_Vector,
197
           Right_Vector  => Real_Vector,
198
           Matrix        => Real_Matrix);
199
 
200
      function "/" is new
201
        Vector_Scalar_Elementwise_Operation
202
          (Left_Scalar   => Real'Base,
203
           Right_Scalar  => Real'Base,
204
           Result_Scalar => Real'Base,
205
           Left_Vector   => Real_Vector,
206
           Result_Vector => Real_Vector,
207
           Operation     => "/");
208
 
209
      function "/" is new
210
        Matrix_Scalar_Elementwise_Operation
211
          (Left_Scalar   => Real'Base,
212
           Right_Scalar  => Real'Base,
213
           Result_Scalar => Real'Base,
214
           Left_Matrix   => Real_Matrix,
215
           Result_Matrix => Real_Matrix,
216
           Operation     => "/");
217
 
218
      function "abs" is new
219
        Vector_Elementwise_Operation
220
          (X_Scalar      => Real'Base,
221
           Result_Scalar => Real'Base,
222
           X_Vector      => Real_Vector,
223
           Result_Vector => Real_Vector,
224
           Operation     => "abs");
225
 
226
      function "abs" is new
227
        Matrix_Elementwise_Operation
228
          (X_Scalar      => Real'Base,
229
           Result_Scalar => Real'Base,
230
           X_Matrix      => Real_Matrix,
231
           Result_Matrix => Real_Matrix,
232
           Operation     => "abs");
233
 
234
      function Unit_Matrix is new
235
        Generic_Array_Operations.Unit_Matrix
236
          (Scalar        => Real'Base,
237
           Matrix        => Real_Matrix,
238
           Zero          => 0.0,
239
           One           => 1.0);
240
 
241
      function Unit_Vector is new
242
        Generic_Array_Operations.Unit_Vector
243
          (Scalar        => Real'Base,
244
           Vector        => Real_Vector,
245
           Zero          => 0.0,
246
           One           => 1.0);
247
 
248
   end Instantiations;
249
 
250
   ---------
251
   -- "+" --
252
   ---------
253
 
254
   function "+" (Right : Real_Vector) return Real_Vector
255
      renames Instantiations."+";
256
 
257
   function "+" (Right : Real_Matrix) return Real_Matrix
258
      renames Instantiations."+";
259
 
260
   function "+" (Left, Right : Real_Vector) return Real_Vector
261
      renames Instantiations."+";
262
 
263
   function "+" (Left, Right : Real_Matrix) return Real_Matrix
264
      renames Instantiations."+";
265
 
266
   ---------
267
   -- "-" --
268
   ---------
269
 
270
   function "-" (Right : Real_Vector) return Real_Vector
271
      renames Instantiations."-";
272
 
273
   function "-" (Right : Real_Matrix) return Real_Matrix
274
      renames Instantiations."-";
275
 
276
   function "-" (Left, Right : Real_Vector) return Real_Vector
277
      renames Instantiations."-";
278
 
279
   function "-" (Left, Right : Real_Matrix) return Real_Matrix
280
      renames Instantiations."-";
281
 
282
   ---------
283
   -- "*" --
284
   ---------
285
 
286
   --  Scalar multiplication
287
 
288
   function "*" (Left : Real'Base; Right : Real_Vector) return Real_Vector
289
      renames Instantiations."*";
290
 
291
   function "*" (Left : Real_Vector; Right : Real'Base) return Real_Vector
292
      renames Instantiations."*";
293
 
294
   function "*" (Left : Real'Base; Right : Real_Matrix) return Real_Matrix
295
      renames Instantiations."*";
296
 
297
   function "*" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix
298
      renames Instantiations."*";
299
 
300
   --  Vector multiplication
301
 
302
   function "*" (Left, Right : Real_Vector) return Real'Base is
303
   begin
304
      if Left'Length /= Right'Length then
305
         raise Constraint_Error with
306
            "vectors are of different length in inner product";
307
      end if;
308
 
309
      return dot (Left'Length, X => Left, Y => Right);
310
   end "*";
311
 
312
   function "*" (Left, Right : Real_Vector) return Real_Matrix
313
      renames Instantiations."*";
314
 
315
   function "*"
316
     (Left : Real_Vector;
317
      Right : Real_Matrix) return Real_Vector
318
   is
319
      R : Real_Vector (Right'Range (2));
320
 
321
   begin
322
      if Left'Length /= Right'Length (1) then
323
         raise Constraint_Error with
324
           "incompatible dimensions in vector-matrix multiplication";
325
      end if;
326
 
327
      gemv (Trans => No_Trans'Access,
328
            M     => Right'Length (2),
329
            N     => Right'Length (1),
330
            A     => Right,
331
            Ld_A  => Right'Length (2),
332
            X     => Left,
333
            Y     => R);
334
 
335
      return R;
336
   end "*";
337
 
338
   function "*"
339
     (Left : Real_Matrix;
340
      Right : Real_Vector) return Real_Vector
341
   is
342
      R : Real_Vector (Left'Range (1));
343
 
344
   begin
345
      if Left'Length (2) /= Right'Length then
346
         raise Constraint_Error with
347
            "incompatible dimensions in matrix-vector multiplication";
348
      end if;
349
 
350
      gemv (Trans => Trans'Access,
351
            M     => Left'Length (2),
352
            N     => Left'Length (1),
353
            A     => Left,
354
            Ld_A  => Left'Length (2),
355
            X     => Right,
356
            Y     => R);
357
 
358
      return R;
359
   end "*";
360
 
361
   --  Matrix Multiplication
362
 
363
   function "*" (Left, Right : Real_Matrix) return Real_Matrix is
364
      R : Real_Matrix (Left'Range (1), Right'Range (2));
365
 
366
   begin
367
      if Left'Length (2) /= Right'Length (1) then
368
         raise Constraint_Error with
369
            "incompatible dimensions in matrix-matrix multiplication";
370
      end if;
371
 
372
      gemm (Trans_A => No_Trans'Access,
373
            Trans_B => No_Trans'Access,
374
            M       => Right'Length (2),
375
            N       => Left'Length (1),
376
            K       => Right'Length (1),
377
            A       => Right,
378
            Ld_A    => Right'Length (2),
379
            B       => Left,
380
            Ld_B    => Left'Length (2),
381
            C       => R,
382
            Ld_C    => R'Length (2));
383
 
384
      return R;
385
   end "*";
386
 
387
   ---------
388
   -- "/" --
389
   ---------
390
 
391
   function "/" (Left : Real_Vector; Right : Real'Base) return Real_Vector
392
      renames Instantiations."/";
393
 
394
   function "/" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix
395
      renames Instantiations."/";
396
 
397
   -----------
398
   -- "abs" --
399
   -----------
400
 
401
   function "abs" (Right : Real_Vector) return Real'Base is
402
   begin
403
      return nrm2 (Right'Length, Right);
404
   end "abs";
405
 
406
   function "abs" (Right : Real_Vector) return Real_Vector
407
      renames Instantiations."abs";
408
 
409
   function "abs" (Right : Real_Matrix) return Real_Matrix
410
      renames Instantiations."abs";
411
 
412
   -----------------
413
   -- Determinant --
414
   -----------------
415
 
416
   function Determinant (A : Real_Matrix) return Real'Base is
417
      N    : constant Integer := Length (A);
418
      LU   : Real_Matrix (1 .. N, 1 .. N) := A;
419
      Piv  : Integer_Vector (1 .. N);
420
      Info : aliased Integer := -1;
421
      Det  : Real := 1.0;
422
 
423
   begin
424
      getrf (M     => N,
425
             N     => N,
426
             A     => LU,
427
             Ld_A  => N,
428
             I_Piv => Piv,
429
             Info  => Info'Access);
430
 
431
      if Info /= 0 then
432
         raise Constraint_Error with "ill-conditioned matrix";
433
      end if;
434
 
435
      for J in 1 .. N loop
436
         Det := (if Piv (J) /= J then -Det * LU (J, J) else Det * LU (J, J));
437
      end loop;
438
 
439
      return Det;
440
   end Determinant;
441
 
442
   -----------------
443
   -- Eigensystem --
444
   -----------------
445
 
446
   procedure Eigensystem
447
     (A       : Real_Matrix;
448
      Values  : out Real_Vector;
449
      Vectors : out Real_Matrix)
450
   is
451
      N      : constant Natural := Length (A);
452
      Tau    : Real_Vector (1 .. N);
453
      L_Work : Real_Vector (1 .. 1);
454
      Info   : aliased Integer;
455
 
456
      E : Real_Vector (1 .. N);
457
      pragma Warnings (Off, E);
458
 
459
   begin
460
      if Values'Length /= N then
461
         raise Constraint_Error with "wrong length for output vector";
462
      end if;
463
 
464
      if N = 0 then
465
         return;
466
      end if;
467
 
468
      --  Initialize working matrix and check for symmetric input matrix
469
 
470
      Transpose (A, Vectors);
471
 
472
      if A /= Vectors then
473
         raise Argument_Error with "matrix not symmetric";
474
      end if;
475
 
476
      --  Compute size of additional working space
477
 
478
      sytrd (Uplo   => Lower'Access,
479
             N      => N,
480
             A      => Vectors,
481
             Ld_A   => N,
482
             D      => Values,
483
             E      => E,
484
             Tau    => Tau,
485
             Work   => L_Work,
486
             L_Work => -1,
487
             Info   => Info'Access);
488
 
489
      declare
490
         Work : Real_Vector (1 .. Integer'Max (Integer (L_Work (1)), 2 * N));
491
         pragma Warnings (Off, Work);
492
 
493
         Comp_Z : aliased constant Character := 'V';
494
 
495
      begin
496
         --  Reduce matrix to tridiagonal form
497
 
498
         sytrd (Uplo   => Lower'Access,
499
                N      => N,
500
                A      => Vectors,
501
                Ld_A   => A'Length (1),
502
                D      => Values,
503
                E      => E,
504
                Tau    => Tau,
505
                Work   => Work,
506
                L_Work => Work'Length,
507
                Info   => Info'Access);
508
 
509
         if Info /= 0 then
510
            raise Program_Error;
511
         end if;
512
 
513
         --  Generate the real orthogonal matrix determined by sytrd
514
 
515
         orgtr (Uplo   => Lower'Access,
516
                N      => N,
517
                A      => Vectors,
518
                Ld_A   => N,
519
                Tau    => Tau,
520
                Work   => Work,
521
                L_Work => Work'Length,
522
                Info   => Info'Access);
523
 
524
         if Info /= 0 then
525
            raise Program_Error;
526
         end if;
527
 
528
         --  Compute all eigenvalues and eigenvectors using QR algorithm
529
 
530
         steqr (Comp_Z => Comp_Z'Access,
531
                N      => N,
532
                D      => Values,
533
                E      => E,
534
                Z      => Vectors,
535
                Ld_Z   => N,
536
                Work   => Work,
537
                Info   => Info'Access);
538
 
539
         if Info /= 0 then
540
            raise Constraint_Error with
541
               "eigensystem computation failed to converge";
542
         end if;
543
      end;
544
   end Eigensystem;
545
 
546
   -----------------
547
   -- Eigenvalues --
548
   -----------------
549
 
550
   procedure Eigenvalues
551
     (A      : Real_Matrix;
552
      Values : out Real_Vector)
553
   is
554
      N      : constant Natural := Length (A);
555
      L_Work : Real_Vector (1 .. 1);
556
      Info   : aliased Integer;
557
 
558
      B   : Real_Matrix (1 .. N, 1 .. N);
559
      Tau : Real_Vector (1 .. N);
560
      E   : Real_Vector (1 .. N);
561
      pragma Warnings (Off, B);
562
      pragma Warnings (Off, Tau);
563
      pragma Warnings (Off, E);
564
 
565
   begin
566
      if Values'Length /= N then
567
         raise Constraint_Error with "wrong length for output vector";
568
      end if;
569
 
570
      if N = 0 then
571
         return;
572
      end if;
573
 
574
      --  Initialize working matrix and check for symmetric input matrix
575
 
576
      Transpose (A, B);
577
 
578
      if A /= B then
579
         raise Argument_Error with "matrix not symmetric";
580
      end if;
581
 
582
      --  Find size of work area
583
 
584
      sytrd (Uplo   => Lower'Access,
585
             N      => N,
586
             A      => B,
587
             Ld_A   => N,
588
             D      => Values,
589
             E      => E,
590
             Tau    => Tau,
591
             Work   => L_Work,
592
             L_Work => -1,
593
             Info   => Info'Access);
594
 
595
      declare
596
         Work : Real_Vector (1 .. Integer'Min (Integer (L_Work (1)), 4 * N));
597
         pragma Warnings (Off, Work);
598
 
599
      begin
600
         --  Reduce matrix to tridiagonal form
601
 
602
         sytrd (Uplo   => Lower'Access,
603
                N      => N,
604
                A      => B,
605
                Ld_A   => A'Length (1),
606
                D      => Values,
607
                E      => E,
608
                Tau    => Tau,
609
                Work   => Work,
610
                L_Work => Work'Length,
611
                Info   => Info'Access);
612
 
613
         if Info /= 0 then
614
            raise Constraint_Error;
615
         end if;
616
 
617
         --  Compute all eigenvalues using QR algorithm
618
 
619
         sterf (N      => N,
620
                D      => Values,
621
                E      => E,
622
                Info   => Info'Access);
623
 
624
         if Info /= 0 then
625
            raise Constraint_Error with
626
               "eigenvalues computation failed to converge";
627
         end if;
628
      end;
629
   end Eigenvalues;
630
 
631
   function Eigenvalues (A : Real_Matrix) return Real_Vector is
632
      R : Real_Vector (A'Range (1));
633
   begin
634
      Eigenvalues (A, R);
635
      return R;
636
   end Eigenvalues;
637
 
638
   -------------
639
   -- Inverse --
640
   -------------
641
 
642
   procedure Inverse (A : Real_Matrix; R : out Real_Matrix) is
643
      N      : constant Integer := Length (A);
644
      Piv    : Integer_Vector (1 .. N);
645
      L_Work : Real_Vector (1 .. 1);
646
      Info   : aliased Integer := -1;
647
 
648
   begin
649
      --  All computations are done using column-major order, but this works
650
      --  out fine, because Transpose (Inverse (Transpose (A))) = Inverse (A).
651
 
652
      R := A;
653
 
654
      --  Compute LU decomposition
655
 
656
      getrf (M      => N,
657
             N      => N,
658
             A      => R,
659
             Ld_A   => N,
660
             I_Piv  => Piv,
661
             Info   => Info'Access);
662
 
663
      if Info /= 0 then
664
         raise Constraint_Error with "inverting singular matrix";
665
      end if;
666
 
667
      --  Determine size of work area
668
 
669
      getri (N      => N,
670
             A      => R,
671
             Ld_A   => N,
672
             I_Piv  => Piv,
673
             Work   => L_Work,
674
             L_Work => -1,
675
             Info   => Info'Access);
676
 
677
      if Info /= 0 then
678
         raise Constraint_Error;
679
      end if;
680
 
681
      declare
682
         Work : Real_Vector (1 .. Integer (L_Work (1)));
683
         pragma Warnings (Off, Work);
684
 
685
      begin
686
         --  Compute inverse from LU decomposition
687
 
688
         getri (N      => N,
689
                A      => R,
690
                Ld_A   => N,
691
                I_Piv  => Piv,
692
                Work   => Work,
693
                L_Work => Work'Length,
694
                Info   => Info'Access);
695
 
696
         if Info /= 0 then
697
            raise Constraint_Error with "inverting singular matrix";
698
         end if;
699
 
700
         --  ??? Should iterate with gerfs, based on implementation advice
701
      end;
702
   end Inverse;
703
 
704
   function Inverse (A : Real_Matrix) return Real_Matrix is
705
      R : Real_Matrix (A'Range (2), A'Range (1));
706
   begin
707
      Inverse (A, R);
708
      return R;
709
   end Inverse;
710
 
711
   -----------
712
   -- Solve --
713
   -----------
714
 
715
   procedure Solve (A : Real_Matrix; X : Real_Vector; B : out Real_Vector) is
716
   begin
717
      if Length (A) /= X'Length then
718
         raise Constraint_Error with
719
           "incompatible matrix and vector dimensions";
720
      end if;
721
 
722
      --  ??? Should solve directly, is faster and more accurate
723
 
724
      B := Inverse (A) * X;
725
   end Solve;
726
 
727
   procedure Solve (A : Real_Matrix; X : Real_Matrix; B : out Real_Matrix) is
728
   begin
729
      if Length (A) /= X'Length (1) then
730
         raise Constraint_Error with "incompatible matrix dimensions";
731
      end if;
732
 
733
      --  ??? Should solve directly, is faster and more accurate
734
 
735
      B := Inverse (A) * X;
736
   end Solve;
737
 
738
   function Solve (A : Real_Matrix; X : Real_Vector) return Real_Vector is
739
      B : Real_Vector (A'Range (2));
740
   begin
741
      Solve (A, X, B);
742
      return B;
743
   end Solve;
744
 
745
   function Solve (A, X : Real_Matrix) return Real_Matrix is
746
      B : Real_Matrix (A'Range (2), X'Range (2));
747
   begin
748
      Solve (A, X, B);
749
      return B;
750
   end Solve;
751
 
752
   ---------------
753
   -- Transpose --
754
   ---------------
755
 
756
   function Transpose (X : Real_Matrix) return Real_Matrix is
757
      R : Real_Matrix (X'Range (2), X'Range (1));
758
   begin
759
      Transpose (X, R);
760
 
761
      return R;
762
   end Transpose;
763
 
764
   -----------------
765
   -- Unit_Matrix --
766
   -----------------
767
 
768
   function Unit_Matrix
769
     (Order   : Positive;
770
      First_1 : Integer := 1;
771
      First_2 : Integer := 1) return Real_Matrix
772
     renames Instantiations.Unit_Matrix;
773
 
774
   -----------------
775
   -- Unit_Vector --
776
   -----------------
777
 
778
   function Unit_Vector
779
     (Index : Integer;
780
      Order : Positive;
781
      First : Integer := 1) return Real_Vector
782
     renames Instantiations.Unit_Vector;
783
 
784
end Ada.Numerics.Generic_Real_Arrays;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.