annotate gcc/ada/libgnat/a-ngrear.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT RUN-TIME COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- ADA.NUMERICS.GENERIC_REAL_ARRAYS --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2006-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- This version of Generic_Real_Arrays avoids the use of BLAS and LAPACK. One
kono
parents:
diff changeset
33 -- reason for this is new Ada 2012 requirements that prohibit algorithms such
kono
parents:
diff changeset
34 -- as Strassen's algorithm, which may be used by some BLAS implementations. In
kono
parents:
diff changeset
35 -- addition, some platforms lacked suitable compilers to compile the reference
kono
parents:
diff changeset
36 -- BLAS/LAPACK implementation. Finally, on some platforms there are more
kono
parents:
diff changeset
37 -- floating point types than supported by BLAS/LAPACK.
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 with Ada.Containers.Generic_Anonymous_Array_Sort; use Ada.Containers;
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 with System; use System;
kono
parents:
diff changeset
42 with System.Generic_Array_Operations; use System.Generic_Array_Operations;
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 package body Ada.Numerics.Generic_Real_Arrays is
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 package Ops renames System.Generic_Array_Operations;
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 function Is_Non_Zero (X : Real'Base) return Boolean is (X /= 0.0);
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 procedure Back_Substitute is new Ops.Back_Substitute
kono
parents:
diff changeset
51 (Scalar => Real'Base,
kono
parents:
diff changeset
52 Matrix => Real_Matrix,
kono
parents:
diff changeset
53 Is_Non_Zero => Is_Non_Zero);
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 function Diagonal is new Ops.Diagonal
kono
parents:
diff changeset
56 (Scalar => Real'Base,
kono
parents:
diff changeset
57 Vector => Real_Vector,
kono
parents:
diff changeset
58 Matrix => Real_Matrix);
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 procedure Forward_Eliminate is new Ops.Forward_Eliminate
kono
parents:
diff changeset
61 (Scalar => Real'Base,
kono
parents:
diff changeset
62 Real => Real'Base,
kono
parents:
diff changeset
63 Matrix => Real_Matrix,
kono
parents:
diff changeset
64 Zero => 0.0,
kono
parents:
diff changeset
65 One => 1.0);
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 procedure Swap_Column is new Ops.Swap_Column
kono
parents:
diff changeset
68 (Scalar => Real'Base,
kono
parents:
diff changeset
69 Matrix => Real_Matrix);
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 procedure Transpose is new Ops.Transpose
kono
parents:
diff changeset
72 (Scalar => Real'Base,
kono
parents:
diff changeset
73 Matrix => Real_Matrix);
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 function Is_Symmetric (A : Real_Matrix) return Boolean is
kono
parents:
diff changeset
76 (Transpose (A) = A);
kono
parents:
diff changeset
77 -- Return True iff A is symmetric, see RM G.3.1 (90).
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 function Is_Tiny (Value, Compared_To : Real) return Boolean is
kono
parents:
diff changeset
80 (abs Compared_To + 100.0 * abs (Value) = abs Compared_To);
kono
parents:
diff changeset
81 -- Return True iff the Value is much smaller in magnitude than the least
kono
parents:
diff changeset
82 -- significant digit of Compared_To.
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 procedure Jacobi
kono
parents:
diff changeset
85 (A : Real_Matrix;
kono
parents:
diff changeset
86 Values : out Real_Vector;
kono
parents:
diff changeset
87 Vectors : out Real_Matrix;
kono
parents:
diff changeset
88 Compute_Vectors : Boolean := True);
kono
parents:
diff changeset
89 -- Perform Jacobi's eigensystem algorithm on real symmetric matrix A
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 function Length is new Square_Matrix_Length (Real'Base, Real_Matrix);
kono
parents:
diff changeset
92 -- Helper function that raises a Constraint_Error is the argument is
kono
parents:
diff changeset
93 -- not a square matrix, and otherwise returns its length.
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 procedure Rotate (X, Y : in out Real; Sin, Tau : Real);
kono
parents:
diff changeset
96 -- Perform a Givens rotation
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 procedure Sort_Eigensystem
kono
parents:
diff changeset
99 (Values : in out Real_Vector;
kono
parents:
diff changeset
100 Vectors : in out Real_Matrix);
kono
parents:
diff changeset
101 -- Sort Values and associated Vectors by decreasing absolute value
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 procedure Swap (Left, Right : in out Real);
kono
parents:
diff changeset
104 -- Exchange Left and Right
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 function Sqrt is new Ops.Sqrt (Real);
kono
parents:
diff changeset
107 -- Instant a generic square root implementation here, in order to avoid
kono
parents:
diff changeset
108 -- instantiating a complete copy of Generic_Elementary_Functions.
kono
parents:
diff changeset
109 -- Speed of the square root is not a big concern here.
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 ------------
kono
parents:
diff changeset
112 -- Rotate --
kono
parents:
diff changeset
113 ------------
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 procedure Rotate (X, Y : in out Real; Sin, Tau : Real) is
kono
parents:
diff changeset
116 Old_X : constant Real := X;
kono
parents:
diff changeset
117 Old_Y : constant Real := Y;
kono
parents:
diff changeset
118 begin
kono
parents:
diff changeset
119 X := Old_X - Sin * (Old_Y + Old_X * Tau);
kono
parents:
diff changeset
120 Y := Old_Y + Sin * (Old_X - Old_Y * Tau);
kono
parents:
diff changeset
121 end Rotate;
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 ----------
kono
parents:
diff changeset
124 -- Swap --
kono
parents:
diff changeset
125 ----------
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 procedure Swap (Left, Right : in out Real) is
kono
parents:
diff changeset
128 Temp : constant Real := Left;
kono
parents:
diff changeset
129 begin
kono
parents:
diff changeset
130 Left := Right;
kono
parents:
diff changeset
131 Right := Temp;
kono
parents:
diff changeset
132 end Swap;
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 -- Instantiating the following subprograms directly would lead to
kono
parents:
diff changeset
135 -- name clashes, so use a local package.
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 package Instantiations is
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 function "+" is new
kono
parents:
diff changeset
140 Vector_Elementwise_Operation
kono
parents:
diff changeset
141 (X_Scalar => Real'Base,
kono
parents:
diff changeset
142 Result_Scalar => Real'Base,
kono
parents:
diff changeset
143 X_Vector => Real_Vector,
kono
parents:
diff changeset
144 Result_Vector => Real_Vector,
kono
parents:
diff changeset
145 Operation => "+");
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 function "+" is new
kono
parents:
diff changeset
148 Matrix_Elementwise_Operation
kono
parents:
diff changeset
149 (X_Scalar => Real'Base,
kono
parents:
diff changeset
150 Result_Scalar => Real'Base,
kono
parents:
diff changeset
151 X_Matrix => Real_Matrix,
kono
parents:
diff changeset
152 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
153 Operation => "+");
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 function "+" is new
kono
parents:
diff changeset
156 Vector_Vector_Elementwise_Operation
kono
parents:
diff changeset
157 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
158 Right_Scalar => Real'Base,
kono
parents:
diff changeset
159 Result_Scalar => Real'Base,
kono
parents:
diff changeset
160 Left_Vector => Real_Vector,
kono
parents:
diff changeset
161 Right_Vector => Real_Vector,
kono
parents:
diff changeset
162 Result_Vector => Real_Vector,
kono
parents:
diff changeset
163 Operation => "+");
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 function "+" is new
kono
parents:
diff changeset
166 Matrix_Matrix_Elementwise_Operation
kono
parents:
diff changeset
167 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
168 Right_Scalar => Real'Base,
kono
parents:
diff changeset
169 Result_Scalar => Real'Base,
kono
parents:
diff changeset
170 Left_Matrix => Real_Matrix,
kono
parents:
diff changeset
171 Right_Matrix => Real_Matrix,
kono
parents:
diff changeset
172 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
173 Operation => "+");
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 function "-" is new
kono
parents:
diff changeset
176 Vector_Elementwise_Operation
kono
parents:
diff changeset
177 (X_Scalar => Real'Base,
kono
parents:
diff changeset
178 Result_Scalar => Real'Base,
kono
parents:
diff changeset
179 X_Vector => Real_Vector,
kono
parents:
diff changeset
180 Result_Vector => Real_Vector,
kono
parents:
diff changeset
181 Operation => "-");
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 function "-" is new
kono
parents:
diff changeset
184 Matrix_Elementwise_Operation
kono
parents:
diff changeset
185 (X_Scalar => Real'Base,
kono
parents:
diff changeset
186 Result_Scalar => Real'Base,
kono
parents:
diff changeset
187 X_Matrix => Real_Matrix,
kono
parents:
diff changeset
188 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
189 Operation => "-");
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 function "-" is new
kono
parents:
diff changeset
192 Vector_Vector_Elementwise_Operation
kono
parents:
diff changeset
193 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
194 Right_Scalar => Real'Base,
kono
parents:
diff changeset
195 Result_Scalar => Real'Base,
kono
parents:
diff changeset
196 Left_Vector => Real_Vector,
kono
parents:
diff changeset
197 Right_Vector => Real_Vector,
kono
parents:
diff changeset
198 Result_Vector => Real_Vector,
kono
parents:
diff changeset
199 Operation => "-");
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 function "-" is new
kono
parents:
diff changeset
202 Matrix_Matrix_Elementwise_Operation
kono
parents:
diff changeset
203 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
204 Right_Scalar => Real'Base,
kono
parents:
diff changeset
205 Result_Scalar => Real'Base,
kono
parents:
diff changeset
206 Left_Matrix => Real_Matrix,
kono
parents:
diff changeset
207 Right_Matrix => Real_Matrix,
kono
parents:
diff changeset
208 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
209 Operation => "-");
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 function "*" is new
kono
parents:
diff changeset
212 Scalar_Vector_Elementwise_Operation
kono
parents:
diff changeset
213 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
214 Right_Scalar => Real'Base,
kono
parents:
diff changeset
215 Result_Scalar => Real'Base,
kono
parents:
diff changeset
216 Right_Vector => Real_Vector,
kono
parents:
diff changeset
217 Result_Vector => Real_Vector,
kono
parents:
diff changeset
218 Operation => "*");
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 function "*" is new
kono
parents:
diff changeset
221 Scalar_Matrix_Elementwise_Operation
kono
parents:
diff changeset
222 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
223 Right_Scalar => Real'Base,
kono
parents:
diff changeset
224 Result_Scalar => Real'Base,
kono
parents:
diff changeset
225 Right_Matrix => Real_Matrix,
kono
parents:
diff changeset
226 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
227 Operation => "*");
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 function "*" is new
kono
parents:
diff changeset
230 Vector_Scalar_Elementwise_Operation
kono
parents:
diff changeset
231 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
232 Right_Scalar => Real'Base,
kono
parents:
diff changeset
233 Result_Scalar => Real'Base,
kono
parents:
diff changeset
234 Left_Vector => Real_Vector,
kono
parents:
diff changeset
235 Result_Vector => Real_Vector,
kono
parents:
diff changeset
236 Operation => "*");
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 function "*" is new
kono
parents:
diff changeset
239 Matrix_Scalar_Elementwise_Operation
kono
parents:
diff changeset
240 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
241 Right_Scalar => Real'Base,
kono
parents:
diff changeset
242 Result_Scalar => Real'Base,
kono
parents:
diff changeset
243 Left_Matrix => Real_Matrix,
kono
parents:
diff changeset
244 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
245 Operation => "*");
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 function "*" is new
kono
parents:
diff changeset
248 Outer_Product
kono
parents:
diff changeset
249 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
250 Right_Scalar => Real'Base,
kono
parents:
diff changeset
251 Result_Scalar => Real'Base,
kono
parents:
diff changeset
252 Left_Vector => Real_Vector,
kono
parents:
diff changeset
253 Right_Vector => Real_Vector,
kono
parents:
diff changeset
254 Matrix => Real_Matrix);
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 function "*" is new
kono
parents:
diff changeset
257 Inner_Product
kono
parents:
diff changeset
258 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
259 Right_Scalar => Real'Base,
kono
parents:
diff changeset
260 Result_Scalar => Real'Base,
kono
parents:
diff changeset
261 Left_Vector => Real_Vector,
kono
parents:
diff changeset
262 Right_Vector => Real_Vector,
kono
parents:
diff changeset
263 Zero => 0.0);
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 function "*" is new
kono
parents:
diff changeset
266 Matrix_Vector_Product
kono
parents:
diff changeset
267 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
268 Right_Scalar => Real'Base,
kono
parents:
diff changeset
269 Result_Scalar => Real'Base,
kono
parents:
diff changeset
270 Matrix => Real_Matrix,
kono
parents:
diff changeset
271 Right_Vector => Real_Vector,
kono
parents:
diff changeset
272 Result_Vector => Real_Vector,
kono
parents:
diff changeset
273 Zero => 0.0);
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 function "*" is new
kono
parents:
diff changeset
276 Vector_Matrix_Product
kono
parents:
diff changeset
277 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
278 Right_Scalar => Real'Base,
kono
parents:
diff changeset
279 Result_Scalar => Real'Base,
kono
parents:
diff changeset
280 Left_Vector => Real_Vector,
kono
parents:
diff changeset
281 Matrix => Real_Matrix,
kono
parents:
diff changeset
282 Result_Vector => Real_Vector,
kono
parents:
diff changeset
283 Zero => 0.0);
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 function "*" is new
kono
parents:
diff changeset
286 Matrix_Matrix_Product
kono
parents:
diff changeset
287 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
288 Right_Scalar => Real'Base,
kono
parents:
diff changeset
289 Result_Scalar => Real'Base,
kono
parents:
diff changeset
290 Left_Matrix => Real_Matrix,
kono
parents:
diff changeset
291 Right_Matrix => Real_Matrix,
kono
parents:
diff changeset
292 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
293 Zero => 0.0);
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 function "/" is new
kono
parents:
diff changeset
296 Vector_Scalar_Elementwise_Operation
kono
parents:
diff changeset
297 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
298 Right_Scalar => Real'Base,
kono
parents:
diff changeset
299 Result_Scalar => Real'Base,
kono
parents:
diff changeset
300 Left_Vector => Real_Vector,
kono
parents:
diff changeset
301 Result_Vector => Real_Vector,
kono
parents:
diff changeset
302 Operation => "/");
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 function "/" is new
kono
parents:
diff changeset
305 Matrix_Scalar_Elementwise_Operation
kono
parents:
diff changeset
306 (Left_Scalar => Real'Base,
kono
parents:
diff changeset
307 Right_Scalar => Real'Base,
kono
parents:
diff changeset
308 Result_Scalar => Real'Base,
kono
parents:
diff changeset
309 Left_Matrix => Real_Matrix,
kono
parents:
diff changeset
310 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
311 Operation => "/");
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 function "abs" is new
kono
parents:
diff changeset
314 L2_Norm
kono
parents:
diff changeset
315 (X_Scalar => Real'Base,
kono
parents:
diff changeset
316 Result_Real => Real'Base,
kono
parents:
diff changeset
317 X_Vector => Real_Vector,
kono
parents:
diff changeset
318 "abs" => "+");
kono
parents:
diff changeset
319 -- While the L2_Norm by definition uses the absolute values of the
kono
parents:
diff changeset
320 -- elements of X_Vector, for real values the subsequent squaring
kono
parents:
diff changeset
321 -- makes this unnecessary, so we substitute the "+" identity function
kono
parents:
diff changeset
322 -- instead.
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 function "abs" is new
kono
parents:
diff changeset
325 Vector_Elementwise_Operation
kono
parents:
diff changeset
326 (X_Scalar => Real'Base,
kono
parents:
diff changeset
327 Result_Scalar => Real'Base,
kono
parents:
diff changeset
328 X_Vector => Real_Vector,
kono
parents:
diff changeset
329 Result_Vector => Real_Vector,
kono
parents:
diff changeset
330 Operation => "abs");
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 function "abs" is new
kono
parents:
diff changeset
333 Matrix_Elementwise_Operation
kono
parents:
diff changeset
334 (X_Scalar => Real'Base,
kono
parents:
diff changeset
335 Result_Scalar => Real'Base,
kono
parents:
diff changeset
336 X_Matrix => Real_Matrix,
kono
parents:
diff changeset
337 Result_Matrix => Real_Matrix,
kono
parents:
diff changeset
338 Operation => "abs");
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340 function Solve is new
kono
parents:
diff changeset
341 Matrix_Vector_Solution (Real'Base, 0.0, Real_Vector, Real_Matrix);
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 function Solve is new
kono
parents:
diff changeset
344 Matrix_Matrix_Solution (Real'Base, 0.0, Real_Matrix);
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 function Unit_Matrix is new
kono
parents:
diff changeset
347 Generic_Array_Operations.Unit_Matrix
kono
parents:
diff changeset
348 (Scalar => Real'Base,
kono
parents:
diff changeset
349 Matrix => Real_Matrix,
kono
parents:
diff changeset
350 Zero => 0.0,
kono
parents:
diff changeset
351 One => 1.0);
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 function Unit_Vector is new
kono
parents:
diff changeset
354 Generic_Array_Operations.Unit_Vector
kono
parents:
diff changeset
355 (Scalar => Real'Base,
kono
parents:
diff changeset
356 Vector => Real_Vector,
kono
parents:
diff changeset
357 Zero => 0.0,
kono
parents:
diff changeset
358 One => 1.0);
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 end Instantiations;
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 ---------
kono
parents:
diff changeset
363 -- "+" --
kono
parents:
diff changeset
364 ---------
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 function "+" (Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
367 renames Instantiations."+";
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 function "+" (Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
370 renames Instantiations."+";
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 function "+" (Left, Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
373 renames Instantiations."+";
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 function "+" (Left, Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
376 renames Instantiations."+";
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 ---------
kono
parents:
diff changeset
379 -- "-" --
kono
parents:
diff changeset
380 ---------
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 function "-" (Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
383 renames Instantiations."-";
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 function "-" (Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
386 renames Instantiations."-";
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 function "-" (Left, Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
389 renames Instantiations."-";
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 function "-" (Left, Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
392 renames Instantiations."-";
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 ---------
kono
parents:
diff changeset
395 -- "*" --
kono
parents:
diff changeset
396 ---------
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 -- Scalar multiplication
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 function "*" (Left : Real'Base; Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
401 renames Instantiations."*";
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 function "*" (Left : Real_Vector; Right : Real'Base) return Real_Vector
kono
parents:
diff changeset
404 renames Instantiations."*";
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 function "*" (Left : Real'Base; Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
407 renames Instantiations."*";
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 function "*" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix
kono
parents:
diff changeset
410 renames Instantiations."*";
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 -- Vector multiplication
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 function "*" (Left, Right : Real_Vector) return Real'Base
kono
parents:
diff changeset
415 renames Instantiations."*";
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 function "*" (Left, Right : Real_Vector) return Real_Matrix
kono
parents:
diff changeset
418 renames Instantiations."*";
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 function "*" (Left : Real_Vector; Right : Real_Matrix) return Real_Vector
kono
parents:
diff changeset
421 renames Instantiations."*";
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 function "*" (Left : Real_Matrix; Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
424 renames Instantiations."*";
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 -- Matrix Multiplication
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 function "*" (Left, Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
429 renames Instantiations."*";
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 ---------
kono
parents:
diff changeset
432 -- "/" --
kono
parents:
diff changeset
433 ---------
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 function "/" (Left : Real_Vector; Right : Real'Base) return Real_Vector
kono
parents:
diff changeset
436 renames Instantiations."/";
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 function "/" (Left : Real_Matrix; Right : Real'Base) return Real_Matrix
kono
parents:
diff changeset
439 renames Instantiations."/";
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 -----------
kono
parents:
diff changeset
442 -- "abs" --
kono
parents:
diff changeset
443 -----------
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 function "abs" (Right : Real_Vector) return Real'Base
kono
parents:
diff changeset
446 renames Instantiations."abs";
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 function "abs" (Right : Real_Vector) return Real_Vector
kono
parents:
diff changeset
449 renames Instantiations."abs";
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 function "abs" (Right : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
452 renames Instantiations."abs";
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454 -----------------
kono
parents:
diff changeset
455 -- Determinant --
kono
parents:
diff changeset
456 -----------------
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 function Determinant (A : Real_Matrix) return Real'Base is
kono
parents:
diff changeset
459 M : Real_Matrix := A;
kono
parents:
diff changeset
460 B : Real_Matrix (A'Range (1), 1 .. 0);
kono
parents:
diff changeset
461 R : Real'Base;
kono
parents:
diff changeset
462 begin
kono
parents:
diff changeset
463 Forward_Eliminate (M, B, R);
kono
parents:
diff changeset
464 return R;
kono
parents:
diff changeset
465 end Determinant;
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 -----------------
kono
parents:
diff changeset
468 -- Eigensystem --
kono
parents:
diff changeset
469 -----------------
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 procedure Eigensystem
kono
parents:
diff changeset
472 (A : Real_Matrix;
kono
parents:
diff changeset
473 Values : out Real_Vector;
kono
parents:
diff changeset
474 Vectors : out Real_Matrix)
kono
parents:
diff changeset
475 is
kono
parents:
diff changeset
476 begin
kono
parents:
diff changeset
477 Jacobi (A, Values, Vectors, Compute_Vectors => True);
kono
parents:
diff changeset
478 Sort_Eigensystem (Values, Vectors);
kono
parents:
diff changeset
479 end Eigensystem;
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 -----------------
kono
parents:
diff changeset
482 -- Eigenvalues --
kono
parents:
diff changeset
483 -----------------
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 function Eigenvalues (A : Real_Matrix) return Real_Vector is
kono
parents:
diff changeset
486 begin
kono
parents:
diff changeset
487 return Values : Real_Vector (A'Range (1)) do
kono
parents:
diff changeset
488 declare
kono
parents:
diff changeset
489 Vectors : Real_Matrix (1 .. 0, 1 .. 0);
kono
parents:
diff changeset
490 begin
kono
parents:
diff changeset
491 Jacobi (A, Values, Vectors, Compute_Vectors => False);
kono
parents:
diff changeset
492 Sort_Eigensystem (Values, Vectors);
kono
parents:
diff changeset
493 end;
kono
parents:
diff changeset
494 end return;
kono
parents:
diff changeset
495 end Eigenvalues;
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 -------------
kono
parents:
diff changeset
498 -- Inverse --
kono
parents:
diff changeset
499 -------------
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 function Inverse (A : Real_Matrix) return Real_Matrix is
kono
parents:
diff changeset
502 (Solve (A, Unit_Matrix (Length (A),
kono
parents:
diff changeset
503 First_1 => A'First (2),
kono
parents:
diff changeset
504 First_2 => A'First (1))));
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 ------------
kono
parents:
diff changeset
507 -- Jacobi --
kono
parents:
diff changeset
508 ------------
kono
parents:
diff changeset
509
kono
parents:
diff changeset
510 procedure Jacobi
kono
parents:
diff changeset
511 (A : Real_Matrix;
kono
parents:
diff changeset
512 Values : out Real_Vector;
kono
parents:
diff changeset
513 Vectors : out Real_Matrix;
kono
parents:
diff changeset
514 Compute_Vectors : Boolean := True)
kono
parents:
diff changeset
515 is
kono
parents:
diff changeset
516 -- This subprogram uses Carl Gustav Jacob Jacobi's iterative method
kono
parents:
diff changeset
517 -- for computing eigenvalues and eigenvectors and is based on
kono
parents:
diff changeset
518 -- Rutishauser's implementation.
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 -- The given real symmetric matrix is transformed iteratively to
kono
parents:
diff changeset
521 -- diagonal form through a sequence of appropriately chosen elementary
kono
parents:
diff changeset
522 -- orthogonal transformations, called Jacobi rotations here.
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 -- The Jacobi method produces a systematic decrease of the sum of the
kono
parents:
diff changeset
525 -- squares of off-diagonal elements. Convergence to zero is quadratic,
kono
parents:
diff changeset
526 -- both for this implementation, as for the classic method that doesn't
kono
parents:
diff changeset
527 -- use row-wise scanning for pivot selection.
kono
parents:
diff changeset
528
kono
parents:
diff changeset
529 -- The numerical stability and accuracy of Jacobi's method make it the
kono
parents:
diff changeset
530 -- best choice here, even though for large matrices other methods will
kono
parents:
diff changeset
531 -- be significantly more efficient in both time and space.
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 -- While the eigensystem computations are absolutely foolproof for all
kono
parents:
diff changeset
534 -- real symmetric matrices, in presence of invalid values, or similar
kono
parents:
diff changeset
535 -- exceptional situations it might not. In such cases the results cannot
kono
parents:
diff changeset
536 -- be trusted and Constraint_Error is raised.
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 -- Note: this implementation needs temporary storage for 2 * N + N**2
kono
parents:
diff changeset
539 -- values of type Real.
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 Max_Iterations : constant := 50;
kono
parents:
diff changeset
542 N : constant Natural := Length (A);
kono
parents:
diff changeset
543
kono
parents:
diff changeset
544 subtype Square_Matrix is Real_Matrix (1 .. N, 1 .. N);
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 -- In order to annihilate the M (Row, Col) element, the
kono
parents:
diff changeset
547 -- rotation parameters Cos and Sin are computed as
kono
parents:
diff changeset
548 -- follows:
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 -- Theta = Cot (2.0 * Phi)
kono
parents:
diff changeset
551 -- = (Diag (Col) - Diag (Row)) / (2.0 * M (Row, Col))
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 -- Then Tan (Phi) as the smaller root (in modulus) of
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 -- T**2 + 2 * T * Theta = 1 (or 0.5 / Theta, if Theta is large)
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 function Compute_Tan (Theta : Real) return Real is
kono
parents:
diff changeset
558 (Real'Copy_Sign (1.0 / (abs Theta + Sqrt (1.0 + Theta**2)), Theta));
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 function Compute_Tan (P, H : Real) return Real is
kono
parents:
diff changeset
561 (if Is_Tiny (P, Compared_To => H) then P / H
kono
parents:
diff changeset
562 else Compute_Tan (Theta => H / (2.0 * P)));
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 function Sum_Strict_Upper (M : Square_Matrix) return Real;
kono
parents:
diff changeset
565 -- Return the sum of all elements in the strict upper triangle of M
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 ----------------------
kono
parents:
diff changeset
568 -- Sum_Strict_Upper --
kono
parents:
diff changeset
569 ----------------------
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 function Sum_Strict_Upper (M : Square_Matrix) return Real is
kono
parents:
diff changeset
572 Sum : Real := 0.0;
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 begin
kono
parents:
diff changeset
575 for Row in 1 .. N - 1 loop
kono
parents:
diff changeset
576 for Col in Row + 1 .. N loop
kono
parents:
diff changeset
577 Sum := Sum + abs M (Row, Col);
kono
parents:
diff changeset
578 end loop;
kono
parents:
diff changeset
579 end loop;
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 return Sum;
kono
parents:
diff changeset
582 end Sum_Strict_Upper;
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 M : Square_Matrix := A; -- Work space for solving eigensystem
kono
parents:
diff changeset
585 Threshold : Real;
kono
parents:
diff changeset
586 Sum : Real;
kono
parents:
diff changeset
587 Diag : Real_Vector (1 .. N);
kono
parents:
diff changeset
588 Diag_Adj : Real_Vector (1 .. N);
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 -- The vector Diag_Adj indicates the amount of change in each value,
kono
parents:
diff changeset
591 -- while Diag tracks the value itself and Values holds the values as
kono
parents:
diff changeset
592 -- they were at the beginning. As the changes typically will be small
kono
parents:
diff changeset
593 -- compared to the absolute value of Diag, at the end of each iteration
kono
parents:
diff changeset
594 -- Diag is computed as Diag + Diag_Adj thus avoiding accumulating
kono
parents:
diff changeset
595 -- rounding errors. This technique is due to Rutishauser.
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 begin
kono
parents:
diff changeset
598 if Compute_Vectors
kono
parents:
diff changeset
599 and then (Vectors'Length (1) /= N or else Vectors'Length (2) /= N)
kono
parents:
diff changeset
600 then
kono
parents:
diff changeset
601 raise Constraint_Error with "incompatible matrix dimensions";
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 elsif Values'Length /= N then
kono
parents:
diff changeset
604 raise Constraint_Error with "incompatible vector length";
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 elsif not Is_Symmetric (M) then
kono
parents:
diff changeset
607 raise Constraint_Error with "matrix not symmetric";
kono
parents:
diff changeset
608 end if;
kono
parents:
diff changeset
609
kono
parents:
diff changeset
610 -- Note: Only the locally declared matrix M and vectors (Diag, Diag_Adj)
kono
parents:
diff changeset
611 -- have lower bound equal to 1. The Vectors matrix may have
kono
parents:
diff changeset
612 -- different bounds, so take care indexing elements. Assignment
kono
parents:
diff changeset
613 -- as a whole is fine as sliding is automatic in that case.
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 Vectors := (if not Compute_Vectors then (1 .. 0 => (1 .. 0 => 0.0))
kono
parents:
diff changeset
616 else Unit_Matrix (Vectors'Length (1), Vectors'Length (2)));
kono
parents:
diff changeset
617 Values := Diagonal (M);
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 Sweep : for Iteration in 1 .. Max_Iterations loop
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 -- The first three iterations, perform rotation for any non-zero
kono
parents:
diff changeset
622 -- element. After this, rotate only for those that are not much
kono
parents:
diff changeset
623 -- smaller than the average off-diagnal element. After the fifth
kono
parents:
diff changeset
624 -- iteration, additionally zero out off-diagonal elements that are
kono
parents:
diff changeset
625 -- very small compared to elements on the diagonal with the same
kono
parents:
diff changeset
626 -- column or row index.
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 Sum := Sum_Strict_Upper (M);
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 exit Sweep when Sum = 0.0;
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 Threshold := (if Iteration < 4 then 0.2 * Sum / Real (N**2) else 0.0);
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 -- Iterate over all off-diagonal elements, rotating any that have
kono
parents:
diff changeset
635 -- an absolute value that exceeds the threshold.
kono
parents:
diff changeset
636
kono
parents:
diff changeset
637 Diag := Values;
kono
parents:
diff changeset
638 Diag_Adj := (others => 0.0); -- Accumulates adjustments to Diag
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 for Row in 1 .. N - 1 loop
kono
parents:
diff changeset
641 for Col in Row + 1 .. N loop
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 -- If, before the rotation M (Row, Col) is tiny compared to
kono
parents:
diff changeset
644 -- Diag (Row) and Diag (Col), rotation is skipped. This is
kono
parents:
diff changeset
645 -- meaningful, as it produces no larger error than would be
kono
parents:
diff changeset
646 -- produced anyhow if the rotation had been performed.
kono
parents:
diff changeset
647 -- Suppress this optimization in the first four sweeps, so
kono
parents:
diff changeset
648 -- that this procedure can be used for computing eigenvectors
kono
parents:
diff changeset
649 -- of perturbed diagonal matrices.
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 if Iteration > 4
kono
parents:
diff changeset
652 and then Is_Tiny (M (Row, Col), Compared_To => Diag (Row))
kono
parents:
diff changeset
653 and then Is_Tiny (M (Row, Col), Compared_To => Diag (Col))
kono
parents:
diff changeset
654 then
kono
parents:
diff changeset
655 M (Row, Col) := 0.0;
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 elsif abs M (Row, Col) > Threshold then
kono
parents:
diff changeset
658 Perform_Rotation : declare
kono
parents:
diff changeset
659 Tan : constant Real := Compute_Tan (M (Row, Col),
kono
parents:
diff changeset
660 Diag (Col) - Diag (Row));
kono
parents:
diff changeset
661 Cos : constant Real := 1.0 / Sqrt (1.0 + Tan**2);
kono
parents:
diff changeset
662 Sin : constant Real := Tan * Cos;
kono
parents:
diff changeset
663 Tau : constant Real := Sin / (1.0 + Cos);
kono
parents:
diff changeset
664 Adj : constant Real := Tan * M (Row, Col);
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 begin
kono
parents:
diff changeset
667 Diag_Adj (Row) := Diag_Adj (Row) - Adj;
kono
parents:
diff changeset
668 Diag_Adj (Col) := Diag_Adj (Col) + Adj;
kono
parents:
diff changeset
669 Diag (Row) := Diag (Row) - Adj;
kono
parents:
diff changeset
670 Diag (Col) := Diag (Col) + Adj;
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 M (Row, Col) := 0.0;
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 for J in 1 .. Row - 1 loop -- 1 <= J < Row
kono
parents:
diff changeset
675 Rotate (M (J, Row), M (J, Col), Sin, Tau);
kono
parents:
diff changeset
676 end loop;
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 for J in Row + 1 .. Col - 1 loop -- Row < J < Col
kono
parents:
diff changeset
679 Rotate (M (Row, J), M (J, Col), Sin, Tau);
kono
parents:
diff changeset
680 end loop;
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 for J in Col + 1 .. N loop -- Col < J <= N
kono
parents:
diff changeset
683 Rotate (M (Row, J), M (Col, J), Sin, Tau);
kono
parents:
diff changeset
684 end loop;
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 for J in Vectors'Range (1) loop
kono
parents:
diff changeset
687 Rotate (Vectors (J, Row - 1 + Vectors'First (2)),
kono
parents:
diff changeset
688 Vectors (J, Col - 1 + Vectors'First (2)),
kono
parents:
diff changeset
689 Sin, Tau);
kono
parents:
diff changeset
690 end loop;
kono
parents:
diff changeset
691 end Perform_Rotation;
kono
parents:
diff changeset
692 end if;
kono
parents:
diff changeset
693 end loop;
kono
parents:
diff changeset
694 end loop;
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 Values := Values + Diag_Adj;
kono
parents:
diff changeset
697 end loop Sweep;
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 -- All normal matrices with valid values should converge perfectly.
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 if Sum /= 0.0 then
kono
parents:
diff changeset
702 raise Constraint_Error with "eigensystem solution does not converge";
kono
parents:
diff changeset
703 end if;
kono
parents:
diff changeset
704 end Jacobi;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 -----------
kono
parents:
diff changeset
707 -- Solve --
kono
parents:
diff changeset
708 -----------
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 function Solve (A : Real_Matrix; X : Real_Vector) return Real_Vector
kono
parents:
diff changeset
711 renames Instantiations.Solve;
kono
parents:
diff changeset
712
kono
parents:
diff changeset
713 function Solve (A, X : Real_Matrix) return Real_Matrix
kono
parents:
diff changeset
714 renames Instantiations.Solve;
kono
parents:
diff changeset
715
kono
parents:
diff changeset
716 ----------------------
kono
parents:
diff changeset
717 -- Sort_Eigensystem --
kono
parents:
diff changeset
718 ----------------------
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 procedure Sort_Eigensystem
kono
parents:
diff changeset
721 (Values : in out Real_Vector;
kono
parents:
diff changeset
722 Vectors : in out Real_Matrix)
kono
parents:
diff changeset
723 is
kono
parents:
diff changeset
724 procedure Swap (Left, Right : Integer);
kono
parents:
diff changeset
725 -- Swap Values (Left) with Values (Right), and also swap the
kono
parents:
diff changeset
726 -- corresponding eigenvectors. Note that lowerbounds may differ.
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 function Less (Left, Right : Integer) return Boolean is
kono
parents:
diff changeset
729 (Values (Left) > Values (Right));
kono
parents:
diff changeset
730 -- Sort by decreasing eigenvalue, see RM G.3.1 (76).
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 procedure Sort is new Generic_Anonymous_Array_Sort (Integer);
kono
parents:
diff changeset
733 -- Sorts eigenvalues and eigenvectors by decreasing value
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 procedure Swap (Left, Right : Integer) is
kono
parents:
diff changeset
736 begin
kono
parents:
diff changeset
737 Swap (Values (Left), Values (Right));
kono
parents:
diff changeset
738 Swap_Column (Vectors, Left - Values'First + Vectors'First (2),
kono
parents:
diff changeset
739 Right - Values'First + Vectors'First (2));
kono
parents:
diff changeset
740 end Swap;
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 begin
kono
parents:
diff changeset
743 Sort (Values'First, Values'Last);
kono
parents:
diff changeset
744 end Sort_Eigensystem;
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 ---------------
kono
parents:
diff changeset
747 -- Transpose --
kono
parents:
diff changeset
748 ---------------
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 function Transpose (X : Real_Matrix) return Real_Matrix is
kono
parents:
diff changeset
751 begin
kono
parents:
diff changeset
752 return R : Real_Matrix (X'Range (2), X'Range (1)) do
kono
parents:
diff changeset
753 Transpose (X, R);
kono
parents:
diff changeset
754 end return;
kono
parents:
diff changeset
755 end Transpose;
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 -----------------
kono
parents:
diff changeset
758 -- Unit_Matrix --
kono
parents:
diff changeset
759 -----------------
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 function Unit_Matrix
kono
parents:
diff changeset
762 (Order : Positive;
kono
parents:
diff changeset
763 First_1 : Integer := 1;
kono
parents:
diff changeset
764 First_2 : Integer := 1) return Real_Matrix
kono
parents:
diff changeset
765 renames Instantiations.Unit_Matrix;
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 -----------------
kono
parents:
diff changeset
768 -- Unit_Vector --
kono
parents:
diff changeset
769 -----------------
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 function Unit_Vector
kono
parents:
diff changeset
772 (Index : Integer;
kono
parents:
diff changeset
773 Order : Positive;
kono
parents:
diff changeset
774 First : Integer := 1) return Real_Vector
kono
parents:
diff changeset
775 renames Instantiations.Unit_Vector;
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 end Ada.Numerics.Generic_Real_Arrays;