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 }