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