1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.linear;
19
20 import java.io.Serializable;
21
22 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
23 import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
24 import org.apache.commons.math4.legacy.exception.NoDataException;
25 import org.apache.commons.math4.legacy.exception.NullArgumentException;
26 import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
27
28
29
30
31
32 public class Array2DRowRealMatrix extends AbstractRealMatrix implements Serializable {
33
34 private static final long serialVersionUID = -1067294169172445528L;
35
36
37 private double[][] data;
38
39
40
41
42 public Array2DRowRealMatrix() {}
43
44
45
46
47
48
49
50
51
52 public Array2DRowRealMatrix(final int rowDimension,
53 final int columnDimension) {
54 super(rowDimension, columnDimension);
55 data = new double[rowDimension][columnDimension];
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public Array2DRowRealMatrix(final double[][] d) {
72 copyIn(d);
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public Array2DRowRealMatrix(final double[][] d, final boolean copyArray) {
92 if (copyArray) {
93 copyIn(d);
94 } else {
95 if (d == null) {
96 throw new NullArgumentException();
97 }
98 final int nRows = d.length;
99 if (nRows == 0) {
100 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_ROW);
101 }
102 final int nCols = d[0].length;
103 if (nCols == 0) {
104 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
105 }
106 for (int r = 1; r < nRows; r++) {
107 if (d[r].length != nCols) {
108 throw new DimensionMismatchException(d[r].length, nCols);
109 }
110 }
111 data = d;
112 }
113 }
114
115
116
117
118
119
120
121
122 public Array2DRowRealMatrix(final double[] v) {
123 final int nRows = v.length;
124 data = new double[nRows][1];
125 for (int row = 0; row < nRows; row++) {
126 data[row][0] = v[row];
127 }
128 }
129
130
131 @Override
132 public RealMatrix createMatrix(final int rowDimension,
133 final int columnDimension) {
134 return new Array2DRowRealMatrix(rowDimension, columnDimension);
135 }
136
137
138 @Override
139 public RealMatrix copy() {
140 return new Array2DRowRealMatrix(copyOut(), false);
141 }
142
143
144
145
146
147
148
149
150
151 public Array2DRowRealMatrix add(final Array2DRowRealMatrix m) {
152
153 checkAdd(m);
154
155 final int rowCount = getRowDimension();
156 final int columnCount = getColumnDimension();
157 final double[][] outData = new double[rowCount][columnCount];
158 for (int row = 0; row < rowCount; row++) {
159 final double[] dataRow = data[row];
160 final double[] mRow = m.data[row];
161 final double[] outDataRow = outData[row];
162 for (int col = 0; col < columnCount; col++) {
163 outDataRow[col] = dataRow[col] + mRow[col];
164 }
165 }
166
167 return new Array2DRowRealMatrix(outData, false);
168 }
169
170
171
172
173
174
175
176
177
178 public Array2DRowRealMatrix subtract(final Array2DRowRealMatrix m) {
179 checkAdd(m);
180
181 final int rowCount = getRowDimension();
182 final int columnCount = getColumnDimension();
183 final double[][] outData = new double[rowCount][columnCount];
184 for (int row = 0; row < rowCount; row++) {
185 final double[] dataRow = data[row];
186 final double[] mRow = m.data[row];
187 final double[] outDataRow = outData[row];
188 for (int col = 0; col < columnCount; col++) {
189 outDataRow[col] = dataRow[col] - mRow[col];
190 }
191 }
192
193 return new Array2DRowRealMatrix(outData, false);
194 }
195
196
197
198
199
200
201
202
203
204 public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m) {
205 checkMultiply(m);
206
207 final int nRows = this.getRowDimension();
208 final int nCols = m.getColumnDimension();
209 final int nSum = this.getColumnDimension();
210
211 final double[][] outData = new double[nRows][nCols];
212
213 final double[] mCol = new double[nSum];
214 final double[][] mData = m.data;
215
216
217 for (int col = 0; col < nCols; col++) {
218
219
220 for (int mRow = 0; mRow < nSum; mRow++) {
221 mCol[mRow] = mData[mRow][col];
222 }
223
224 for (int row = 0; row < nRows; row++) {
225 final double[] dataRow = data[row];
226 double sum = 0;
227 for (int i = 0; i < nSum; i++) {
228 sum += dataRow[i] * mCol[i];
229 }
230 outData[row][col] = sum;
231 }
232 }
233
234 return new Array2DRowRealMatrix(outData, false);
235 }
236
237
238 @Override
239 public double[][] getData() {
240 return copyOut();
241 }
242
243
244
245
246
247
248 public double[][] getDataRef() {
249 return data;
250 }
251
252
253 @Override
254 public void setSubMatrix(final double[][] subMatrix, final int row,
255 final int column) {
256 if (data == null) {
257 if (row > 0) {
258 throw new MathIllegalStateException(LocalizedFormats.FIRST_ROWS_NOT_INITIALIZED_YET, row);
259 }
260 if (column > 0) {
261 throw new MathIllegalStateException(LocalizedFormats.FIRST_COLUMNS_NOT_INITIALIZED_YET, column);
262 }
263 NullArgumentException.check(subMatrix);
264 final int nRows = subMatrix.length;
265 if (nRows == 0) {
266 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_ROW);
267 }
268
269 final int nCols = subMatrix[0].length;
270 if (nCols == 0) {
271 throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_COLUMN);
272 }
273 data = new double[subMatrix.length][nCols];
274 for (int i = 0; i < data.length; ++i) {
275 if (subMatrix[i].length != nCols) {
276 throw new DimensionMismatchException(subMatrix[i].length, nCols);
277 }
278 System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
279 }
280 } else {
281 super.setSubMatrix(subMatrix, row, column);
282 }
283 }
284
285
286 @Override
287 public double getEntry(final int row, final int column) {
288 try {
289 return data[row][column];
290 } catch (IndexOutOfBoundsException e) {
291
292 MatrixUtils.checkMatrixIndex(this, row, column);
293
294 throw e;
295 }
296 }
297
298
299 @Override
300 public void setEntry(final int row, final int column, final double value) {
301 MatrixUtils.checkMatrixIndex(this, row, column);
302 data[row][column] = value;
303 }
304
305
306 @Override
307 public void addToEntry(final int row, final int column,
308 final double increment) {
309 MatrixUtils.checkMatrixIndex(this, row, column);
310 data[row][column] += increment;
311 }
312
313
314 @Override
315 public void multiplyEntry(final int row, final int column,
316 final double factor) {
317 MatrixUtils.checkMatrixIndex(this, row, column);
318 data[row][column] *= factor;
319 }
320
321
322 @Override
323 public int getRowDimension() {
324 return (data == null) ? 0 : data.length;
325 }
326
327
328 @Override
329 public int getColumnDimension() {
330 return (data == null || data[0] == null) ? 0 : data[0].length;
331 }
332
333
334 @Override
335 public double[] operate(final double[] v) {
336 final int nRows = this.getRowDimension();
337 final int nCols = this.getColumnDimension();
338 if (v.length != nCols) {
339 throw new DimensionMismatchException(v.length, nCols);
340 }
341 final double[] out = new double[nRows];
342 for (int row = 0; row < nRows; row++) {
343 final double[] dataRow = data[row];
344 double sum = 0;
345 for (int i = 0; i < nCols; i++) {
346 sum += dataRow[i] * v[i];
347 }
348 out[row] = sum;
349 }
350 return out;
351 }
352
353
354 @Override
355 public double[] preMultiply(final double[] v) {
356 final int nRows = getRowDimension();
357 final int nCols = getColumnDimension();
358 if (v.length != nRows) {
359 throw new DimensionMismatchException(v.length, nRows);
360 }
361
362 final double[] out = new double[nCols];
363 for (int col = 0; col < nCols; ++col) {
364 double sum = 0;
365 for (int i = 0; i < nRows; ++i) {
366 sum += data[i][col] * v[i];
367 }
368 out[col] = sum;
369 }
370
371 return out;
372 }
373
374
375 @Override
376 public RealMatrix getSubMatrix(final int startRow, final int endRow,
377 final int startColumn, final int endColumn) {
378 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
379 final int rowCount = endRow - startRow + 1;
380 final int columnCount = endColumn - startColumn + 1;
381 final double[][] outData = new double[rowCount][columnCount];
382 for (int i = 0; i < rowCount; ++i) {
383 System.arraycopy(data[startRow + i], startColumn, outData[i], 0, columnCount);
384 }
385
386 Array2DRowRealMatrix subMatrix = new Array2DRowRealMatrix();
387 subMatrix.data = outData;
388 return subMatrix;
389 }
390
391
392 @Override
393 public double walkInRowOrder(final RealMatrixChangingVisitor visitor) {
394 final int rows = getRowDimension();
395 final int columns = getColumnDimension();
396 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
397 for (int i = 0; i < rows; ++i) {
398 final double[] rowI = data[i];
399 for (int j = 0; j < columns; ++j) {
400 rowI[j] = visitor.visit(i, j, rowI[j]);
401 }
402 }
403 return visitor.end();
404 }
405
406
407 @Override
408 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) {
409 final int rows = getRowDimension();
410 final int columns = getColumnDimension();
411 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
412 for (int i = 0; i < rows; ++i) {
413 final double[] rowI = data[i];
414 for (int j = 0; j < columns; ++j) {
415 visitor.visit(i, j, rowI[j]);
416 }
417 }
418 return visitor.end();
419 }
420
421
422 @Override
423 public double walkInRowOrder(final RealMatrixChangingVisitor visitor,
424 final int startRow, final int endRow,
425 final int startColumn, final int endColumn) {
426 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
427 visitor.start(getRowDimension(), getColumnDimension(),
428 startRow, endRow, startColumn, endColumn);
429 for (int i = startRow; i <= endRow; ++i) {
430 final double[] rowI = data[i];
431 for (int j = startColumn; j <= endColumn; ++j) {
432 rowI[j] = visitor.visit(i, j, rowI[j]);
433 }
434 }
435 return visitor.end();
436 }
437
438
439 @Override
440 public double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
441 final int startRow, final int endRow,
442 final int startColumn, final int endColumn) {
443 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
444 visitor.start(getRowDimension(), getColumnDimension(),
445 startRow, endRow, startColumn, endColumn);
446 for (int i = startRow; i <= endRow; ++i) {
447 final double[] rowI = data[i];
448 for (int j = startColumn; j <= endColumn; ++j) {
449 visitor.visit(i, j, rowI[j]);
450 }
451 }
452 return visitor.end();
453 }
454
455
456 @Override
457 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) {
458 final int rows = getRowDimension();
459 final int columns = getColumnDimension();
460 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
461 for (int j = 0; j < columns; ++j) {
462 for (int i = 0; i < rows; ++i) {
463 final double[] rowI = data[i];
464 rowI[j] = visitor.visit(i, j, rowI[j]);
465 }
466 }
467 return visitor.end();
468 }
469
470
471 @Override
472 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) {
473 final int rows = getRowDimension();
474 final int columns = getColumnDimension();
475 visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
476 for (int j = 0; j < columns; ++j) {
477 for (int i = 0; i < rows; ++i) {
478 visitor.visit(i, j, data[i][j]);
479 }
480 }
481 return visitor.end();
482 }
483
484
485 @Override
486 public double walkInColumnOrder(final RealMatrixChangingVisitor visitor,
487 final int startRow, final int endRow,
488 final int startColumn, final int endColumn) {
489 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
490 visitor.start(getRowDimension(), getColumnDimension(),
491 startRow, endRow, startColumn, endColumn);
492 for (int j = startColumn; j <= endColumn; ++j) {
493 for (int i = startRow; i <= endRow; ++i) {
494 final double[] rowI = data[i];
495 rowI[j] = visitor.visit(i, j, rowI[j]);
496 }
497 }
498 return visitor.end();
499 }
500
501
502 @Override
503 public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor,
504 final int startRow, final int endRow,
505 final int startColumn, final int endColumn) {
506 MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn);
507 visitor.start(getRowDimension(), getColumnDimension(),
508 startRow, endRow, startColumn, endColumn);
509 for (int j = startColumn; j <= endColumn; ++j) {
510 for (int i = startRow; i <= endRow; ++i) {
511 visitor.visit(i, j, data[i][j]);
512 }
513 }
514 return visitor.end();
515 }
516
517
518
519
520
521
522 private double[][] copyOut() {
523 final int nRows = this.getRowDimension();
524 final double[][] out = new double[nRows][this.getColumnDimension()];
525
526 for (int i = 0; i < nRows; i++) {
527 System.arraycopy(data[i], 0, out[i], 0, data[i].length);
528 }
529 return out;
530 }
531
532
533
534
535
536
537
538
539
540 private void copyIn(final double[][] in) {
541 setSubMatrix(in, 0, 0);
542 }
543
544
545 @Override
546 public double[] getRow(final int row) {
547 MatrixUtils.checkRowIndex(this, row);
548 final int nCols = getColumnDimension();
549 final double[] out = new double[nCols];
550 System.arraycopy(data[row], 0, out, 0, nCols);
551 return out;
552 }
553
554
555 @Override
556 public void setRow(final int row,
557 final double[] array) {
558 MatrixUtils.checkRowIndex(this, row);
559 final int nCols = getColumnDimension();
560 if (array.length != nCols) {
561 throw new MatrixDimensionMismatchException(1, array.length, 1, nCols);
562 }
563 System.arraycopy(array, 0, data[row], 0, nCols);
564 }
565 }