1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * This is not the original file distributed by the Apache Software Foundation
20 * It has been modified by the Hipparchus project
21 */
22
23 package org.hipparchus.linear;
24
25 import org.hipparchus.analysis.UnivariateFunction;
26 import org.hipparchus.analysis.polynomials.SmoothStepFactory;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.exception.NullArgumentException;
29 import org.hipparchus.util.Blendable;
30 import org.hipparchus.util.FastMath;
31
32 /**
33 * Interface defining a real-valued matrix with basic algebraic operations.
34 * <p>
35 * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
36 * returns the element in the first row, first column of the matrix.</p>
37 *
38 */
39 public interface RealMatrix extends AnyMatrix, Blendable<RealMatrix> {
40
41 /**
42 * Create a new RealMatrix of the same type as the instance with the
43 * supplied
44 * row and column dimensions.
45 *
46 * @param rowDimension the number of rows in the new matrix
47 * @param columnDimension the number of columns in the new matrix
48 * @return a new matrix of the same type as the instance
49 * @throws MathIllegalArgumentException if row or column dimension is not
50 * positive.
51 */
52 RealMatrix createMatrix(int rowDimension, int columnDimension)
53 throws MathIllegalArgumentException;
54
55 /**
56 * Returns a (deep) copy of this.
57 *
58 * @return matrix copy
59 */
60 RealMatrix copy();
61
62 /**
63 * Returns the sum of {@code this} and {@code m}.
64 *
65 * @param m matrix to be added
66 * @return {@code this + m}
67 * @throws MathIllegalArgumentException if {@code m} is not the same
68 * size as {@code this}.
69 */
70 RealMatrix add(RealMatrix m)
71 throws MathIllegalArgumentException;
72
73 /**
74 * Returns {@code this} minus {@code m}.
75 *
76 * @param m matrix to be subtracted
77 * @return {@code this - m}
78 * @throws MathIllegalArgumentException if {@code m} is not the same
79 * size as {@code this}.
80 */
81 RealMatrix subtract(RealMatrix m)
82 throws MathIllegalArgumentException;
83
84 /**
85 * Returns the result of adding {@code d} to each entry of {@code this}.
86 *
87 * @param d value to be added to each entry
88 * @return {@code d + this}
89 */
90 RealMatrix scalarAdd(double d);
91
92 /**
93 * Returns the result of multiplying each entry of {@code this} by
94 * {@code d}.
95 *
96 * @param d value to multiply all entries by
97 * @return {@code d * this}
98 */
99 RealMatrix scalarMultiply(double d);
100
101 /**
102 * Returns the result of postmultiplying {@code this} by {@code m}.
103 *
104 * @param m matrix to postmultiply by
105 * @return {@code this * m}
106 * @throws MathIllegalArgumentException if
107 * {@code columnDimension(this) != rowDimension(m)}
108 */
109 RealMatrix multiply(RealMatrix m)
110 throws MathIllegalArgumentException;
111
112 /**
113 * Returns the result of postmultiplying {@code this} by {@code m^T}.
114 * <p>
115 * This is equivalent to call {@link #multiply(RealMatrix) multiply}(m.{@link #transpose()}),
116 * but some implementations may avoid building the intermediate transposed matrix.
117 * </p>
118 * @param m matrix to first transpose and second postmultiply by
119 * @return {@code this * m^T}
120 * @throws MathIllegalArgumentException if
121 * {@code columnDimension(this) != columnDimension(m)}
122 * @since 1.3
123 */
124 default RealMatrix multiplyTransposed(final RealMatrix m)
125 throws MathIllegalArgumentException {
126 return multiply(m.transpose());
127 }
128
129 /**
130 * Returns the result of postmultiplying {@code this^T} by {@code m}.
131 * <p>
132 * This is equivalent to call {@link #transpose()}.{@link #multiply(RealMatrix) multiply(m)},
133 * but some implementations may avoid building the intermediate transposed matrix.
134 * </p>
135 * @param m matrix to postmultiply by
136 * @return {@code this^T * m}
137 * @throws MathIllegalArgumentException if
138 * {@code columnDimension(this) != columnDimension(m)}
139 * @since 1.3
140 */
141 default RealMatrix transposeMultiply(final RealMatrix m)
142 throws MathIllegalArgumentException {
143 return transpose().multiply(m);
144 }
145
146 /**
147 * Returns the result of premultiplying {@code this} by {@code m}.
148 *
149 * @param m matrix to premultiply by
150 * @return {@code m * this}
151 * @throws MathIllegalArgumentException if
152 * {@code rowDimension(this) != columnDimension(m)}
153 */
154 RealMatrix preMultiply(RealMatrix m)
155 throws MathIllegalArgumentException;
156
157 /**
158 * Returns the result of multiplying {@code this} with itself {@code p}
159 * times. Depending on the underlying storage, instability for high powers
160 * might occur.
161 *
162 * @param p raise {@code this} to power {@code p}
163 * @return {@code this^p}
164 * @throws MathIllegalArgumentException if {@code p < 0}
165 * @throws MathIllegalArgumentException if the matrix is not square
166 */
167 RealMatrix power(int p)
168 throws MathIllegalArgumentException;
169
170 /** {@inheritDoc} */
171 @Override
172 default RealMatrix blendArithmeticallyWith(final RealMatrix other, final double blendingValue) {
173 SmoothStepFactory.checkBetweenZeroAndOneIncluded(blendingValue);
174 return this.scalarMultiply(1 - blendingValue).add(other.scalarMultiply(blendingValue));
175 }
176
177 /**
178 * Returns matrix entries as a two-dimensional array.
179 *
180 * @return 2-dimensional array of entries
181 */
182 double[][] getData();
183
184 /**
185 * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteColumnSumNorm.html">
186 * maximum absolute column sum norm</a> (L<sub>1</sub>) of the matrix.
187 *
188 * @return norm
189 */
190 default double getNorm1() {
191 return walkInColumnOrder(new RealMatrixPreservingVisitor() {
192
193 /** Last row index. */
194 private int endRow;
195
196 /** Sum of absolute values on one column. */
197 private double columnSum;
198
199 /** Maximal sum across all columns. */
200 private double maxColSum;
201
202 /** {@inheritDoc} */
203 @Override
204 public void start(final int rows, final int columns,
205 final int startRow, final int endRow,
206 final int startColumn, final int endColumn) {
207 this.endRow = endRow;
208 columnSum = 0;
209 maxColSum = 0;
210 }
211
212 /** {@inheritDoc} */
213 @Override
214 public void visit(final int row, final int column, final double value) {
215 columnSum += FastMath.abs(value);
216 if (row == endRow) {
217 maxColSum = FastMath.max(maxColSum, columnSum);
218 columnSum = 0;
219 }
220 }
221
222 /** {@inheritDoc} */
223 @Override
224 public double end() {
225 return maxColSum;
226 }
227 });
228 }
229
230 /**
231 * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
232 * maximum absolute row sum norm</a> (L<sub>∞</sub>) of the matrix.
233 *
234 * @return norm
235 */
236 default double getNormInfty() {
237 return walkInRowOrder(new RealMatrixPreservingVisitor() {
238
239 /** Last column index. */
240 private int endColumn;
241
242 /** Sum of absolute values on one row. */
243 private double rowSum;
244
245 /** Maximal sum across all rows. */
246 private double maxRowSum;
247
248 /** {@inheritDoc} */
249 @Override
250 public void start(final int rows, final int columns,
251 final int startRow, final int endRow,
252 final int startColumn, final int endColumn) {
253 this.endColumn = endColumn;
254 rowSum = 0;
255 maxRowSum = 0;
256 }
257
258 /** {@inheritDoc} */
259 @Override
260 public void visit(final int row, final int column, final double value) {
261 rowSum += FastMath.abs(value);
262 if (column == endColumn) {
263 maxRowSum = FastMath.max(maxRowSum, rowSum);
264 rowSum = 0;
265 }
266 }
267
268 /** {@inheritDoc} */
269 @Override
270 public double end() {
271 return maxRowSum;
272 }
273 });
274
275 }
276
277 /**
278 * Returns the <a href="http://mathworld.wolfram.com/FrobeniusNorm.html">
279 * Frobenius norm</a> of the matrix.
280 *
281 * @return norm
282 */
283 double getFrobeniusNorm();
284
285 /**
286 * Gets a submatrix. Rows and columns are indicated
287 * counting from 0 to n-1.
288 *
289 * @param startRow Initial row index
290 * @param endRow Final row index (inclusive)
291 * @param startColumn Initial column index
292 * @param endColumn Final column index (inclusive)
293 * @return The subMatrix containing the data of the
294 * specified rows and columns.
295 * @throws MathIllegalArgumentException if the indices are not valid.
296 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
297 * {@code endColumn < startColumn}.
298 */
299 RealMatrix getSubMatrix(int startRow, int endRow, int startColumn,
300 int endColumn)
301 throws MathIllegalArgumentException;
302
303 /**
304 * Gets a submatrix. Rows and columns are indicated counting from 0 to n-1.
305 *
306 * @param selectedRows Array of row indices.
307 * @param selectedColumns Array of column indices.
308 * @return The subMatrix containing the data in the specified rows and
309 * columns
310 * @throws NullArgumentException if the row or column selections are
311 * {@code null}
312 * @throws MathIllegalArgumentException if the row or column selections are empty (zero
313 * length).
314 * @throws MathIllegalArgumentException if the indices are not valid.
315 */
316 RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
317 throws MathIllegalArgumentException, NullArgumentException;
318
319 /**
320 * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
321 *
322 * @param startRow Initial row index
323 * @param endRow Final row index (inclusive)
324 * @param startColumn Initial column index
325 * @param endColumn Final column index (inclusive)
326 * @param destination The arrays where the submatrix data should be copied
327 * (if larger than rows/columns counts, only the upper-left part will be
328 * used)
329 * @throws MathIllegalArgumentException if the indices are not valid.
330 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
331 * {@code endColumn < startColumn}.
332 * @throws MathIllegalArgumentException if the destination array is too
333 * small.
334 */
335 void copySubMatrix(int startRow, int endRow, int startColumn,
336 int endColumn, double[][] destination)
337 throws MathIllegalArgumentException;
338
339 /**
340 * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
341 *
342 * @param selectedRows Array of row indices.
343 * @param selectedColumns Array of column indices.
344 * @param destination The arrays where the submatrix data should be copied
345 * (if larger than rows/columns counts, only the upper-left part will be
346 * used)
347 * @throws NullArgumentException if the row or column selections are
348 * {@code null}
349 * @throws MathIllegalArgumentException if the row or column selections are empty (zero
350 * length).
351 * @throws MathIllegalArgumentException if the indices are not valid.
352 * @throws MathIllegalArgumentException if the destination array is too
353 * small.
354 */
355 void copySubMatrix(int[] selectedRows, int[] selectedColumns,
356 double[][] destination)
357 throws MathIllegalArgumentException, NullArgumentException;
358
359 /**
360 * Replace the submatrix starting at {@code row, column} using data in the
361 * input {@code subMatrix} array. Indexes are 0-based.
362 * <p>
363 * Example:<br>
364 * Starting with </p>
365 * <pre>
366 * 1 2 3 4
367 * 5 6 7 8
368 * 9 0 1 2
369 * </pre>
370 * <p>
371 * and {@code subMatrix = {{3, 4} {5,6}}}, invoking
372 * {@code setSubMatrix(subMatrix,1,1))} will result in </p>
373 * <pre>
374 * 1 2 3 4
375 * 5 3 4 8
376 * 9 5 6 2
377 * </pre>
378 *
379 * @param subMatrix array containing the submatrix replacement data
380 * @param row row coordinate of the top, left element to be replaced
381 * @param column column coordinate of the top, left element to be replaced
382 * @throws MathIllegalArgumentException if {@code subMatrix} is empty.
383 * @throws MathIllegalArgumentException if {@code subMatrix} does not fit into
384 * this matrix from element in {@code (row, column)}.
385 * @throws MathIllegalArgumentException if {@code subMatrix} is not rectangular
386 * (not all rows have the same length) or empty.
387 * @throws NullArgumentException if {@code subMatrix} is {@code null}.
388 */
389 void setSubMatrix(double[][] subMatrix, int row, int column)
390 throws MathIllegalArgumentException, NullArgumentException;
391
392 /**
393 * Get the entries at the given row index as a row matrix. Row indices start
394 * at 0.
395 *
396 * @param row Row to be fetched.
397 * @return row Matrix.
398 * @throws MathIllegalArgumentException if the specified row index is invalid.
399 */
400 RealMatrix getRowMatrix(int row) throws MathIllegalArgumentException;
401
402 /**
403 * Sets the specified {@code row} of {@code this} matrix to the entries of
404 * the specified row {@code matrix}. Row indices start at 0.
405 *
406 * @param row Row to be set.
407 * @param matrix Row matrix to be copied (must have one row and the same
408 * number of columns as the instance).
409 * @throws MathIllegalArgumentException if the specified row index is invalid.
410 * @throws MathIllegalArgumentException if the row dimension of the
411 * {@code matrix} is not {@code 1}, or the column dimensions of {@code this}
412 * and {@code matrix} do not match.
413 */
414 void setRowMatrix(int row, RealMatrix matrix)
415 throws MathIllegalArgumentException;
416
417 /**
418 * Get the entries at the given column index as a column matrix. Column
419 * indices start at 0.
420 *
421 * @param column Column to be fetched.
422 * @return column Matrix.
423 * @throws MathIllegalArgumentException if the specified column index is invalid.
424 */
425 RealMatrix getColumnMatrix(int column)
426 throws MathIllegalArgumentException;
427
428 /**
429 * Sets the specified {@code column} of {@code this} matrix to the entries
430 * of the specified column {@code matrix}. Column indices start at 0.
431 *
432 * @param column Column to be set.
433 * @param matrix Column matrix to be copied (must have one column and the
434 * same number of rows as the instance).
435 * @throws MathIllegalArgumentException if the specified column index is invalid.
436 * @throws MathIllegalArgumentException if the column dimension of the
437 * {@code matrix} is not {@code 1}, or the row dimensions of {@code this}
438 * and {@code matrix} do not match.
439 */
440 void setColumnMatrix(int column, RealMatrix matrix)
441 throws MathIllegalArgumentException;
442
443 /**
444 * Returns the entries in row number {@code row} as a vector. Row indices
445 * start at 0.
446 *
447 * @param row Row to be fetched.
448 * @return a row vector.
449 * @throws MathIllegalArgumentException if the specified row index is invalid.
450 */
451 RealVector getRowVector(int row)
452 throws MathIllegalArgumentException;
453
454 /**
455 * Sets the specified {@code row} of {@code this} matrix to the entries of
456 * the specified {@code vector}. Row indices start at 0.
457 *
458 * @param row Row to be set.
459 * @param vector row vector to be copied (must have the same number of
460 * column as the instance).
461 * @throws MathIllegalArgumentException if the specified row index is invalid.
462 * @throws MathIllegalArgumentException if the {@code vector} dimension
463 * does not match the column dimension of {@code this} matrix.
464 */
465 void setRowVector(int row, RealVector vector)
466 throws MathIllegalArgumentException;
467
468 /**
469 * Get the entries at the given column index as a vector. Column indices
470 * start at 0.
471 *
472 * @param column Column to be fetched.
473 * @return a column vector.
474 * @throws MathIllegalArgumentException if the specified column index is invalid
475 */
476 RealVector getColumnVector(int column)
477 throws MathIllegalArgumentException;
478
479 /**
480 * Sets the specified {@code column} of {@code this} matrix to the entries
481 * of the specified {@code vector}. Column indices start at 0.
482 *
483 * @param column Column to be set.
484 * @param vector column vector to be copied (must have the same number of
485 * rows as the instance).
486 * @throws MathIllegalArgumentException if the specified column index is invalid.
487 * @throws MathIllegalArgumentException if the {@code vector} dimension
488 * does not match the row dimension of {@code this} matrix.
489 */
490 void setColumnVector(int column, RealVector vector)
491 throws MathIllegalArgumentException;
492
493 /**
494 * Get the entries at the given row index. Row indices start at 0.
495 *
496 * @param row Row to be fetched.
497 * @return the array of entries in the row.
498 * @throws MathIllegalArgumentException if the specified row index is not valid.
499 */
500 double[] getRow(int row) throws MathIllegalArgumentException;
501
502 /**
503 * Sets the specified {@code row} of {@code this} matrix to the entries
504 * of the specified {@code array}. Row indices start at 0.
505 *
506 * @param row Row to be set.
507 * @param array Row matrix to be copied (must have the same number of
508 * columns as the instance)
509 * @throws MathIllegalArgumentException if the specified row index is invalid.
510 * @throws MathIllegalArgumentException if the {@code array} length does
511 * not match the column dimension of {@code this} matrix.
512 */
513 void setRow(int row, double[] array)
514 throws MathIllegalArgumentException;
515
516 /**
517 * Get the entries at the given column index as an array. Column indices
518 * start at 0.
519 *
520 * @param column Column to be fetched.
521 * @return the array of entries in the column.
522 * @throws MathIllegalArgumentException if the specified column index is not valid.
523 */
524 double[] getColumn(int column) throws MathIllegalArgumentException;
525
526 /**
527 * Sets the specified {@code column} of {@code this} matrix to the entries
528 * of the specified {@code array}. Column indices start at 0.
529 *
530 * @param column Column to be set.
531 * @param array Column array to be copied (must have the same number of
532 * rows as the instance).
533 * @throws MathIllegalArgumentException if the specified column index is invalid.
534 * @throws MathIllegalArgumentException if the {@code array} length does
535 * not match the row dimension of {@code this} matrix.
536 */
537 void setColumn(int column, double[] array)
538 throws MathIllegalArgumentException;
539
540 /**
541 * Get the entry in the specified row and column. Row and column indices
542 * start at 0.
543 *
544 * @param row Row index of entry to be fetched.
545 * @param column Column index of entry to be fetched.
546 * @return the matrix entry at {@code (row, column)}.
547 * @throws MathIllegalArgumentException if the row or column index is not valid.
548 */
549 double getEntry(int row, int column) throws MathIllegalArgumentException;
550
551 /**
552 * Set the entry in the specified row and column. Row and column indices
553 * start at 0.
554 *
555 * @param row Row index of entry to be set.
556 * @param column Column index of entry to be set.
557 * @param value the new value of the entry.
558 * @throws MathIllegalArgumentException if the row or column index is not valid
559 */
560 void setEntry(int row, int column, double value) throws MathIllegalArgumentException;
561
562 /**
563 * Adds (in place) the specified value to the specified entry of
564 * {@code this} matrix. Row and column indices start at 0.
565 *
566 * @param row Row index of the entry to be modified.
567 * @param column Column index of the entry to be modified.
568 * @param increment value to add to the matrix entry.
569 * @throws MathIllegalArgumentException if the row or column index is not valid.
570 */
571 void addToEntry(int row, int column, double increment) throws MathIllegalArgumentException;
572
573 /**
574 * Multiplies (in place) the specified entry of {@code this} matrix by the
575 * specified value. Row and column indices start at 0.
576 *
577 * @param row Row index of the entry to be modified.
578 * @param column Column index of the entry to be modified.
579 * @param factor Multiplication factor for the matrix entry.
580 * @throws MathIllegalArgumentException if the row or column index is not valid.
581 */
582 void multiplyEntry(int row, int column, double factor) throws MathIllegalArgumentException;
583
584 /**
585 * Returns the transpose of this matrix.
586 *
587 * @return transpose matrix
588 */
589 RealMatrix transpose();
590
591 /**
592 * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
593 * trace</a> of the matrix (the sum of the elements on the main diagonal).
594 *
595 * @return the trace.
596 * @throws MathIllegalArgumentException if the matrix is not square.
597 */
598 double getTrace() throws MathIllegalArgumentException;
599
600 /**
601 * Returns the result of multiplying this by the vector {@code v}.
602 *
603 * @param v the vector to operate on
604 * @return {@code this * v}
605 * @throws MathIllegalArgumentException if the length of {@code v} does not
606 * match the column dimension of {@code this}.
607 */
608 double[] operate(double[] v) throws MathIllegalArgumentException;
609
610 /**
611 * Returns the result of multiplying this by the vector {@code v}.
612 *
613 * @param v the vector to operate on
614 * @return {@code this * v}
615 * @throws MathIllegalArgumentException if the dimension of {@code v} does not
616 * match the column dimension of {@code this}.
617 */
618 RealVector operate(RealVector v) throws MathIllegalArgumentException;
619
620 /**
621 * Returns the (row) vector result of premultiplying this by the vector {@code v}.
622 *
623 * @param v the row vector to premultiply by
624 * @return {@code v * this}
625 * @throws MathIllegalArgumentException if the length of {@code v} does not
626 * match the row dimension of {@code this}.
627 */
628 double[] preMultiply(double[] v) throws MathIllegalArgumentException;
629
630 /**
631 * Returns the (row) vector result of premultiplying this by the vector {@code v}.
632 *
633 * @param v the row vector to premultiply by
634 * @return {@code v * this}
635 * @throws MathIllegalArgumentException if the dimension of {@code v} does not
636 * match the row dimension of {@code this}.
637 */
638 RealVector preMultiply(RealVector v) throws MathIllegalArgumentException;
639
640 /**
641 * Visit (and possibly change) all matrix entries in row order.
642 * <p>Row order starts at upper left and iterating through all elements
643 * of a row from left to right before going to the leftmost element
644 * of the next row.</p>
645 * @param visitor visitor used to process all matrix entries
646 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
647 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
648 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
649 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
650 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
651 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
652 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
653 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
654 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
655 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
656 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
657 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
658 * of the walk
659 */
660 double walkInRowOrder(RealMatrixChangingVisitor visitor);
661
662 /**
663 * Visit (but don't change) all matrix entries in row order.
664 * <p>Row order starts at upper left and iterating through all elements
665 * of a row from left to right before going to the leftmost element
666 * of the next row.</p>
667 * @param visitor visitor used to process all matrix entries
668 * @see #walkInRowOrder(RealMatrixChangingVisitor)
669 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
670 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
671 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
672 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
673 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
674 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
675 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
676 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
677 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
678 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
679 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
680 * of the walk
681 */
682 double walkInRowOrder(RealMatrixPreservingVisitor visitor);
683
684 /**
685 * Visit (and possibly change) some matrix entries in row order.
686 * <p>Row order starts at upper left and iterating through all elements
687 * of a row from left to right before going to the leftmost element
688 * of the next row.</p>
689 * @param visitor visitor used to process all matrix entries
690 * @param startRow Initial row index
691 * @param endRow Final row index (inclusive)
692 * @param startColumn Initial column index
693 * @param endColumn Final column index
694 * @throws MathIllegalArgumentException if the indices are not valid.
695 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
696 * {@code endColumn < startColumn}.
697 * @see #walkInRowOrder(RealMatrixChangingVisitor)
698 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
699 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
700 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
701 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
702 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
703 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
704 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
705 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
706 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
707 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
708 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
709 * of the walk
710 */
711 double walkInRowOrder(RealMatrixChangingVisitor visitor, int startRow,
712 int endRow, int startColumn, int endColumn)
713 throws MathIllegalArgumentException;
714
715 /**
716 * Visit (but don't change) some matrix entries in row order.
717 * <p>Row order starts at upper left and iterating through all elements
718 * of a row from left to right before going to the leftmost element
719 * of the next row.</p>
720 * @param visitor visitor used to process all matrix entries
721 * @param startRow Initial row index
722 * @param endRow Final row index (inclusive)
723 * @param startColumn Initial column index
724 * @param endColumn Final column index
725 * @throws MathIllegalArgumentException if the indices are not valid.
726 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
727 * {@code endColumn < startColumn}.
728 * @see #walkInRowOrder(RealMatrixChangingVisitor)
729 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
730 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
731 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
732 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
733 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
734 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
735 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
736 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
737 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
738 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
739 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
740 * of the walk
741 */
742 double walkInRowOrder(RealMatrixPreservingVisitor visitor, int startRow,
743 int endRow, int startColumn, int endColumn)
744 throws MathIllegalArgumentException;
745
746 /**
747 * Visit (and possibly change) all matrix entries in column order.
748 * <p>Column order starts at upper left and iterating through all elements
749 * of a column from top to bottom before going to the topmost element
750 * of the next column.</p>
751 * @param visitor visitor used to process all matrix entries
752 * @see #walkInRowOrder(RealMatrixChangingVisitor)
753 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
754 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
755 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
756 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
757 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
758 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
759 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
760 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
761 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
762 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
763 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
764 * of the walk
765 */
766 double walkInColumnOrder(RealMatrixChangingVisitor visitor);
767
768 /**
769 * Visit (but don't change) all matrix entries in column order.
770 * <p>Column order starts at upper left and iterating through all elements
771 * of a column from top to bottom before going to the topmost element
772 * of the next column.</p>
773 * @param visitor visitor used to process all matrix entries
774 * @see #walkInRowOrder(RealMatrixChangingVisitor)
775 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
776 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
777 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
778 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
779 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
780 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
781 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
782 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
783 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
784 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
785 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
786 * of the walk
787 */
788 double walkInColumnOrder(RealMatrixPreservingVisitor visitor);
789
790 /**
791 * Visit (and possibly change) some matrix entries in column order.
792 * <p>Column order starts at upper left and iterating through all elements
793 * of a column from top to bottom before going to the topmost element
794 * of the next column.</p>
795 * @param visitor visitor used to process all matrix entries
796 * @param startRow Initial row index
797 * @param endRow Final row index (inclusive)
798 * @param startColumn Initial column index
799 * @param endColumn Final column index
800 * @throws MathIllegalArgumentException if the indices are not valid.
801 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
802 * {@code endColumn < startColumn}.
803 * @see #walkInRowOrder(RealMatrixChangingVisitor)
804 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
805 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
806 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
807 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
808 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
809 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
810 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
811 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
812 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
813 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
814 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
815 * of the walk
816 */
817 double walkInColumnOrder(RealMatrixChangingVisitor visitor, int startRow,
818 int endRow, int startColumn, int endColumn)
819 throws MathIllegalArgumentException;
820
821 /**
822 * Visit (but don't change) some matrix entries in column order.
823 * <p>Column order starts at upper left and iterating through all elements
824 * of a column from top to bottom before going to the topmost element
825 * of the next column.</p>
826 * @param visitor visitor used to process all matrix entries
827 * @param startRow Initial row index
828 * @param endRow Final row index (inclusive)
829 * @param startColumn Initial column index
830 * @param endColumn Final column index
831 * @throws MathIllegalArgumentException if the indices are not valid.
832 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
833 * {@code endColumn < startColumn}.
834 * @see #walkInRowOrder(RealMatrixChangingVisitor)
835 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
836 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
837 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
838 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
839 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
840 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
841 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
842 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
843 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
844 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
845 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
846 * of the walk
847 */
848 double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow,
849 int endRow, int startColumn, int endColumn)
850 throws MathIllegalArgumentException;
851
852 /**
853 * Visit (and possibly change) all matrix entries using the fastest possible order.
854 * <p>The fastest walking order depends on the exact matrix class. It may be
855 * different from traditional row or column orders.</p>
856 * @param visitor visitor used to process all matrix entries
857 * @see #walkInRowOrder(RealMatrixChangingVisitor)
858 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
859 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
860 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
861 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
862 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
863 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
864 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
865 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
866 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
867 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
868 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
869 * of the walk
870 */
871 double walkInOptimizedOrder(RealMatrixChangingVisitor visitor);
872
873 /**
874 * Visit (but don't change) all matrix entries using the fastest possible order.
875 * <p>The fastest walking order depends on the exact matrix class. It may be
876 * different from traditional row or column orders.</p>
877 * @param visitor visitor used to process all matrix entries
878 * @see #walkInRowOrder(RealMatrixChangingVisitor)
879 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
880 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
881 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
882 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
883 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
884 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
885 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
886 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
887 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
888 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
889 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
890 * of the walk
891 */
892 double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor);
893
894 /**
895 * Visit (and possibly change) some matrix entries using the fastest possible order.
896 * <p>The fastest walking order depends on the exact matrix class. It may be
897 * different from traditional row or column orders.</p>
898 * @param visitor visitor used to process all matrix entries
899 * @param startRow Initial row index
900 * @param endRow Final row index (inclusive)
901 * @param startColumn Initial column index
902 * @param endColumn Final column index (inclusive)
903 * @throws MathIllegalArgumentException if the indices are not valid.
904 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
905 * {@code endColumn < startColumn}.
906 * @see #walkInRowOrder(RealMatrixChangingVisitor)
907 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
908 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
909 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
910 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
911 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
912 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
913 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
914 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
915 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
916 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
917 * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
918 * of the walk
919 */
920 double walkInOptimizedOrder(RealMatrixChangingVisitor visitor,
921 int startRow, int endRow, int startColumn, int endColumn)
922 throws MathIllegalArgumentException;
923
924 /**
925 * Visit (but don't change) some matrix entries using the fastest possible order.
926 * <p>The fastest walking order depends on the exact matrix class. It may be
927 * different from traditional row or column orders.</p>
928 * @param visitor visitor used to process all matrix entries
929 * @param startRow Initial row index
930 * @param endRow Final row index (inclusive)
931 * @param startColumn Initial column index
932 * @param endColumn Final column index (inclusive)
933 * @throws MathIllegalArgumentException if the indices are not valid.
934 * @throws MathIllegalArgumentException if {@code endRow < startRow} or
935 * {@code endColumn < startColumn}.
936 * @see #walkInRowOrder(RealMatrixChangingVisitor)
937 * @see #walkInRowOrder(RealMatrixPreservingVisitor)
938 * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
939 * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
940 * @see #walkInColumnOrder(RealMatrixChangingVisitor)
941 * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
942 * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
943 * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
944 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
945 * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
946 * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
947 * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
948 * of the walk
949 */
950 double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor,
951 int startRow, int endRow, int startColumn, int endColumn)
952 throws MathIllegalArgumentException;
953
954 /**
955 * Acts as if implemented as:
956 * <pre>
957 * return copy().mapToSelf(function);
958 * </pre>
959 * Returns a new matrix. Does not change instance data.
960 *
961 * @param function Function to apply to each entry.
962 * @return a new matrix.
963 * @since 1.7
964 */
965 default RealMatrix map(UnivariateFunction function) {
966 return copy().mapToSelf(function);
967 }
968
969 /**
970 * Replace each entry by the result of applying the function to it.
971 *
972 * @param function Function to apply to each entry.
973 * @return a reference to this matrix.
974 * @since 1.7
975 */
976 default RealMatrix mapToSelf(final UnivariateFunction function) {
977 walkInOptimizedOrder(new RealMatrixChangingVisitor() {
978
979 /** {@inheritDoc} */
980 @Override
981 public double visit(int row, int column, double value) {
982 // apply the function to the current entry
983 return function.value(value);
984 }
985
986 /** {@inheritDoc} */
987 @Override
988 public void start(int rows, int columns, int startRow, int endRow,
989 int startColumn, int endColumn) {
990 }
991
992 /** {@inheritDoc} */
993 @Override
994 public double end() {
995 return 0;
996 }
997
998 });
999
1000 return this;
1001
1002 }
1003
1004 }