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