annotate gcc/ada/libgnat/s-gearop.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 -- S Y S T E M . G E N E R I C _ A R R A Y _ O P E R A T I O N S --
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 with Ada.Numerics; use Ada.Numerics;
kono
parents:
diff changeset
33 package body System.Generic_Array_Operations is
kono
parents:
diff changeset
34 function Check_Unit_Last
kono
parents:
diff changeset
35 (Index : Integer;
kono
parents:
diff changeset
36 Order : Positive;
kono
parents:
diff changeset
37 First : Integer) return Integer;
kono
parents:
diff changeset
38 pragma Inline_Always (Check_Unit_Last);
kono
parents:
diff changeset
39 -- Compute index of last element returned by Unit_Vector or Unit_Matrix.
kono
parents:
diff changeset
40 -- A separate function is needed to allow raising Constraint_Error before
kono
parents:
diff changeset
41 -- declaring the function result variable. The result variable needs to be
kono
parents:
diff changeset
42 -- declared first, to allow front-end inlining.
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 --------------
kono
parents:
diff changeset
45 -- Diagonal --
kono
parents:
diff changeset
46 --------------
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 function Diagonal (A : Matrix) return Vector is
kono
parents:
diff changeset
49 N : constant Natural := Natural'Min (A'Length (1), A'Length (2));
kono
parents:
diff changeset
50 begin
kono
parents:
diff changeset
51 return R : Vector (A'First (1) .. A'First (1) + N - 1) do
kono
parents:
diff changeset
52 for J in 0 .. N - 1 loop
kono
parents:
diff changeset
53 R (R'First + J) := A (A'First (1) + J, A'First (2) + J);
kono
parents:
diff changeset
54 end loop;
kono
parents:
diff changeset
55 end return;
kono
parents:
diff changeset
56 end Diagonal;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 --------------------------
kono
parents:
diff changeset
59 -- Square_Matrix_Length --
kono
parents:
diff changeset
60 --------------------------
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 function Square_Matrix_Length (A : Matrix) return Natural is
kono
parents:
diff changeset
63 begin
kono
parents:
diff changeset
64 if A'Length (1) /= A'Length (2) then
kono
parents:
diff changeset
65 raise Constraint_Error with "matrix is not square";
kono
parents:
diff changeset
66 else
kono
parents:
diff changeset
67 return A'Length (1);
kono
parents:
diff changeset
68 end if;
kono
parents:
diff changeset
69 end Square_Matrix_Length;
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 ---------------------
kono
parents:
diff changeset
72 -- Check_Unit_Last --
kono
parents:
diff changeset
73 ---------------------
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 function Check_Unit_Last
kono
parents:
diff changeset
76 (Index : Integer;
kono
parents:
diff changeset
77 Order : Positive;
kono
parents:
diff changeset
78 First : Integer) return Integer
kono
parents:
diff changeset
79 is
kono
parents:
diff changeset
80 begin
kono
parents:
diff changeset
81 -- Order the tests carefully to avoid overflow
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 if Index < First
kono
parents:
diff changeset
84 or else First > Integer'Last - Order + 1
kono
parents:
diff changeset
85 or else Index > First + (Order - 1)
kono
parents:
diff changeset
86 then
kono
parents:
diff changeset
87 raise Constraint_Error;
kono
parents:
diff changeset
88 end if;
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 return First + (Order - 1);
kono
parents:
diff changeset
91 end Check_Unit_Last;
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 ---------------------
kono
parents:
diff changeset
94 -- Back_Substitute --
kono
parents:
diff changeset
95 ---------------------
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 procedure Back_Substitute (M, N : in out Matrix) is
kono
parents:
diff changeset
98 pragma Assert (M'First (1) = N'First (1)
kono
parents:
diff changeset
99 and then
kono
parents:
diff changeset
100 M'Last (1) = N'Last (1));
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 procedure Sub_Row
kono
parents:
diff changeset
103 (M : in out Matrix;
kono
parents:
diff changeset
104 Target : Integer;
kono
parents:
diff changeset
105 Source : Integer;
kono
parents:
diff changeset
106 Factor : Scalar);
kono
parents:
diff changeset
107 -- Elementary row operation that subtracts Factor * M (Source, <>) from
kono
parents:
diff changeset
108 -- M (Target, <>)
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 -------------
kono
parents:
diff changeset
111 -- Sub_Row --
kono
parents:
diff changeset
112 -------------
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 procedure Sub_Row
kono
parents:
diff changeset
115 (M : in out Matrix;
kono
parents:
diff changeset
116 Target : Integer;
kono
parents:
diff changeset
117 Source : Integer;
kono
parents:
diff changeset
118 Factor : Scalar)
kono
parents:
diff changeset
119 is
kono
parents:
diff changeset
120 begin
kono
parents:
diff changeset
121 for J in M'Range (2) loop
kono
parents:
diff changeset
122 M (Target, J) := M (Target, J) - Factor * M (Source, J);
kono
parents:
diff changeset
123 end loop;
kono
parents:
diff changeset
124 end Sub_Row;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 -- Local declarations
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 Max_Col : Integer := M'Last (2);
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 -- Start of processing for Back_Substitute
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 begin
kono
parents:
diff changeset
133 Do_Rows : for Row in reverse M'Range (1) loop
kono
parents:
diff changeset
134 Find_Non_Zero : for Col in reverse M'First (2) .. Max_Col loop
kono
parents:
diff changeset
135 if Is_Non_Zero (M (Row, Col)) then
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 -- Found first non-zero element, so subtract a multiple of this
kono
parents:
diff changeset
138 -- element from all higher rows, to reduce all other elements
kono
parents:
diff changeset
139 -- in this column to zero.
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 declare
kono
parents:
diff changeset
142 -- We can't use a for loop, as we'd need to iterate to
kono
parents:
diff changeset
143 -- Row - 1, but that expression will overflow if M'First
kono
parents:
diff changeset
144 -- equals Integer'First, which is true for aggregates
kono
parents:
diff changeset
145 -- without explicit bounds..
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 J : Integer := M'First (1);
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 begin
kono
parents:
diff changeset
150 while J < Row loop
kono
parents:
diff changeset
151 Sub_Row (N, J, Row, (M (J, Col) / M (Row, Col)));
kono
parents:
diff changeset
152 Sub_Row (M, J, Row, (M (J, Col) / M (Row, Col)));
kono
parents:
diff changeset
153 J := J + 1;
kono
parents:
diff changeset
154 end loop;
kono
parents:
diff changeset
155 end;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 -- Avoid potential overflow in the subtraction below
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 exit Do_Rows when Col = M'First (2);
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 Max_Col := Col - 1;
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 exit Find_Non_Zero;
kono
parents:
diff changeset
164 end if;
kono
parents:
diff changeset
165 end loop Find_Non_Zero;
kono
parents:
diff changeset
166 end loop Do_Rows;
kono
parents:
diff changeset
167 end Back_Substitute;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 -----------------------
kono
parents:
diff changeset
170 -- Forward_Eliminate --
kono
parents:
diff changeset
171 -----------------------
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 procedure Forward_Eliminate
kono
parents:
diff changeset
174 (M : in out Matrix;
kono
parents:
diff changeset
175 N : in out Matrix;
kono
parents:
diff changeset
176 Det : out Scalar)
kono
parents:
diff changeset
177 is
kono
parents:
diff changeset
178 pragma Assert (M'First (1) = N'First (1)
kono
parents:
diff changeset
179 and then
kono
parents:
diff changeset
180 M'Last (1) = N'Last (1));
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 -- The following are variations of the elementary matrix row operations:
kono
parents:
diff changeset
183 -- row switching, row multiplication and row addition. Because in this
kono
parents:
diff changeset
184 -- algorithm the addition factor is always a negated value, we chose to
kono
parents:
diff changeset
185 -- use row subtraction instead. Similarly, instead of multiplying by
kono
parents:
diff changeset
186 -- a reciprocal, we divide.
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 procedure Sub_Row
kono
parents:
diff changeset
189 (M : in out Matrix;
kono
parents:
diff changeset
190 Target : Integer;
kono
parents:
diff changeset
191 Source : Integer;
kono
parents:
diff changeset
192 Factor : Scalar);
kono
parents:
diff changeset
193 -- Subtrace Factor * M (Source, <>) from M (Target, <>)
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 procedure Divide_Row
kono
parents:
diff changeset
196 (M, N : in out Matrix;
kono
parents:
diff changeset
197 Row : Integer;
kono
parents:
diff changeset
198 Scale : Scalar);
kono
parents:
diff changeset
199 -- Divide M (Row) and N (Row) by Scale, and update Det
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 procedure Switch_Row
kono
parents:
diff changeset
202 (M, N : in out Matrix;
kono
parents:
diff changeset
203 Row_1 : Integer;
kono
parents:
diff changeset
204 Row_2 : Integer);
kono
parents:
diff changeset
205 -- Exchange M (Row_1) and N (Row_1) with M (Row_2) and N (Row_2),
kono
parents:
diff changeset
206 -- negating Det in the process.
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 -------------
kono
parents:
diff changeset
209 -- Sub_Row --
kono
parents:
diff changeset
210 -------------
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 procedure Sub_Row
kono
parents:
diff changeset
213 (M : in out Matrix;
kono
parents:
diff changeset
214 Target : Integer;
kono
parents:
diff changeset
215 Source : Integer;
kono
parents:
diff changeset
216 Factor : Scalar)
kono
parents:
diff changeset
217 is
kono
parents:
diff changeset
218 begin
kono
parents:
diff changeset
219 for J in M'Range (2) loop
kono
parents:
diff changeset
220 M (Target, J) := M (Target, J) - Factor * M (Source, J);
kono
parents:
diff changeset
221 end loop;
kono
parents:
diff changeset
222 end Sub_Row;
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 ----------------
kono
parents:
diff changeset
225 -- Divide_Row --
kono
parents:
diff changeset
226 ----------------
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 procedure Divide_Row
kono
parents:
diff changeset
229 (M, N : in out Matrix;
kono
parents:
diff changeset
230 Row : Integer;
kono
parents:
diff changeset
231 Scale : Scalar)
kono
parents:
diff changeset
232 is
kono
parents:
diff changeset
233 begin
kono
parents:
diff changeset
234 Det := Det * Scale;
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 for J in M'Range (2) loop
kono
parents:
diff changeset
237 M (Row, J) := M (Row, J) / Scale;
kono
parents:
diff changeset
238 end loop;
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 for J in N'Range (2) loop
kono
parents:
diff changeset
241 N (Row - M'First (1) + N'First (1), J) :=
kono
parents:
diff changeset
242 N (Row - M'First (1) + N'First (1), J) / Scale;
kono
parents:
diff changeset
243 end loop;
kono
parents:
diff changeset
244 end Divide_Row;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 ----------------
kono
parents:
diff changeset
247 -- Switch_Row --
kono
parents:
diff changeset
248 ----------------
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 procedure Switch_Row
kono
parents:
diff changeset
251 (M, N : in out Matrix;
kono
parents:
diff changeset
252 Row_1 : Integer;
kono
parents:
diff changeset
253 Row_2 : Integer)
kono
parents:
diff changeset
254 is
kono
parents:
diff changeset
255 procedure Swap (X, Y : in out Scalar);
kono
parents:
diff changeset
256 -- Exchange the values of X and Y
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 ----------
kono
parents:
diff changeset
259 -- Swap --
kono
parents:
diff changeset
260 ----------
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 procedure Swap (X, Y : in out Scalar) is
kono
parents:
diff changeset
263 T : constant Scalar := X;
kono
parents:
diff changeset
264 begin
kono
parents:
diff changeset
265 X := Y;
kono
parents:
diff changeset
266 Y := T;
kono
parents:
diff changeset
267 end Swap;
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 -- Start of processing for Switch_Row
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 begin
kono
parents:
diff changeset
272 if Row_1 /= Row_2 then
kono
parents:
diff changeset
273 Det := Zero - Det;
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 for J in M'Range (2) loop
kono
parents:
diff changeset
276 Swap (M (Row_1, J), M (Row_2, J));
kono
parents:
diff changeset
277 end loop;
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 for J in N'Range (2) loop
kono
parents:
diff changeset
280 Swap (N (Row_1 - M'First (1) + N'First (1), J),
kono
parents:
diff changeset
281 N (Row_2 - M'First (1) + N'First (1), J));
kono
parents:
diff changeset
282 end loop;
kono
parents:
diff changeset
283 end if;
kono
parents:
diff changeset
284 end Switch_Row;
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 -- Local declarations
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 Row : Integer := M'First (1);
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 -- Start of processing for Forward_Eliminate
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 begin
kono
parents:
diff changeset
293 Det := One;
kono
parents:
diff changeset
294
kono
parents:
diff changeset
295 for J in M'Range (2) loop
kono
parents:
diff changeset
296 declare
kono
parents:
diff changeset
297 Max_Row : Integer := Row;
kono
parents:
diff changeset
298 Max_Abs : Real'Base := 0.0;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 begin
kono
parents:
diff changeset
301 -- Find best pivot in column J, starting in row Row
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 for K in Row .. M'Last (1) loop
kono
parents:
diff changeset
304 declare
kono
parents:
diff changeset
305 New_Abs : constant Real'Base := abs M (K, J);
kono
parents:
diff changeset
306 begin
kono
parents:
diff changeset
307 if Max_Abs < New_Abs then
kono
parents:
diff changeset
308 Max_Abs := New_Abs;
kono
parents:
diff changeset
309 Max_Row := K;
kono
parents:
diff changeset
310 end if;
kono
parents:
diff changeset
311 end;
kono
parents:
diff changeset
312 end loop;
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 if Max_Abs > 0.0 then
kono
parents:
diff changeset
315 Switch_Row (M, N, Row, Max_Row);
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 -- The temporaries below are necessary to force a copy of the
kono
parents:
diff changeset
318 -- value and avoid improper aliasing.
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 declare
kono
parents:
diff changeset
321 Scale : constant Scalar := M (Row, J);
kono
parents:
diff changeset
322 begin
kono
parents:
diff changeset
323 Divide_Row (M, N, Row, Scale);
kono
parents:
diff changeset
324 end;
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 for U in Row + 1 .. M'Last (1) loop
kono
parents:
diff changeset
327 declare
kono
parents:
diff changeset
328 Factor : constant Scalar := M (U, J);
kono
parents:
diff changeset
329 begin
kono
parents:
diff changeset
330 Sub_Row (N, U, Row, Factor);
kono
parents:
diff changeset
331 Sub_Row (M, U, Row, Factor);
kono
parents:
diff changeset
332 end;
kono
parents:
diff changeset
333 end loop;
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 exit when Row >= M'Last (1);
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 Row := Row + 1;
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 else
kono
parents:
diff changeset
340 -- Set zero (note that we do not have literals)
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 Det := Zero;
kono
parents:
diff changeset
343 end if;
kono
parents:
diff changeset
344 end;
kono
parents:
diff changeset
345 end loop;
kono
parents:
diff changeset
346 end Forward_Eliminate;
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 -------------------
kono
parents:
diff changeset
349 -- Inner_Product --
kono
parents:
diff changeset
350 -------------------
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 function Inner_Product
kono
parents:
diff changeset
353 (Left : Left_Vector;
kono
parents:
diff changeset
354 Right : Right_Vector) return Result_Scalar
kono
parents:
diff changeset
355 is
kono
parents:
diff changeset
356 R : Result_Scalar := Zero;
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 begin
kono
parents:
diff changeset
359 if Left'Length /= Right'Length then
kono
parents:
diff changeset
360 raise Constraint_Error with
kono
parents:
diff changeset
361 "vectors are of different length in inner product";
kono
parents:
diff changeset
362 end if;
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 for J in Left'Range loop
kono
parents:
diff changeset
365 R := R + Left (J) * Right (J - Left'First + Right'First);
kono
parents:
diff changeset
366 end loop;
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 return R;
kono
parents:
diff changeset
369 end Inner_Product;
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 -------------
kono
parents:
diff changeset
372 -- L2_Norm --
kono
parents:
diff changeset
373 -------------
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 function L2_Norm (X : X_Vector) return Result_Real'Base is
kono
parents:
diff changeset
376 Sum : Result_Real'Base := 0.0;
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 begin
kono
parents:
diff changeset
379 for J in X'Range loop
kono
parents:
diff changeset
380 Sum := Sum + Result_Real'Base (abs X (J))**2;
kono
parents:
diff changeset
381 end loop;
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 return Sqrt (Sum);
kono
parents:
diff changeset
384 end L2_Norm;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 ----------------------------------
kono
parents:
diff changeset
387 -- Matrix_Elementwise_Operation --
kono
parents:
diff changeset
388 ----------------------------------
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 function Matrix_Elementwise_Operation (X : X_Matrix) return Result_Matrix is
kono
parents:
diff changeset
391 begin
kono
parents:
diff changeset
392 return R : Result_Matrix (X'Range (1), X'Range (2)) do
kono
parents:
diff changeset
393 for J in R'Range (1) loop
kono
parents:
diff changeset
394 for K in R'Range (2) loop
kono
parents:
diff changeset
395 R (J, K) := Operation (X (J, K));
kono
parents:
diff changeset
396 end loop;
kono
parents:
diff changeset
397 end loop;
kono
parents:
diff changeset
398 end return;
kono
parents:
diff changeset
399 end Matrix_Elementwise_Operation;
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 ----------------------------------
kono
parents:
diff changeset
402 -- Vector_Elementwise_Operation --
kono
parents:
diff changeset
403 ----------------------------------
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 function Vector_Elementwise_Operation (X : X_Vector) return Result_Vector is
kono
parents:
diff changeset
406 begin
kono
parents:
diff changeset
407 return R : Result_Vector (X'Range) do
kono
parents:
diff changeset
408 for J in R'Range loop
kono
parents:
diff changeset
409 R (J) := Operation (X (J));
kono
parents:
diff changeset
410 end loop;
kono
parents:
diff changeset
411 end return;
kono
parents:
diff changeset
412 end Vector_Elementwise_Operation;
kono
parents:
diff changeset
413
kono
parents:
diff changeset
414 -----------------------------------------
kono
parents:
diff changeset
415 -- Matrix_Matrix_Elementwise_Operation --
kono
parents:
diff changeset
416 -----------------------------------------
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 function Matrix_Matrix_Elementwise_Operation
kono
parents:
diff changeset
419 (Left : Left_Matrix;
kono
parents:
diff changeset
420 Right : Right_Matrix) return Result_Matrix
kono
parents:
diff changeset
421 is
kono
parents:
diff changeset
422 begin
kono
parents:
diff changeset
423 return R : Result_Matrix (Left'Range (1), Left'Range (2)) do
kono
parents:
diff changeset
424 if Left'Length (1) /= Right'Length (1)
kono
parents:
diff changeset
425 or else
kono
parents:
diff changeset
426 Left'Length (2) /= Right'Length (2)
kono
parents:
diff changeset
427 then
kono
parents:
diff changeset
428 raise Constraint_Error with
kono
parents:
diff changeset
429 "matrices are of different dimension in elementwise operation";
kono
parents:
diff changeset
430 end if;
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 for J in R'Range (1) loop
kono
parents:
diff changeset
433 for K in R'Range (2) loop
kono
parents:
diff changeset
434 R (J, K) :=
kono
parents:
diff changeset
435 Operation
kono
parents:
diff changeset
436 (Left (J, K),
kono
parents:
diff changeset
437 Right
kono
parents:
diff changeset
438 (J - R'First (1) + Right'First (1),
kono
parents:
diff changeset
439 K - R'First (2) + Right'First (2)));
kono
parents:
diff changeset
440 end loop;
kono
parents:
diff changeset
441 end loop;
kono
parents:
diff changeset
442 end return;
kono
parents:
diff changeset
443 end Matrix_Matrix_Elementwise_Operation;
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 ------------------------------------------------
kono
parents:
diff changeset
446 -- Matrix_Matrix_Scalar_Elementwise_Operation --
kono
parents:
diff changeset
447 ------------------------------------------------
kono
parents:
diff changeset
448
kono
parents:
diff changeset
449 function Matrix_Matrix_Scalar_Elementwise_Operation
kono
parents:
diff changeset
450 (X : X_Matrix;
kono
parents:
diff changeset
451 Y : Y_Matrix;
kono
parents:
diff changeset
452 Z : Z_Scalar) return Result_Matrix
kono
parents:
diff changeset
453 is
kono
parents:
diff changeset
454 begin
kono
parents:
diff changeset
455 return R : Result_Matrix (X'Range (1), X'Range (2)) do
kono
parents:
diff changeset
456 if X'Length (1) /= Y'Length (1)
kono
parents:
diff changeset
457 or else
kono
parents:
diff changeset
458 X'Length (2) /= Y'Length (2)
kono
parents:
diff changeset
459 then
kono
parents:
diff changeset
460 raise Constraint_Error with
kono
parents:
diff changeset
461 "matrices are of different dimension in elementwise operation";
kono
parents:
diff changeset
462 end if;
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 for J in R'Range (1) loop
kono
parents:
diff changeset
465 for K in R'Range (2) loop
kono
parents:
diff changeset
466 R (J, K) :=
kono
parents:
diff changeset
467 Operation
kono
parents:
diff changeset
468 (X (J, K),
kono
parents:
diff changeset
469 Y (J - R'First (1) + Y'First (1),
kono
parents:
diff changeset
470 K - R'First (2) + Y'First (2)),
kono
parents:
diff changeset
471 Z);
kono
parents:
diff changeset
472 end loop;
kono
parents:
diff changeset
473 end loop;
kono
parents:
diff changeset
474 end return;
kono
parents:
diff changeset
475 end Matrix_Matrix_Scalar_Elementwise_Operation;
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 -----------------------------------------
kono
parents:
diff changeset
478 -- Vector_Vector_Elementwise_Operation --
kono
parents:
diff changeset
479 -----------------------------------------
kono
parents:
diff changeset
480
kono
parents:
diff changeset
481 function Vector_Vector_Elementwise_Operation
kono
parents:
diff changeset
482 (Left : Left_Vector;
kono
parents:
diff changeset
483 Right : Right_Vector) return Result_Vector
kono
parents:
diff changeset
484 is
kono
parents:
diff changeset
485 begin
kono
parents:
diff changeset
486 return R : Result_Vector (Left'Range) do
kono
parents:
diff changeset
487 if Left'Length /= Right'Length then
kono
parents:
diff changeset
488 raise Constraint_Error with
kono
parents:
diff changeset
489 "vectors are of different length in elementwise operation";
kono
parents:
diff changeset
490 end if;
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 for J in R'Range loop
kono
parents:
diff changeset
493 R (J) := Operation (Left (J), Right (J - R'First + Right'First));
kono
parents:
diff changeset
494 end loop;
kono
parents:
diff changeset
495 end return;
kono
parents:
diff changeset
496 end Vector_Vector_Elementwise_Operation;
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 ------------------------------------------------
kono
parents:
diff changeset
499 -- Vector_Vector_Scalar_Elementwise_Operation --
kono
parents:
diff changeset
500 ------------------------------------------------
kono
parents:
diff changeset
501
kono
parents:
diff changeset
502 function Vector_Vector_Scalar_Elementwise_Operation
kono
parents:
diff changeset
503 (X : X_Vector;
kono
parents:
diff changeset
504 Y : Y_Vector;
kono
parents:
diff changeset
505 Z : Z_Scalar) return Result_Vector is
kono
parents:
diff changeset
506 begin
kono
parents:
diff changeset
507 return R : Result_Vector (X'Range) do
kono
parents:
diff changeset
508 if X'Length /= Y'Length then
kono
parents:
diff changeset
509 raise Constraint_Error with
kono
parents:
diff changeset
510 "vectors are of different length in elementwise operation";
kono
parents:
diff changeset
511 end if;
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 for J in R'Range loop
kono
parents:
diff changeset
514 R (J) := Operation (X (J), Y (J - X'First + Y'First), Z);
kono
parents:
diff changeset
515 end loop;
kono
parents:
diff changeset
516 end return;
kono
parents:
diff changeset
517 end Vector_Vector_Scalar_Elementwise_Operation;
kono
parents:
diff changeset
518
kono
parents:
diff changeset
519 -----------------------------------------
kono
parents:
diff changeset
520 -- Matrix_Scalar_Elementwise_Operation --
kono
parents:
diff changeset
521 -----------------------------------------
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 function Matrix_Scalar_Elementwise_Operation
kono
parents:
diff changeset
524 (Left : Left_Matrix;
kono
parents:
diff changeset
525 Right : Right_Scalar) return Result_Matrix
kono
parents:
diff changeset
526 is
kono
parents:
diff changeset
527 begin
kono
parents:
diff changeset
528 return R : Result_Matrix (Left'Range (1), Left'Range (2)) do
kono
parents:
diff changeset
529 for J in R'Range (1) loop
kono
parents:
diff changeset
530 for K in R'Range (2) loop
kono
parents:
diff changeset
531 R (J, K) := Operation (Left (J, K), Right);
kono
parents:
diff changeset
532 end loop;
kono
parents:
diff changeset
533 end loop;
kono
parents:
diff changeset
534 end return;
kono
parents:
diff changeset
535 end Matrix_Scalar_Elementwise_Operation;
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 -----------------------------------------
kono
parents:
diff changeset
538 -- Vector_Scalar_Elementwise_Operation --
kono
parents:
diff changeset
539 -----------------------------------------
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 function Vector_Scalar_Elementwise_Operation
kono
parents:
diff changeset
542 (Left : Left_Vector;
kono
parents:
diff changeset
543 Right : Right_Scalar) return Result_Vector
kono
parents:
diff changeset
544 is
kono
parents:
diff changeset
545 begin
kono
parents:
diff changeset
546 return R : Result_Vector (Left'Range) do
kono
parents:
diff changeset
547 for J in R'Range loop
kono
parents:
diff changeset
548 R (J) := Operation (Left (J), Right);
kono
parents:
diff changeset
549 end loop;
kono
parents:
diff changeset
550 end return;
kono
parents:
diff changeset
551 end Vector_Scalar_Elementwise_Operation;
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 -----------------------------------------
kono
parents:
diff changeset
554 -- Scalar_Matrix_Elementwise_Operation --
kono
parents:
diff changeset
555 -----------------------------------------
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 function Scalar_Matrix_Elementwise_Operation
kono
parents:
diff changeset
558 (Left : Left_Scalar;
kono
parents:
diff changeset
559 Right : Right_Matrix) return Result_Matrix
kono
parents:
diff changeset
560 is
kono
parents:
diff changeset
561 begin
kono
parents:
diff changeset
562 return R : Result_Matrix (Right'Range (1), Right'Range (2)) do
kono
parents:
diff changeset
563 for J in R'Range (1) loop
kono
parents:
diff changeset
564 for K in R'Range (2) loop
kono
parents:
diff changeset
565 R (J, K) := Operation (Left, Right (J, K));
kono
parents:
diff changeset
566 end loop;
kono
parents:
diff changeset
567 end loop;
kono
parents:
diff changeset
568 end return;
kono
parents:
diff changeset
569 end Scalar_Matrix_Elementwise_Operation;
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 -----------------------------------------
kono
parents:
diff changeset
572 -- Scalar_Vector_Elementwise_Operation --
kono
parents:
diff changeset
573 -----------------------------------------
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 function Scalar_Vector_Elementwise_Operation
kono
parents:
diff changeset
576 (Left : Left_Scalar;
kono
parents:
diff changeset
577 Right : Right_Vector) return Result_Vector
kono
parents:
diff changeset
578 is
kono
parents:
diff changeset
579 begin
kono
parents:
diff changeset
580 return R : Result_Vector (Right'Range) do
kono
parents:
diff changeset
581 for J in R'Range loop
kono
parents:
diff changeset
582 R (J) := Operation (Left, Right (J));
kono
parents:
diff changeset
583 end loop;
kono
parents:
diff changeset
584 end return;
kono
parents:
diff changeset
585 end Scalar_Vector_Elementwise_Operation;
kono
parents:
diff changeset
586
kono
parents:
diff changeset
587 ----------
kono
parents:
diff changeset
588 -- Sqrt --
kono
parents:
diff changeset
589 ----------
kono
parents:
diff changeset
590
kono
parents:
diff changeset
591 function Sqrt (X : Real'Base) return Real'Base is
kono
parents:
diff changeset
592 Root, Next : Real'Base;
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594 begin
kono
parents:
diff changeset
595 -- Be defensive: any comparisons with NaN values will yield False.
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597 if not (X > 0.0) then
kono
parents:
diff changeset
598 if X = 0.0 then
kono
parents:
diff changeset
599 return X;
kono
parents:
diff changeset
600 else
kono
parents:
diff changeset
601 raise Argument_Error;
kono
parents:
diff changeset
602 end if;
kono
parents:
diff changeset
603
kono
parents:
diff changeset
604 elsif X > Real'Base'Last then
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 -- X is infinity, which is its own square root
kono
parents:
diff changeset
607
kono
parents:
diff changeset
608 return X;
kono
parents:
diff changeset
609 end if;
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 -- Compute an initial estimate based on:
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- X = M * R**E and Sqrt (X) = Sqrt (M) * R**(E / 2.0),
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 -- where M is the mantissa, R is the radix and E the exponent.
kono
parents:
diff changeset
616
kono
parents:
diff changeset
617 -- By ignoring the mantissa and ignoring the case of an odd
kono
parents:
diff changeset
618 -- exponent, we get a final error that is at most R. In other words,
kono
parents:
diff changeset
619 -- the result has about a single bit precision.
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 Root := Real'Base (Real'Machine_Radix) ** (Real'Exponent (X) / 2);
kono
parents:
diff changeset
622
kono
parents:
diff changeset
623 -- Because of the poor initial estimate, use the Babylonian method of
kono
parents:
diff changeset
624 -- computing the square root, as it is stable for all inputs. Every step
kono
parents:
diff changeset
625 -- will roughly double the precision of the result. Just a few steps
kono
parents:
diff changeset
626 -- suffice in most cases. Eight iterations should give about 2**8 bits
kono
parents:
diff changeset
627 -- of precision.
kono
parents:
diff changeset
628
kono
parents:
diff changeset
629 for J in 1 .. 8 loop
kono
parents:
diff changeset
630 Next := (Root + X / Root) / 2.0;
kono
parents:
diff changeset
631 exit when Root = Next;
kono
parents:
diff changeset
632 Root := Next;
kono
parents:
diff changeset
633 end loop;
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635 return Root;
kono
parents:
diff changeset
636 end Sqrt;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 ---------------------------
kono
parents:
diff changeset
639 -- Matrix_Matrix_Product --
kono
parents:
diff changeset
640 ---------------------------
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 function Matrix_Matrix_Product
kono
parents:
diff changeset
643 (Left : Left_Matrix;
kono
parents:
diff changeset
644 Right : Right_Matrix) return Result_Matrix
kono
parents:
diff changeset
645 is
kono
parents:
diff changeset
646 begin
kono
parents:
diff changeset
647 return R : Result_Matrix (Left'Range (1), Right'Range (2)) do
kono
parents:
diff changeset
648 if Left'Length (2) /= Right'Length (1) then
kono
parents:
diff changeset
649 raise Constraint_Error with
kono
parents:
diff changeset
650 "incompatible dimensions in matrix multiplication";
kono
parents:
diff changeset
651 end if;
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 for J in R'Range (1) loop
kono
parents:
diff changeset
654 for K in R'Range (2) loop
kono
parents:
diff changeset
655 declare
kono
parents:
diff changeset
656 S : Result_Scalar := Zero;
kono
parents:
diff changeset
657
kono
parents:
diff changeset
658 begin
kono
parents:
diff changeset
659 for M in Left'Range (2) loop
kono
parents:
diff changeset
660 S := S + Left (J, M) *
kono
parents:
diff changeset
661 Right
kono
parents:
diff changeset
662 (M - Left'First (2) + Right'First (1), K);
kono
parents:
diff changeset
663 end loop;
kono
parents:
diff changeset
664
kono
parents:
diff changeset
665 R (J, K) := S;
kono
parents:
diff changeset
666 end;
kono
parents:
diff changeset
667 end loop;
kono
parents:
diff changeset
668 end loop;
kono
parents:
diff changeset
669 end return;
kono
parents:
diff changeset
670 end Matrix_Matrix_Product;
kono
parents:
diff changeset
671
kono
parents:
diff changeset
672 ----------------------------
kono
parents:
diff changeset
673 -- Matrix_Vector_Solution --
kono
parents:
diff changeset
674 ----------------------------
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 function Matrix_Vector_Solution (A : Matrix; X : Vector) return Vector is
kono
parents:
diff changeset
677 N : constant Natural := A'Length (1);
kono
parents:
diff changeset
678 MA : Matrix := A;
kono
parents:
diff changeset
679 MX : Matrix (A'Range (1), 1 .. 1);
kono
parents:
diff changeset
680 R : Vector (A'Range (2));
kono
parents:
diff changeset
681 Det : Scalar;
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 begin
kono
parents:
diff changeset
684 if A'Length (2) /= N then
kono
parents:
diff changeset
685 raise Constraint_Error with "matrix is not square";
kono
parents:
diff changeset
686 end if;
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 if X'Length /= N then
kono
parents:
diff changeset
689 raise Constraint_Error with "incompatible vector length";
kono
parents:
diff changeset
690 end if;
kono
parents:
diff changeset
691
kono
parents:
diff changeset
692 for J in 0 .. MX'Length (1) - 1 loop
kono
parents:
diff changeset
693 MX (MX'First (1) + J, 1) := X (X'First + J);
kono
parents:
diff changeset
694 end loop;
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 Forward_Eliminate (MA, MX, Det);
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 if Det = Zero then
kono
parents:
diff changeset
699 raise Constraint_Error with "matrix is singular";
kono
parents:
diff changeset
700 end if;
kono
parents:
diff changeset
701
kono
parents:
diff changeset
702 Back_Substitute (MA, MX);
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 for J in 0 .. R'Length - 1 loop
kono
parents:
diff changeset
705 R (R'First + J) := MX (MX'First (1) + J, 1);
kono
parents:
diff changeset
706 end loop;
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 return R;
kono
parents:
diff changeset
709 end Matrix_Vector_Solution;
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 ----------------------------
kono
parents:
diff changeset
712 -- Matrix_Matrix_Solution --
kono
parents:
diff changeset
713 ----------------------------
kono
parents:
diff changeset
714
kono
parents:
diff changeset
715 function Matrix_Matrix_Solution (A, X : Matrix) return Matrix is
kono
parents:
diff changeset
716 N : constant Natural := A'Length (1);
kono
parents:
diff changeset
717 MA : Matrix (A'Range (2), A'Range (2));
kono
parents:
diff changeset
718 MB : Matrix (A'Range (2), X'Range (2));
kono
parents:
diff changeset
719 Det : Scalar;
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 begin
kono
parents:
diff changeset
722 if A'Length (2) /= N then
kono
parents:
diff changeset
723 raise Constraint_Error with "matrix is not square";
kono
parents:
diff changeset
724 end if;
kono
parents:
diff changeset
725
kono
parents:
diff changeset
726 if X'Length (1) /= N then
kono
parents:
diff changeset
727 raise Constraint_Error with "matrices have unequal number of rows";
kono
parents:
diff changeset
728 end if;
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 for J in 0 .. A'Length (1) - 1 loop
kono
parents:
diff changeset
731 for K in MA'Range (2) loop
kono
parents:
diff changeset
732 MA (MA'First (1) + J, K) := A (A'First (1) + J, K);
kono
parents:
diff changeset
733 end loop;
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 for K in MB'Range (2) loop
kono
parents:
diff changeset
736 MB (MB'First (1) + J, K) := X (X'First (1) + J, K);
kono
parents:
diff changeset
737 end loop;
kono
parents:
diff changeset
738 end loop;
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 Forward_Eliminate (MA, MB, Det);
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 if Det = Zero then
kono
parents:
diff changeset
743 raise Constraint_Error with "matrix is singular";
kono
parents:
diff changeset
744 end if;
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 Back_Substitute (MA, MB);
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 return MB;
kono
parents:
diff changeset
749 end Matrix_Matrix_Solution;
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 ---------------------------
kono
parents:
diff changeset
752 -- Matrix_Vector_Product --
kono
parents:
diff changeset
753 ---------------------------
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 function Matrix_Vector_Product
kono
parents:
diff changeset
756 (Left : Matrix;
kono
parents:
diff changeset
757 Right : Right_Vector) return Result_Vector
kono
parents:
diff changeset
758 is
kono
parents:
diff changeset
759 begin
kono
parents:
diff changeset
760 return R : Result_Vector (Left'Range (1)) do
kono
parents:
diff changeset
761 if Left'Length (2) /= Right'Length then
kono
parents:
diff changeset
762 raise Constraint_Error with
kono
parents:
diff changeset
763 "incompatible dimensions in matrix-vector multiplication";
kono
parents:
diff changeset
764 end if;
kono
parents:
diff changeset
765
kono
parents:
diff changeset
766 for J in Left'Range (1) loop
kono
parents:
diff changeset
767 declare
kono
parents:
diff changeset
768 S : Result_Scalar := Zero;
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770 begin
kono
parents:
diff changeset
771 for K in Left'Range (2) loop
kono
parents:
diff changeset
772 S := S + Left (J, K)
kono
parents:
diff changeset
773 * Right (K - Left'First (2) + Right'First);
kono
parents:
diff changeset
774 end loop;
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 R (J) := S;
kono
parents:
diff changeset
777 end;
kono
parents:
diff changeset
778 end loop;
kono
parents:
diff changeset
779 end return;
kono
parents:
diff changeset
780 end Matrix_Vector_Product;
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782 -------------------
kono
parents:
diff changeset
783 -- Outer_Product --
kono
parents:
diff changeset
784 -------------------
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 function Outer_Product
kono
parents:
diff changeset
787 (Left : Left_Vector;
kono
parents:
diff changeset
788 Right : Right_Vector) return Matrix
kono
parents:
diff changeset
789 is
kono
parents:
diff changeset
790 begin
kono
parents:
diff changeset
791 return R : Matrix (Left'Range, Right'Range) do
kono
parents:
diff changeset
792 for J in R'Range (1) loop
kono
parents:
diff changeset
793 for K in R'Range (2) loop
kono
parents:
diff changeset
794 R (J, K) := Left (J) * Right (K);
kono
parents:
diff changeset
795 end loop;
kono
parents:
diff changeset
796 end loop;
kono
parents:
diff changeset
797 end return;
kono
parents:
diff changeset
798 end Outer_Product;
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 -----------------
kono
parents:
diff changeset
801 -- Swap_Column --
kono
parents:
diff changeset
802 -----------------
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 procedure Swap_Column (A : in out Matrix; Left, Right : Integer) is
kono
parents:
diff changeset
805 Temp : Scalar;
kono
parents:
diff changeset
806 begin
kono
parents:
diff changeset
807 for J in A'Range (1) loop
kono
parents:
diff changeset
808 Temp := A (J, Left);
kono
parents:
diff changeset
809 A (J, Left) := A (J, Right);
kono
parents:
diff changeset
810 A (J, Right) := Temp;
kono
parents:
diff changeset
811 end loop;
kono
parents:
diff changeset
812 end Swap_Column;
kono
parents:
diff changeset
813
kono
parents:
diff changeset
814 ---------------
kono
parents:
diff changeset
815 -- Transpose --
kono
parents:
diff changeset
816 ---------------
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 procedure Transpose (A : Matrix; R : out Matrix) is
kono
parents:
diff changeset
819 begin
kono
parents:
diff changeset
820 for J in R'Range (1) loop
kono
parents:
diff changeset
821 for K in R'Range (2) loop
kono
parents:
diff changeset
822 R (J, K) := A (K - R'First (2) + A'First (1),
kono
parents:
diff changeset
823 J - R'First (1) + A'First (2));
kono
parents:
diff changeset
824 end loop;
kono
parents:
diff changeset
825 end loop;
kono
parents:
diff changeset
826 end Transpose;
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 -------------------------------
kono
parents:
diff changeset
829 -- Update_Matrix_With_Matrix --
kono
parents:
diff changeset
830 -------------------------------
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 procedure Update_Matrix_With_Matrix (X : in out X_Matrix; Y : Y_Matrix) is
kono
parents:
diff changeset
833 begin
kono
parents:
diff changeset
834 if X'Length (1) /= Y'Length (1)
kono
parents:
diff changeset
835 or else
kono
parents:
diff changeset
836 X'Length (2) /= Y'Length (2)
kono
parents:
diff changeset
837 then
kono
parents:
diff changeset
838 raise Constraint_Error with
kono
parents:
diff changeset
839 "matrices are of different dimension in update operation";
kono
parents:
diff changeset
840 end if;
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 for J in X'Range (1) loop
kono
parents:
diff changeset
843 for K in X'Range (2) loop
kono
parents:
diff changeset
844 Update (X (J, K), Y (J - X'First (1) + Y'First (1),
kono
parents:
diff changeset
845 K - X'First (2) + Y'First (2)));
kono
parents:
diff changeset
846 end loop;
kono
parents:
diff changeset
847 end loop;
kono
parents:
diff changeset
848 end Update_Matrix_With_Matrix;
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 -------------------------------
kono
parents:
diff changeset
851 -- Update_Vector_With_Vector --
kono
parents:
diff changeset
852 -------------------------------
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 procedure Update_Vector_With_Vector (X : in out X_Vector; Y : Y_Vector) is
kono
parents:
diff changeset
855 begin
kono
parents:
diff changeset
856 if X'Length /= Y'Length then
kono
parents:
diff changeset
857 raise Constraint_Error with
kono
parents:
diff changeset
858 "vectors are of different length in update operation";
kono
parents:
diff changeset
859 end if;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 for J in X'Range loop
kono
parents:
diff changeset
862 Update (X (J), Y (J - X'First + Y'First));
kono
parents:
diff changeset
863 end loop;
kono
parents:
diff changeset
864 end Update_Vector_With_Vector;
kono
parents:
diff changeset
865
kono
parents:
diff changeset
866 -----------------
kono
parents:
diff changeset
867 -- Unit_Matrix --
kono
parents:
diff changeset
868 -----------------
kono
parents:
diff changeset
869
kono
parents:
diff changeset
870 function Unit_Matrix
kono
parents:
diff changeset
871 (Order : Positive;
kono
parents:
diff changeset
872 First_1 : Integer := 1;
kono
parents:
diff changeset
873 First_2 : Integer := 1) return Matrix
kono
parents:
diff changeset
874 is
kono
parents:
diff changeset
875 begin
kono
parents:
diff changeset
876 return R : Matrix (First_1 .. Check_Unit_Last (First_1, Order, First_1),
kono
parents:
diff changeset
877 First_2 .. Check_Unit_Last (First_2, Order, First_2))
kono
parents:
diff changeset
878 do
kono
parents:
diff changeset
879 R := (others => (others => Zero));
kono
parents:
diff changeset
880
kono
parents:
diff changeset
881 for J in 0 .. Order - 1 loop
kono
parents:
diff changeset
882 R (First_1 + J, First_2 + J) := One;
kono
parents:
diff changeset
883 end loop;
kono
parents:
diff changeset
884 end return;
kono
parents:
diff changeset
885 end Unit_Matrix;
kono
parents:
diff changeset
886
kono
parents:
diff changeset
887 -----------------
kono
parents:
diff changeset
888 -- Unit_Vector --
kono
parents:
diff changeset
889 -----------------
kono
parents:
diff changeset
890
kono
parents:
diff changeset
891 function Unit_Vector
kono
parents:
diff changeset
892 (Index : Integer;
kono
parents:
diff changeset
893 Order : Positive;
kono
parents:
diff changeset
894 First : Integer := 1) return Vector
kono
parents:
diff changeset
895 is
kono
parents:
diff changeset
896 begin
kono
parents:
diff changeset
897 return R : Vector (First .. Check_Unit_Last (Index, Order, First)) do
kono
parents:
diff changeset
898 R := (others => Zero);
kono
parents:
diff changeset
899 R (Index) := One;
kono
parents:
diff changeset
900 end return;
kono
parents:
diff changeset
901 end Unit_Vector;
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903 ---------------------------
kono
parents:
diff changeset
904 -- Vector_Matrix_Product --
kono
parents:
diff changeset
905 ---------------------------
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907 function Vector_Matrix_Product
kono
parents:
diff changeset
908 (Left : Left_Vector;
kono
parents:
diff changeset
909 Right : Matrix) return Result_Vector
kono
parents:
diff changeset
910 is
kono
parents:
diff changeset
911 begin
kono
parents:
diff changeset
912 return R : Result_Vector (Right'Range (2)) do
kono
parents:
diff changeset
913 if Left'Length /= Right'Length (1) then
kono
parents:
diff changeset
914 raise Constraint_Error with
kono
parents:
diff changeset
915 "incompatible dimensions in vector-matrix multiplication";
kono
parents:
diff changeset
916 end if;
kono
parents:
diff changeset
917
kono
parents:
diff changeset
918 for J in Right'Range (2) loop
kono
parents:
diff changeset
919 declare
kono
parents:
diff changeset
920 S : Result_Scalar := Zero;
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 begin
kono
parents:
diff changeset
923 for K in Right'Range (1) loop
kono
parents:
diff changeset
924 S := S + Left (K - Right'First (1)
kono
parents:
diff changeset
925 + Left'First) * Right (K, J);
kono
parents:
diff changeset
926 end loop;
kono
parents:
diff changeset
927
kono
parents:
diff changeset
928 R (J) := S;
kono
parents:
diff changeset
929 end;
kono
parents:
diff changeset
930 end loop;
kono
parents:
diff changeset
931 end return;
kono
parents:
diff changeset
932 end Vector_Matrix_Product;
kono
parents:
diff changeset
933
kono
parents:
diff changeset
934 end System.Generic_Array_Operations;