1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.field.linalg;
18
19 import java.util.Arrays;
20 import java.util.List;
21 import java.util.ArrayList;
22 import org.apache.commons.numbers.field.Field;
23 import org.apache.commons.math4.legacy.linear.AnyMatrix;
24
25
26
27
28
29
30
31
32 public final class FieldDenseMatrix<T>
33 implements AnyMatrix {
34
35 private final Field<T> field;
36
37 private final int rows;
38
39 private final int columns;
40
41
42
43
44
45
46
47 private final T[] data;
48
49
50
51
52
53
54
55 @SuppressWarnings("unchecked")
56 private FieldDenseMatrix(Field<T> f,
57 int r,
58 int c) {
59 if (r <= 0 ||
60 c <= 0) {
61 throw new IllegalArgumentException("Negative size");
62 }
63
64 field = f;
65 rows = r;
66 columns = c;
67 data = (T[]) new Object[r * c];
68 }
69
70
71
72
73
74
75
76
77
78
79
80 public static <T> FieldDenseMatrix<T> create(Field<T> f,
81 int r,
82 int c) {
83 return new FieldDenseMatrix<>(f, r, c);
84 }
85
86
87
88
89
90
91
92
93
94
95
96 public static <T> FieldDenseMatrix<T> zero(Field<T> f,
97 int r,
98 int c) {
99 return create(f, r, c).fill(f.zero());
100 }
101
102
103
104
105
106
107
108
109
110
111 public static <T> FieldDenseMatrix<T> identity(Field<T> f,
112 int n) {
113 final FieldDenseMatrix<T> r = zero(f, n, n);
114
115 for (int i = 0; i < n; i++) {
116 r.set(i, i, f.one());
117 }
118
119 return r;
120 }
121
122
123 @Override
124 public boolean equals(Object other) {
125 if (this == other) {
126 return true;
127 } else {
128 if (other instanceof FieldDenseMatrix) {
129 final FieldDenseMatrix<?> m = (FieldDenseMatrix<?>) other;
130 return field.equals(m.field) &&
131 rows == m.rows &&
132 columns == m.columns &&
133 Arrays.equals(data, m.data);
134 } else {
135 return false;
136 }
137 }
138 }
139
140
141
142
143
144
145 public FieldDenseMatrix<T> copy() {
146 final FieldDenseMatrix<T> r = create(field, rows, columns);
147 System.arraycopy(data, 0, r.data, 0, data.length);
148 return r;
149 }
150
151
152
153
154
155
156 public FieldDenseMatrix<T> transpose() {
157 final FieldDenseMatrix<T> r = create(field, columns, rows);
158
159 for (int i = 0; i < rows; i++) {
160 for (int j = 0; j < columns; j++) {
161 r.set(j, i, get(i, j));
162 }
163 }
164
165 return r;
166 }
167
168
169 @Override
170 public int getRowDimension() {
171 return rows;
172 }
173
174
175 @Override
176 public int getColumnDimension() {
177 return columns;
178 }
179
180
181
182
183 public Field<T> getField() {
184 return field;
185 }
186
187
188
189
190
191
192
193 public FieldDenseMatrix<T> fill(T value) {
194 Arrays.fill(data, value);
195 return this;
196 }
197
198
199
200
201
202
203
204
205 public T get(int i,
206 int j) {
207 return data[i * columns + j];
208 }
209
210
211
212
213
214
215
216
217 public void set(int i,
218 int j,
219 T value) {
220 data[i * columns + j] = value;
221 }
222
223
224
225
226
227
228
229
230 public FieldDenseMatrix<T> add(FieldDenseMatrix<T> other) {
231 checkAdd(other);
232 final FieldDenseMatrix<T> r = create(field, rows, columns);
233
234 for (int i = 0; i < data.length; i++) {
235 r.data[i] = field.add(data[i], other.data[i]);
236 }
237
238 return r;
239 }
240
241
242
243
244
245
246
247
248 public FieldDenseMatrix<T> subtract(FieldDenseMatrix<T> other) {
249 checkAdd(other);
250 final FieldDenseMatrix<T> r = create(field, rows, columns);
251
252 for (int i = 0; i < data.length; i++) {
253 r.data[i] = field.subtract(data[i], other.data[i]);
254 }
255
256 return r;
257 }
258
259
260
261
262
263
264 public FieldDenseMatrix<T> negate() {
265 final FieldDenseMatrix<T> r = create(field, rows, columns);
266
267 for (int i = 0; i < data.length; i++) {
268 r.data[i] = field.negate(data[i]);
269 }
270
271 return r;
272 }
273
274
275
276
277
278
279
280
281 public FieldDenseMatrix<T> multiply(FieldDenseMatrix<T> other) {
282 checkMultiply(other);
283 final FieldDenseMatrix<T> r = zero(field, rows, other.columns);
284
285 for (int i = 0; i < rows; i++) {
286 final int o1 = i * columns;
287 final int o2 = i * r.columns;
288 for (int j = 0; j < other.columns; j++) {
289 final int o3 = o2 + j;
290 for (int k = 0; k < columns; k++) {
291 r.data[o3] = field.add(r.data[o3],
292 field.multiply(data[o1 + k],
293 other.data[k * other.columns + j]));
294 }
295 }
296 }
297
298 return r;
299 }
300
301
302
303
304
305
306
307
308 public FieldDenseMatrix<T> pow(int p) {
309 checkMultiply(this);
310
311 if (p < 0) {
312 throw new IllegalArgumentException("Negative exponent: " + p);
313 }
314
315 if (p == 0) {
316 return identity(field, rows);
317 }
318
319 if (p == 1) {
320 return copy();
321 }
322
323 final int power = p - 1;
324
325
326
327
328
329 final char[] binary = Integer.toBinaryString(power).toCharArray();
330 final ArrayList<Integer> nonZeroPositions = new ArrayList<>();
331
332 for (int i = 0; i < binary.length; i++) {
333 if (binary[i] == '1') {
334 final int pos = binary.length - i - 1;
335 nonZeroPositions.add(pos);
336 }
337 }
338
339 final List<FieldDenseMatrix<T>> results = new ArrayList<>(binary.length);
340 results.add(this);
341 for (int i = 1; i < binary.length; i++) {
342 final FieldDenseMatrix<T> s = results.get(i - 1);
343 final FieldDenseMatrix<T> r = s.multiply(s);
344 results.add(r);
345 }
346
347 FieldDenseMatrix<T> r = this;
348 for (Integer i : nonZeroPositions) {
349 r = r.multiply(results.get(i));
350 }
351
352 return r;
353 }
354
355
356 @Override
357 public int hashCode() {
358 assert false : "hashCode not designed";
359 return 42;
360 }
361 }