RealMatrix.java

  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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.linear;

  22. import org.hipparchus.analysis.UnivariateFunction;
  23. import org.hipparchus.analysis.polynomials.SmoothStepFactory;
  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.exception.NullArgumentException;
  26. import org.hipparchus.util.Blendable;
  27. import org.hipparchus.util.FastMath;

  28. /**
  29.  * Interface defining a real-valued matrix with basic algebraic operations.
  30.  * <p>
  31.  * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
  32.  * returns the element in the first row, first column of the matrix.</p>
  33.  *
  34.  */
  35. public interface RealMatrix extends AnyMatrix, Blendable<RealMatrix> {

  36.     /**
  37.      * Create a new RealMatrix of the same type as the instance with the
  38.      * supplied
  39.      * row and column dimensions.
  40.      *
  41.      * @param rowDimension the number of rows in the new matrix
  42.      * @param columnDimension the number of columns in the new matrix
  43.      * @return a new matrix of the same type as the instance
  44.      * @throws MathIllegalArgumentException if row or column dimension is not
  45.      * positive.
  46.      */
  47.     RealMatrix createMatrix(int rowDimension, int columnDimension)
  48.         throws MathIllegalArgumentException;

  49.     /**
  50.      * Returns a (deep) copy of this.
  51.      *
  52.      * @return matrix copy
  53.      */
  54.     RealMatrix copy();

  55.     /**
  56.      * Returns the sum of {@code this} and {@code m}.
  57.      *
  58.      * @param m matrix to be added
  59.      * @return {@code this + m}
  60.      * @throws MathIllegalArgumentException if {@code m} is not the same
  61.      * size as {@code this}.
  62.      */
  63.     RealMatrix add(RealMatrix m)
  64.         throws MathIllegalArgumentException;

  65.     /**
  66.      * Returns {@code this} minus {@code m}.
  67.      *
  68.      * @param m matrix to be subtracted
  69.      * @return {@code this - m}
  70.      * @throws MathIllegalArgumentException if {@code m} is not the same
  71.      * size as {@code this}.
  72.      */
  73.     RealMatrix subtract(RealMatrix m)
  74.         throws MathIllegalArgumentException;

  75.     /**
  76.      * Returns the result of adding {@code d} to each entry of {@code this}.
  77.      *
  78.      * @param d value to be added to each entry
  79.      * @return {@code d + this}
  80.      */
  81.     RealMatrix scalarAdd(double d);

  82.     /**
  83.      * Returns the result of multiplying each entry of {@code this} by
  84.      * {@code d}.
  85.      *
  86.      * @param d value to multiply all entries by
  87.      * @return {@code d * this}
  88.      */
  89.     RealMatrix scalarMultiply(double d);

  90.     /**
  91.      * Returns the result of postmultiplying {@code this} by {@code m}.
  92.      *
  93.      * @param m matrix to postmultiply by
  94.      * @return {@code this * m}
  95.      * @throws MathIllegalArgumentException if
  96.      * {@code columnDimension(this) != rowDimension(m)}
  97.      */
  98.     RealMatrix multiply(RealMatrix m)
  99.         throws MathIllegalArgumentException;

  100.     /**
  101.      * Returns the result of postmultiplying {@code this} by {@code m^T}.
  102.      * <p>
  103.      * This is equivalent to call {@link #multiply(RealMatrix) multiply}(m.{@link #transpose()}),
  104.      * but some implementations may avoid building the intermediate transposed matrix.
  105.      * </p>
  106.      * @param m matrix to first transpose and second postmultiply by
  107.      * @return {@code this * m^T}
  108.      * @throws MathIllegalArgumentException if
  109.      * {@code columnDimension(this) != columnDimension(m)}
  110.      * @since 1.3
  111.      */
  112.     default RealMatrix multiplyTransposed(final RealMatrix m)
  113.         throws MathIllegalArgumentException {
  114.         return multiply(m.transpose());
  115.     }

  116.     /**
  117.      * Returns the result of postmultiplying {@code this^T} by {@code m}.
  118.      * <p>
  119.      * This is equivalent to call {@link #transpose()}.{@link #multiply(RealMatrix) multiply(m)},
  120.      * but some implementations may avoid building the intermediate transposed matrix.
  121.      * </p>
  122.      * @param m matrix to postmultiply by
  123.      * @return {@code this^T * m}
  124.      * @throws MathIllegalArgumentException if
  125.      * {@code columnDimension(this) != columnDimension(m)}
  126.      * @since 1.3
  127.      */
  128.     default RealMatrix transposeMultiply(final RealMatrix m)
  129.         throws MathIllegalArgumentException {
  130.         return transpose().multiply(m);
  131.     }

  132.     /**
  133.      * Returns the result of premultiplying {@code this} by {@code m}.
  134.      *
  135.      * @param m matrix to premultiply by
  136.      * @return {@code m * this}
  137.      * @throws MathIllegalArgumentException if
  138.      * {@code rowDimension(this) != columnDimension(m)}
  139.      */
  140.     RealMatrix preMultiply(RealMatrix m)
  141.         throws MathIllegalArgumentException;

  142.     /**
  143.      * Returns the result of multiplying {@code this} with itself {@code p}
  144.      * times. Depending on the underlying storage, instability for high powers
  145.      * might occur.
  146.      *
  147.      * @param p raise {@code this} to power {@code p}
  148.      * @return {@code this^p}
  149.      * @throws MathIllegalArgumentException if {@code p < 0}
  150.      * @throws MathIllegalArgumentException if the matrix is not square
  151.      */
  152.     RealMatrix power(int p)
  153.         throws MathIllegalArgumentException;

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     default RealMatrix blendArithmeticallyWith(final RealMatrix other, final double blendingValue) {
  157.         SmoothStepFactory.checkBetweenZeroAndOneIncluded(blendingValue);
  158.         return this.scalarMultiply(1 - blendingValue).add(other.scalarMultiply(blendingValue));
  159.     }

  160.     /**
  161.      * Returns matrix entries as a two-dimensional array.
  162.      *
  163.      * @return 2-dimensional array of entries
  164.      */
  165.     double[][] getData();

  166.     /**
  167.      * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteColumnSumNorm.html">
  168.      * maximum absolute column sum norm</a> (L<sub>1</sub>) of the matrix.
  169.      *
  170.      * @return norm
  171.      */
  172.     default double getNorm1() {
  173.         return walkInColumnOrder(new RealMatrixPreservingVisitor() {

  174.             /** Last row index. */
  175.             private int endRow;

  176.             /** Sum of absolute values on one column. */
  177.             private double columnSum;

  178.             /** Maximal sum across all columns. */
  179.             private double maxColSum;

  180.             /** {@inheritDoc} */
  181.             @Override
  182.             public void start(final int rows, final int columns,
  183.                               final int startRow, final int endRow,
  184.                               final int startColumn, final int endColumn) {
  185.                 this.endRow = endRow;
  186.                 columnSum   = 0;
  187.                 maxColSum   = 0;
  188.             }

  189.             /** {@inheritDoc} */
  190.             @Override
  191.             public void visit(final int row, final int column, final double value) {
  192.                 columnSum += FastMath.abs(value);
  193.                 if (row == endRow) {
  194.                     maxColSum = FastMath.max(maxColSum, columnSum);
  195.                     columnSum = 0;
  196.                 }
  197.             }

  198.             /** {@inheritDoc} */
  199.             @Override
  200.             public double end() {
  201.                 return maxColSum;
  202.             }
  203.         });
  204.     }

  205.     /**
  206.      * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
  207.      * maximum absolute row sum norm</a> (L<sub>&infin;</sub>) of the matrix.
  208.      *
  209.      * @return norm
  210.      */
  211.     default double getNormInfty() {
  212.         return walkInRowOrder(new RealMatrixPreservingVisitor() {

  213.             /** Last column index. */
  214.             private int endColumn;

  215.             /** Sum of absolute values on one row. */
  216.             private double rowSum;

  217.             /** Maximal sum across all rows. */
  218.             private double maxRowSum;

  219.             /** {@inheritDoc} */
  220.             @Override
  221.             public void start(final int rows, final int columns,
  222.                               final int startRow, final int endRow,
  223.                               final int startColumn, final int endColumn) {
  224.                 this.endColumn = endColumn;
  225.                 rowSum   = 0;
  226.                 maxRowSum   = 0;
  227.             }

  228.             /** {@inheritDoc} */
  229.             @Override
  230.             public void visit(final int row, final int column, final double value) {
  231.                 rowSum += FastMath.abs(value);
  232.                 if (column == endColumn) {
  233.                     maxRowSum = FastMath.max(maxRowSum, rowSum);
  234.                     rowSum = 0;
  235.                 }
  236.             }

  237.             /** {@inheritDoc} */
  238.             @Override
  239.             public double end() {
  240.                 return maxRowSum;
  241.             }
  242.         });

  243.     }

  244.     /**
  245.      * Returns the <a href="http://mathworld.wolfram.com/FrobeniusNorm.html">
  246.      * Frobenius norm</a> of the matrix.
  247.      *
  248.      * @return norm
  249.      */
  250.     double getFrobeniusNorm();

  251.     /**
  252.      * Gets a submatrix. Rows and columns are indicated
  253.      * counting from 0 to n-1.
  254.      *
  255.      * @param startRow Initial row index
  256.      * @param endRow Final row index (inclusive)
  257.      * @param startColumn Initial column index
  258.      * @param endColumn Final column index (inclusive)
  259.      * @return The subMatrix containing the data of the
  260.      * specified rows and columns.
  261.      * @throws MathIllegalArgumentException if the indices are not valid.
  262.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  263.      * {@code endColumn < startColumn}.
  264.      */
  265.     RealMatrix getSubMatrix(int startRow, int endRow, int startColumn,
  266.                             int endColumn)
  267.         throws MathIllegalArgumentException;

  268.     /**
  269.      * Gets a submatrix. Rows and columns are indicated counting from 0 to n-1.
  270.      *
  271.      * @param selectedRows Array of row indices.
  272.      * @param selectedColumns Array of column indices.
  273.      * @return The subMatrix containing the data in the specified rows and
  274.      * columns
  275.      * @throws NullArgumentException if the row or column selections are
  276.      * {@code null}
  277.      * @throws MathIllegalArgumentException if the row or column selections are empty (zero
  278.      * length).
  279.      * @throws MathIllegalArgumentException if the indices are not valid.
  280.      */
  281.     RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
  282.         throws MathIllegalArgumentException, NullArgumentException;

  283.     /**
  284.      * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
  285.      *
  286.      * @param startRow Initial row index
  287.      * @param endRow Final row index (inclusive)
  288.      * @param startColumn Initial column index
  289.      * @param endColumn Final column index (inclusive)
  290.      * @param destination The arrays where the submatrix data should be copied
  291.      * (if larger than rows/columns counts, only the upper-left part will be
  292.      * used)
  293.      * @throws MathIllegalArgumentException if the indices are not valid.
  294.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  295.      * {@code endColumn < startColumn}.
  296.      * @throws MathIllegalArgumentException if the destination array is too
  297.      * small.
  298.      */
  299.     void copySubMatrix(int startRow, int endRow, int startColumn,
  300.                        int endColumn, double[][] destination)
  301.         throws MathIllegalArgumentException;

  302.     /**
  303.      * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
  304.      *
  305.      * @param selectedRows Array of row indices.
  306.      * @param selectedColumns Array of column indices.
  307.      * @param destination The arrays where the submatrix data should be copied
  308.      * (if larger than rows/columns counts, only the upper-left part will be
  309.      * used)
  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.      * @throws MathIllegalArgumentException if the destination array is too
  316.      * small.
  317.      */
  318.     void copySubMatrix(int[] selectedRows, int[] selectedColumns,
  319.                        double[][] destination)
  320.         throws MathIllegalArgumentException, NullArgumentException;

  321.    /**
  322.     * Replace the submatrix starting at {@code row, column} using data in the
  323.     * input {@code subMatrix} array. Indexes are 0-based.
  324.     * <p>
  325.     * Example:<br>
  326.     * Starting with </p>
  327.     * <pre>
  328.     * 1  2  3  4
  329.     * 5  6  7  8
  330.     * 9  0  1  2
  331.     * </pre>
  332.     * <p>
  333.     * and {@code subMatrix = {{3, 4} {5,6}}}, invoking
  334.     * {@code setSubMatrix(subMatrix,1,1))} will result in </p>
  335.     * <pre>
  336.     * 1  2  3  4
  337.     * 5  3  4  8
  338.     * 9  5  6  2
  339.     * </pre>
  340.     *
  341.     * @param subMatrix  array containing the submatrix replacement data
  342.     * @param row  row coordinate of the top, left element to be replaced
  343.     * @param column  column coordinate of the top, left element to be replaced
  344.     * @throws MathIllegalArgumentException if {@code subMatrix} is empty.
  345.     * @throws MathIllegalArgumentException if {@code subMatrix} does not fit into
  346.     * this matrix from element in {@code (row, column)}.
  347.     * @throws MathIllegalArgumentException if {@code subMatrix} is not rectangular
  348.     * (not all rows have the same length) or empty.
  349.     * @throws NullArgumentException if {@code subMatrix} is {@code null}.
  350.     */
  351.     void setSubMatrix(double[][] subMatrix, int row, int column)
  352.         throws MathIllegalArgumentException, NullArgumentException;

  353.    /**
  354.     * Get the entries at the given row index as a row matrix.  Row indices start
  355.     * at 0.
  356.     *
  357.     * @param row Row to be fetched.
  358.     * @return row Matrix.
  359.     * @throws MathIllegalArgumentException if the specified row index is invalid.
  360.     */
  361.    RealMatrix getRowMatrix(int row) throws MathIllegalArgumentException;

  362.     /**
  363.      * Sets the specified {@code row} of {@code this} matrix to the entries of
  364.      * the specified row {@code matrix}. Row indices start at 0.
  365.      *
  366.      * @param row Row to be set.
  367.      * @param matrix Row matrix to be copied (must have one row and the same
  368.      * number of columns as the instance).
  369.      * @throws MathIllegalArgumentException if the specified row index is invalid.
  370.      * @throws MathIllegalArgumentException if the row dimension of the
  371.      * {@code matrix} is not {@code 1}, or the column dimensions of {@code this}
  372.      * and {@code matrix} do not match.
  373.      */
  374.     void setRowMatrix(int row, RealMatrix matrix)
  375.         throws MathIllegalArgumentException;

  376.     /**
  377.      * Get the entries at the given column index as a column matrix. Column
  378.      * indices start at 0.
  379.      *
  380.      * @param column Column to be fetched.
  381.      * @return column Matrix.
  382.      * @throws MathIllegalArgumentException if the specified column index is invalid.
  383.      */
  384.     RealMatrix getColumnMatrix(int column)
  385.         throws MathIllegalArgumentException;

  386.     /**
  387.      * Sets the specified {@code column} of {@code this} matrix to the entries
  388.      * of the specified column {@code matrix}. Column indices start at 0.
  389.      *
  390.      * @param column Column to be set.
  391.      * @param matrix Column matrix to be copied (must have one column and the
  392.      * same number of rows as the instance).
  393.      * @throws MathIllegalArgumentException if the specified column index is invalid.
  394.      * @throws MathIllegalArgumentException if the column dimension of the
  395.      * {@code matrix} is not {@code 1}, or the row dimensions of {@code this}
  396.      * and {@code matrix} do not match.
  397.      */
  398.     void setColumnMatrix(int column, RealMatrix matrix)
  399.         throws MathIllegalArgumentException;

  400.     /**
  401.      * Returns the entries in row number {@code row} as a vector. Row indices
  402.      * start at 0.
  403.      *
  404.      * @param row Row to be fetched.
  405.      * @return a row vector.
  406.      * @throws MathIllegalArgumentException if the specified row index is invalid.
  407.      */
  408.     RealVector getRowVector(int row)
  409.         throws MathIllegalArgumentException;

  410.     /**
  411.      * Sets the specified {@code row} of {@code this} matrix to the entries of
  412.      * the specified {@code vector}. Row indices start at 0.
  413.      *
  414.      * @param row Row to be set.
  415.      * @param vector row vector to be copied (must have the same number of
  416.      * column as the instance).
  417.      * @throws MathIllegalArgumentException if the specified row index is invalid.
  418.      * @throws MathIllegalArgumentException if the {@code vector} dimension
  419.      * does not match the column dimension of {@code this} matrix.
  420.      */
  421.     void setRowVector(int row, RealVector vector)
  422.         throws MathIllegalArgumentException;

  423.     /**
  424.      * Get the entries at the given column index as a vector. Column indices
  425.      * start at 0.
  426.      *
  427.      * @param column Column to be fetched.
  428.      * @return a column vector.
  429.      * @throws MathIllegalArgumentException if the specified column index is invalid
  430.      */
  431.     RealVector getColumnVector(int column)
  432.         throws MathIllegalArgumentException;

  433.     /**
  434.      * Sets the specified {@code column} of {@code this} matrix to the entries
  435.      * of the specified {@code vector}. Column indices start at 0.
  436.      *
  437.      * @param column Column to be set.
  438.      * @param vector column vector to be copied (must have the same number of
  439.      * rows as the instance).
  440.      * @throws MathIllegalArgumentException if the specified column index is invalid.
  441.      * @throws MathIllegalArgumentException if the {@code vector} dimension
  442.      * does not match the row dimension of {@code this} matrix.
  443.      */
  444.     void setColumnVector(int column, RealVector vector)
  445.         throws MathIllegalArgumentException;

  446.     /**
  447.      * Get the entries at the given row index. Row indices start at 0.
  448.      *
  449.      * @param row Row to be fetched.
  450.      * @return the array of entries in the row.
  451.      * @throws MathIllegalArgumentException if the specified row index is not valid.
  452.      */
  453.     double[] getRow(int row) throws MathIllegalArgumentException;

  454.     /**
  455.      * Sets the specified {@code row} of {@code this} matrix to the entries
  456.      * of the specified {@code array}. Row indices start at 0.
  457.      *
  458.      * @param row Row to be set.
  459.      * @param array Row matrix to be copied (must have the same number of
  460.      * columns as the instance)
  461.      * @throws MathIllegalArgumentException if the specified row index is invalid.
  462.      * @throws MathIllegalArgumentException if the {@code array} length does
  463.      * not match the column dimension of {@code this} matrix.
  464.      */
  465.     void setRow(int row, double[] array)
  466.         throws MathIllegalArgumentException;

  467.     /**
  468.      * Get the entries at the given column index as an array. Column indices
  469.      * start at 0.
  470.      *
  471.      * @param column Column to be fetched.
  472.      * @return the array of entries in the column.
  473.      * @throws MathIllegalArgumentException if the specified column index is not valid.
  474.      */
  475.     double[] getColumn(int column) throws MathIllegalArgumentException;

  476.     /**
  477.      * Sets the specified {@code column} of {@code this} matrix to the entries
  478.      * of the specified {@code array}. Column indices start at 0.
  479.      *
  480.      * @param column Column to be set.
  481.      * @param array Column array to be copied (must have the same number of
  482.      * rows as the instance).
  483.      * @throws MathIllegalArgumentException if the specified column index is invalid.
  484.      * @throws MathIllegalArgumentException if the {@code array} length does
  485.      * not match the row dimension of {@code this} matrix.
  486.      */
  487.     void setColumn(int column, double[] array)
  488.         throws MathIllegalArgumentException;

  489.     /**
  490.      * Get the entry in the specified row and column. Row and column indices
  491.      * start at 0.
  492.      *
  493.      * @param row Row index of entry to be fetched.
  494.      * @param column Column index of entry to be fetched.
  495.      * @return the matrix entry at {@code (row, column)}.
  496.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  497.      */
  498.     double getEntry(int row, int column) throws MathIllegalArgumentException;

  499.     /**
  500.      * Set the entry in the specified row and column. Row and column indices
  501.      * start at 0.
  502.      *
  503.      * @param row Row index of entry to be set.
  504.      * @param column Column index of entry to be set.
  505.      * @param value the new value of the entry.
  506.      * @throws MathIllegalArgumentException if the row or column index is not valid
  507.      */
  508.     void setEntry(int row, int column, double value) throws MathIllegalArgumentException;

  509.     /**
  510.      * Adds (in place) the specified value to the specified entry of
  511.      * {@code this} matrix. Row and column indices start at 0.
  512.      *
  513.      * @param row Row index of the entry to be modified.
  514.      * @param column Column index of the entry to be modified.
  515.      * @param increment value to add to the matrix entry.
  516.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  517.      */
  518.     void addToEntry(int row, int column, double increment) throws MathIllegalArgumentException;

  519.     /**
  520.      * Multiplies (in place) the specified entry of {@code this} matrix by the
  521.      * specified value. Row and column indices start at 0.
  522.      *
  523.      * @param row Row index of the entry to be modified.
  524.      * @param column Column index of the entry to be modified.
  525.      * @param factor Multiplication factor for the matrix entry.
  526.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  527.      */
  528.     void multiplyEntry(int row, int column, double factor) throws MathIllegalArgumentException;

  529.     /**
  530.      * Returns the transpose of this matrix.
  531.      *
  532.      * @return transpose matrix
  533.      */
  534.     RealMatrix transpose();

  535.     /**
  536.      * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
  537.      * trace</a> of the matrix (the sum of the elements on the main diagonal).
  538.      *
  539.      * @return the trace.
  540.      * @throws MathIllegalArgumentException if the matrix is not square.
  541.      */
  542.     double getTrace() throws MathIllegalArgumentException;

  543.     /**
  544.      * Returns the result of multiplying this by the vector {@code v}.
  545.      *
  546.      * @param v the vector to operate on
  547.      * @return {@code this * v}
  548.      * @throws MathIllegalArgumentException if the length of {@code v} does not
  549.      * match the column dimension of {@code this}.
  550.      */
  551.     double[] operate(double[] v) throws MathIllegalArgumentException;

  552.     /**
  553.      * Returns the result of multiplying this by the vector {@code v}.
  554.      *
  555.      * @param v the vector to operate on
  556.      * @return {@code this * v}
  557.      * @throws MathIllegalArgumentException if the dimension of {@code v} does not
  558.      * match the column dimension of {@code this}.
  559.      */
  560.     RealVector operate(RealVector v) throws MathIllegalArgumentException;

  561.     /**
  562.      * Returns the (row) vector result of premultiplying this by the vector {@code v}.
  563.      *
  564.      * @param v the row vector to premultiply by
  565.      * @return {@code v * this}
  566.      * @throws MathIllegalArgumentException if the length of {@code v} does not
  567.      * match the row dimension of {@code this}.
  568.      */
  569.     double[] preMultiply(double[] v) throws MathIllegalArgumentException;

  570.     /**
  571.      * Returns the (row) vector result of premultiplying this by the vector {@code v}.
  572.      *
  573.      * @param v the row vector to premultiply by
  574.      * @return {@code v * this}
  575.      * @throws MathIllegalArgumentException if the dimension of {@code v} does not
  576.      * match the row dimension of {@code this}.
  577.      */
  578.     RealVector preMultiply(RealVector v) throws MathIllegalArgumentException;

  579.     /**
  580.      * Visit (and possibly change) all matrix entries in row order.
  581.      * <p>Row order starts at upper left and iterating through all elements
  582.      * of a row from left to right before going to the leftmost element
  583.      * of the next row.</p>
  584.      * @param visitor visitor used to process all matrix entries
  585.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  586.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  587.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  588.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  589.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  590.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  591.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  592.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  593.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  594.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  595.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  596.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  597.      * of the walk
  598.      */
  599.     double walkInRowOrder(RealMatrixChangingVisitor visitor);

  600.     /**
  601.      * Visit (but don't change) all matrix entries in row order.
  602.      * <p>Row order starts at upper left and iterating through all elements
  603.      * of a row from left to right before going to the leftmost element
  604.      * of the next row.</p>
  605.      * @param visitor visitor used to process all matrix entries
  606.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  607.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  608.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  609.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  610.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  611.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  612.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  613.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  614.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  615.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  616.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  617.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  618.      * of the walk
  619.      */
  620.     double walkInRowOrder(RealMatrixPreservingVisitor visitor);

  621.     /**
  622.      * Visit (and possibly change) some matrix entries in row order.
  623.      * <p>Row order starts at upper left and iterating through all elements
  624.      * of a row from left to right before going to the leftmost element
  625.      * of the next row.</p>
  626.      * @param visitor visitor used to process all matrix entries
  627.      * @param startRow Initial row index
  628.      * @param endRow Final row index (inclusive)
  629.      * @param startColumn Initial column index
  630.      * @param endColumn Final column index
  631.      * @throws MathIllegalArgumentException if the indices are not valid.
  632.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  633.      * {@code endColumn < startColumn}.
  634.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  635.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  636.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  637.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  638.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  639.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  640.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  641.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  642.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  643.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  644.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  645.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  646.      * of the walk
  647.      */
  648.     double walkInRowOrder(RealMatrixChangingVisitor visitor, int startRow,
  649.         int endRow, int startColumn, int endColumn)
  650.         throws MathIllegalArgumentException;

  651.     /**
  652.      * Visit (but don't change) some matrix entries in row order.
  653.      * <p>Row order starts at upper left and iterating through all elements
  654.      * of a row from left to right before going to the leftmost element
  655.      * of the next row.</p>
  656.      * @param visitor visitor used to process all matrix entries
  657.      * @param startRow Initial row index
  658.      * @param endRow Final row index (inclusive)
  659.      * @param startColumn Initial column index
  660.      * @param endColumn Final column index
  661.      * @throws MathIllegalArgumentException if the indices are not valid.
  662.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  663.      * {@code endColumn < startColumn}.
  664.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  665.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  666.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  667.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  668.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  669.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  670.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  671.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  672.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  673.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  674.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  675.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  676.      * of the walk
  677.      */
  678.     double walkInRowOrder(RealMatrixPreservingVisitor visitor, int startRow,
  679.         int endRow, int startColumn, int endColumn)
  680.         throws MathIllegalArgumentException;

  681.     /**
  682.      * Visit (and possibly change) all matrix entries in column order.
  683.      * <p>Column order starts at upper left and iterating through all elements
  684.      * of a column from top to bottom before going to the topmost element
  685.      * of the next column.</p>
  686.      * @param visitor visitor used to process all matrix entries
  687.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  688.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  689.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  690.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  691.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  692.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  693.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  694.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  695.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  696.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  697.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  698.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  699.      * of the walk
  700.      */
  701.     double walkInColumnOrder(RealMatrixChangingVisitor visitor);

  702.     /**
  703.      * Visit (but don't change) all matrix entries in column order.
  704.      * <p>Column order starts at upper left and iterating through all elements
  705.      * of a column from top to bottom before going to the topmost element
  706.      * of the next column.</p>
  707.      * @param visitor visitor used to process all matrix entries
  708.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  709.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  710.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  711.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  712.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  713.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  714.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  715.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  716.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  717.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  718.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  719.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  720.      * of the walk
  721.      */
  722.     double walkInColumnOrder(RealMatrixPreservingVisitor visitor);

  723.     /**
  724.      * Visit (and possibly change) some matrix entries in column order.
  725.      * <p>Column order starts at upper left and iterating through all elements
  726.      * of a column from top to bottom before going to the topmost element
  727.      * of the next column.</p>
  728.      * @param visitor visitor used to process all matrix entries
  729.      * @param startRow Initial row index
  730.      * @param endRow Final row index (inclusive)
  731.      * @param startColumn Initial column index
  732.      * @param endColumn Final column index
  733.      * @throws MathIllegalArgumentException if the indices are not valid.
  734.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  735.      * {@code endColumn < startColumn}.
  736.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  737.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  738.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  739.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  740.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  741.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  742.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  743.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  744.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  745.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  746.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  747.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  748.      * of the walk
  749.      */
  750.     double walkInColumnOrder(RealMatrixChangingVisitor visitor, int startRow,
  751.         int endRow, int startColumn, int endColumn)
  752.         throws MathIllegalArgumentException;

  753.     /**
  754.      * Visit (but don't change) some matrix entries in column order.
  755.      * <p>Column order starts at upper left and iterating through all elements
  756.      * of a column from top to bottom before going to the topmost element
  757.      * of the next column.</p>
  758.      * @param visitor visitor used to process all matrix entries
  759.      * @param startRow Initial row index
  760.      * @param endRow Final row index (inclusive)
  761.      * @param startColumn Initial column index
  762.      * @param endColumn Final column index
  763.      * @throws MathIllegalArgumentException if the indices are not valid.
  764.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  765.      * {@code endColumn < startColumn}.
  766.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  767.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  768.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  769.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  770.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  771.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  772.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  773.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  774.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  775.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  776.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  777.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  778.      * of the walk
  779.      */
  780.     double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow,
  781.         int endRow, int startColumn, int endColumn)
  782.         throws MathIllegalArgumentException;

  783.     /**
  784.      * Visit (and possibly change) all matrix entries using the fastest possible order.
  785.      * <p>The fastest walking order depends on the exact matrix class. It may be
  786.      * different from traditional row or column orders.</p>
  787.      * @param visitor visitor used to process all matrix entries
  788.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  789.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  790.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  791.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  792.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  793.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  794.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  795.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  796.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  797.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  798.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  799.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  800.      * of the walk
  801.      */
  802.     double walkInOptimizedOrder(RealMatrixChangingVisitor visitor);

  803.     /**
  804.      * Visit (but don't change) all matrix entries using the fastest possible order.
  805.      * <p>The fastest walking order depends on the exact matrix class. It may be
  806.      * different from traditional row or column orders.</p>
  807.      * @param visitor visitor used to process all matrix entries
  808.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  809.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  810.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  811.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  812.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  813.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  814.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  815.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  816.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  817.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  818.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  819.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  820.      * of the walk
  821.      */
  822.     double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor);

  823.     /**
  824.      * Visit (and possibly change) some matrix entries using the fastest possible order.
  825.      * <p>The fastest walking order depends on the exact matrix class. It may be
  826.      * different from traditional row or column orders.</p>
  827.      * @param visitor visitor used to process all matrix entries
  828.      * @param startRow Initial row index
  829.      * @param endRow Final row index (inclusive)
  830.      * @param startColumn Initial column index
  831.      * @param endColumn Final column index (inclusive)
  832.      * @throws MathIllegalArgumentException if the indices are not valid.
  833.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  834.      * {@code endColumn < startColumn}.
  835.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  836.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  837.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  838.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  839.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  840.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  841.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  842.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  843.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  844.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  845.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
  846.      * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
  847.      * of the walk
  848.      */
  849.     double walkInOptimizedOrder(RealMatrixChangingVisitor visitor,
  850.         int startRow, int endRow, int startColumn, int endColumn)
  851.         throws MathIllegalArgumentException;

  852.     /**
  853.      * Visit (but don't change) some 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.      * @param startRow Initial row index
  858.      * @param endRow Final row index (inclusive)
  859.      * @param startColumn Initial column index
  860.      * @param endColumn Final column index (inclusive)
  861.      * @throws MathIllegalArgumentException if the indices are not valid.
  862.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  863.      * {@code endColumn < startColumn}.
  864.      * @see #walkInRowOrder(RealMatrixChangingVisitor)
  865.      * @see #walkInRowOrder(RealMatrixPreservingVisitor)
  866.      * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
  867.      * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
  868.      * @see #walkInColumnOrder(RealMatrixChangingVisitor)
  869.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
  870.      * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
  871.      * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
  872.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
  873.      * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
  874.      * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
  875.      * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
  876.      * of the walk
  877.      */
  878.     double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor,
  879.         int startRow, int endRow, int startColumn, int endColumn)
  880.         throws MathIllegalArgumentException;

  881.     /**
  882.      * Acts as if implemented as:
  883.      * <pre>
  884.      *  return copy().mapToSelf(function);
  885.      * </pre>
  886.      * Returns a new matrix. Does not change instance data.
  887.      *
  888.      * @param function Function to apply to each entry.
  889.      * @return a new matrix.
  890.      * @since 1.7
  891.      */
  892.     default RealMatrix map(UnivariateFunction function) {
  893.         return copy().mapToSelf(function);
  894.     }

  895.     /**
  896.      * Replace each entry by the result of applying the function to it.
  897.      *
  898.      * @param function Function to apply to each entry.
  899.      * @return a reference to this matrix.
  900.      * @since 1.7
  901.      */
  902.     default RealMatrix mapToSelf(final UnivariateFunction function) {
  903.         walkInOptimizedOrder(new RealMatrixChangingVisitor() {

  904.             /** {@inheritDoc} */
  905.             @Override
  906.             public double visit(int row, int column, double value) {
  907.                 // apply the function to the current entry
  908.                 return function.value(value);
  909.             }

  910.             /** {@inheritDoc} */
  911.             @Override
  912.             public void start(int rows, int columns, int startRow, int endRow,
  913.                               int startColumn, int endColumn) {
  914.             }

  915.             /** {@inheritDoc} */
  916.             @Override
  917.             public double end() {
  918.                 return 0;
  919.             }

  920.         });

  921.         return this;

  922.     }

  923. }