| Previous | Table of Contents | Next |
10.4.2.9. Implementing the Generic Matrix Package
From the exploration of HB.Vectors and Show_Matrices, the package implementation is easy to understand.
1 package body HB.Matrices_Generic is
2
3 function *
4 (K : ElementType; Right : Vector) return Vector is
5 Result: Vector(RightRange);
6 begin
7 for I in RightRange loop
8 Result(I) := K * Right(I);
9 end loop;
10 return Result;
11 end *;
12
13 function + (Left, Right : Vector) return Vector is
14 Result : Vector(LeftRange);
15 begin
16 if LeftLength /= RightLength then
17 raise Bounds_Error;
18 else
19 for I in LeftRange loop
20 Result(I) :=
21 Left(I) + Right(I - LeftFirst + RightFirst);
22 end loop;
23 return Result;
24 end if;
25 end +;
26
27 function *
28 (Left, Right : Vector) return ElementType is
29 Sum : ElementType := Zero;
30 begin
31 if LeftLength /= RightLength then
32 raise Bounds_Error;
33 else
34 for I in LeftRange loop
35 Sum := Sum +
36 Left(I) * Right(I - LeftFirst + RightFirst);
37 end loop;
38 return Sum;
39 end if;
40 end *;
41
42 function *
43 (K : ElementType; Right : Matrix) return Matrix is
44 Result: Matrix(RightRange(1), RightRange(2));
45 begin
46 for I in RightRange(1) loop
47 for J in RightRange(2) loop
48 Result(I,J) := K * Right(I,J);
49 end loop;
50 end loop;
51 return Result;
52 end *;
53
54 function Transpose (Left: Matrix) return Matrix is
55 Result: Matrix(LeftRange(2), LeftRange(1));
56 begin
57 for I in ResultRange(1) loop
58 for J in ResultRange(2) loop
59 Result(I,J) := Left(J,I);
60 end loop;
61 end loop;
62 return Result;
63 end Transpose;
64
65 function + (Left, Right : Matrix) return Matrix is
66 Result : Matrix(LeftRange(1), LeftRange(2));
67 begin
68 if LeftLength(1) /= RightLength(1) or
69 LeftLength(2) /= RightLength(2) then
70 raise Bounds_Error;
71 else
72 for I in LeftRange(1) loop
73 for J in LeftRange(2) loop
74 Result(I, J) := Left(I, J) +
75 Right(I - LeftFirst(1) + RightFirst(1),
76 J - LeftFirst(2) + RightFirst(2));
77 end loop;
78 end loop;
79 return Result;
80 end if;
81 end +;
82
83 function * (Left, Right : Matrix) return Matrix is
84 Result: Matrix(LeftRange(1), RightRange(2)) :=
85 (others => (others => Zero));
86 begin
87 if LeftLength(2) /= RightLength(1) then
88 raise Bounds_Error;
89 else
90 for RowL in LeftRange(1) loop
91 for ColR in RightRange(2) loop
92 for ColL in LeftRange(2) loop
93 Result(RowL, ColR) := Result(RowL, ColR) +
94 Left(RowL, ColL) *
95 Right((ColL-LeftFirst(2))+RightFirst(1),
96 ColR);
97 end loop;
98 end loop;
99 end loop;
100 end if;
101 return Result;
102 end *;
103
104 function *
105 (Left: Vector; Right: Matrix) return Vector is
106 Result: Vector(RightRange(2)) := (others => Zero);
107 begin
108 if LeftLength /= RightLength(1) then
109 raise Bounds_Error;
110 else
111 for C in RightRange(2) loop
112 for R in RightRange(1) loop
113 Result(C) := Result(C) + Right(R, C) *
114 Left(LeftFirst + (R-RightFirst(1)));
115 end loop;
116 end loop;
117 end if;
118 return Result;
119 end *;
120
121 function *
122 (Left: Matrix; Right: Vector) return Vector is
123 Result: Vector(LeftRange(1)) := (others => Zero);
124 begin
125 if LeftLength(2) /= RightLength then
126 raise Bounds_Error;
127 else
128 for R in LeftRange(1) loop
129 for C in LeftRange(2) loop
130 Result(R) := Result(R) + Left(R, C) *
131 Right(RightFirst + (C-LeftFirst(2)));
132 end loop;
133 end loop;
134 end if;
135 return Result;
136 end *;
137
138 end HB.Matrices_Generic;
I do not belabor the algorithms embodied in the various operations; these are well-known and straightforward algorithms from matrix algebra. From the Ada perspective, I point out the declaration (lines 84-85)
Result: Matrix(LeftRange(1), RightRange(2)) :=
(others => (others => Zero));
which sizes a result matrix in terms of the Left and Right matrix operands and further initializes all elements of this matrix to 0, the parameter representing the zero of the element type. This aggregate initialization is very concise and can be implemented efficiently because the programmer leaves it up to the compiler just how all the elements are initialized at execution time.
Finally, lines 87-88 give the conformability condition for matrix multiplication: Left must have as many columns as Right has rows.
| Previous | Table of Contents | Next |