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