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 }