FieldMatrix.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 java.util.function.Function;

  23. import org.hipparchus.Field;
  24. import org.hipparchus.FieldElement;
  25. import org.hipparchus.analysis.polynomials.SmoothStepFactory;
  26. import org.hipparchus.exception.MathIllegalArgumentException;
  27. import org.hipparchus.exception.NullArgumentException;
  28. import org.hipparchus.util.FieldBlendable;

  29. /**
  30.  * Interface defining field-valued matrix with basic algebraic operations.
  31.  * <p>
  32.  * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
  33.  * returns the element in the first row, first column of the matrix.</p>
  34.  *
  35.  * @param <T> the type of the field elements
  36.  */
  37. public interface FieldMatrix<T extends FieldElement<T>> extends AnyMatrix, FieldBlendable<FieldMatrix<T>, T> {
  38.     /**
  39.      * Get the type of field elements of the matrix.
  40.      *
  41.      * @return the type of field elements of the matrix.
  42.      */
  43.     Field<T> getField();

  44.     /**
  45.      * Create a new {@link FieldMatrix} of the same type as the instance with
  46.      * the supplied row and column dimensions.
  47.      *
  48.      * @param rowDimension  the number of rows in the new matrix
  49.      * @param columnDimension  the number of columns in the new matrix
  50.      * @return a new matrix of the same type as the instance
  51.      * @throws MathIllegalArgumentException if row or column dimension is not
  52.      * positive.
  53.      */
  54.     FieldMatrix<T> createMatrix(int rowDimension, int columnDimension)
  55.     throws MathIllegalArgumentException;

  56.     /**
  57.      * Make a (deep) copy of this.
  58.      *
  59.      * @return a copy of this matrix.
  60.      */
  61.     FieldMatrix<T> copy();

  62.     /**
  63.      * Compute the sum of this and m.
  64.      *
  65.      * @param m Matrix to be added.
  66.      * @return {@code this} + {@code m}.
  67.      * @throws MathIllegalArgumentException if {@code m} is not the same
  68.      * size as {@code this} matrix.
  69.      */
  70.     FieldMatrix<T> add(FieldMatrix<T> m) throws MathIllegalArgumentException;

  71.     /**
  72.      * Subtract {@code m} from this matrix.
  73.      *
  74.      * @param m Matrix to be subtracted.
  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> subtract(FieldMatrix<T> m) throws MathIllegalArgumentException;

  80.      /**
  81.      * Increment each entry of this matrix.
  82.      *
  83.      * @param d Value to be added to each entry.
  84.      * @return {@code d} + {@code this}.
  85.      */
  86.     FieldMatrix<T> scalarAdd(T d);

  87.     /**
  88.      * Multiply each entry by {@code d}.
  89.      *
  90.      * @param d Value to multiply all entries by.
  91.      * @return {@code d} * {@code this}.
  92.      */
  93.     FieldMatrix<T> scalarMultiply(T d);

  94.     /**
  95.      * Postmultiply this matrix by {@code m}.
  96.      *
  97.      * @param m  Matrix to postmultiply by.
  98.      * @return {@code this} * {@code m}.
  99.      * @throws MathIllegalArgumentException if the number of columns of
  100.      * {@code this} matrix is not equal to the number of rows of matrix
  101.      * {@code m}.
  102.      */
  103.     FieldMatrix<T> multiply(FieldMatrix<T> m) throws MathIllegalArgumentException;

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

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

  136.     /**
  137.      * Premultiply this matrix by {@code m}.
  138.      *
  139.      * @param m Matrix to premultiply by.
  140.      * @return {@code m} * {@code this}.
  141.      * @throws MathIllegalArgumentException if the number of columns of {@code m}
  142.      * differs from the number of rows of {@code this} matrix.
  143.      */
  144.     FieldMatrix<T> preMultiply(FieldMatrix<T> m) throws MathIllegalArgumentException;

  145.     /**
  146.      * Returns the result multiplying this with itself <code>p</code> times.
  147.      * Depending on the type of the field elements, T, instability for high
  148.      * powers might occur.
  149.      *
  150.      * @param p raise this to power p
  151.      * @return this^p
  152.      * @throws MathIllegalArgumentException if {@code p < 0}
  153.      * @throws MathIllegalArgumentException if {@code this matrix} is not square
  154.      */
  155.     FieldMatrix<T> power(int p) throws MathIllegalArgumentException;

  156.     /** {@inheritDoc} */
  157.     @Override
  158.     default FieldMatrix<T> blendArithmeticallyWith(final FieldMatrix<T> other, final T blendingValue) {
  159.         SmoothStepFactory.checkBetweenZeroAndOneIncluded(blendingValue.getReal());
  160.         return this.scalarMultiply(getField().getOne().subtract(blendingValue))
  161.                    .add(other.scalarMultiply(blendingValue));
  162.     }

  163.     /**
  164.      * Returns matrix entries as a two-dimensional array.
  165.      *
  166.      * @return a 2-dimensional array of entries.
  167.      */
  168.     T[][] getData();

  169.     /**
  170.      * Get a submatrix. Rows and columns are indicated
  171.      * counting from 0 to n - 1.
  172.      *
  173.      * @param startRow Initial row index
  174.      * @param endRow Final row index (inclusive)
  175.      * @param startColumn Initial column index
  176.      * @param endColumn Final column index (inclusive)
  177.      * @return the matrix containing the data of the specified rows and columns.
  178.      * @throws MathIllegalArgumentException is {@code endRow < startRow} of
  179.      * {@code endColumn < startColumn}.
  180.      * @throws MathIllegalArgumentException if the indices are not valid.
  181.      */
  182.    FieldMatrix<T> getSubMatrix(int startRow, int endRow, int startColumn, int endColumn)
  183.    throws MathIllegalArgumentException;

  184.    /**
  185.     * Get a submatrix. Rows and columns are indicated
  186.     * counting from 0 to n - 1.
  187.     *
  188.     * @param selectedRows Array of row indices.
  189.     * @param selectedColumns Array of column indices.
  190.     * @return the matrix containing the data in the
  191.     * specified rows and columns.
  192.     * @throws MathIllegalArgumentException if {@code selectedRows} or
  193.     * {@code selectedColumns} is empty
  194.     * @throws NullArgumentException if {@code selectedRows} or
  195.     * {@code selectedColumns} is {@code null}.
  196.     * @throws MathIllegalArgumentException if row or column selections are not valid.
  197.     */
  198.    FieldMatrix<T> getSubMatrix(int[] selectedRows, int[] selectedColumns)
  199.    throws MathIllegalArgumentException, NullArgumentException;

  200.    /**
  201.     * Copy a submatrix. Rows and columns are 0-based. The designated submatrix
  202.     * is copied into the top left portion of the destination array.
  203.     *
  204.     * @param startRow Initial row index.
  205.     * @param endRow Final row index (inclusive).
  206.     * @param startColumn Initial column index.
  207.     * @param endColumn Final column index (inclusive).
  208.     * @param destination The array where the submatrix data should be copied
  209.     * (if larger than rows/columns counts, only the upper-left part will be modified).
  210.     * @throws MathIllegalArgumentException if the dimensions of
  211.     * {@code destination} are not large enough to hold the submatrix.
  212.     * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  213.     * {@code endColumn < startColumn}.
  214.     * @throws MathIllegalArgumentException if the indices are not valid.
  215.     */
  216.     void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
  217.                        T[][] destination)
  218.     throws MathIllegalArgumentException;

  219.   /**
  220.    * Copy a submatrix. Rows and columns are indicated
  221.    * counting from 0 to n - 1.
  222.    *
  223.    * @param selectedRows Array of row indices.
  224.    * @param selectedColumns Array of column indices.
  225.    * @param destination Arrays where the submatrix data should be copied
  226.    * (if larger than rows/columns counts, only the upper-left part will be used)
  227.    * @throws MathIllegalArgumentException if the dimensions of
  228.    * {@code destination} do not match those of {@code this}.
  229.    * @throws MathIllegalArgumentException if {@code selectedRows} or
  230.    * {@code selectedColumns} is empty
  231.    * @throws NullArgumentException if {@code selectedRows} or
  232.    * {@code selectedColumns} is {@code null}.
  233.    * @throws MathIllegalArgumentException if the indices are not valid.
  234.    */
  235.   void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
  236.   throws MathIllegalArgumentException, NullArgumentException;

  237.     /**
  238.      * Replace the submatrix starting at {@code (row, column)} using data in the
  239.      * input {@code subMatrix} array. Indexes are 0-based.
  240.      * <p>
  241.      * Example:<br>
  242.      * Starting with
  243.      * </p>
  244.      *
  245.      * <pre>
  246.      * 1  2  3  4
  247.      * 5  6  7  8
  248.      * 9  0  1  2
  249.      * </pre>
  250.      *
  251.      * <p>and {@code subMatrix = {{3, 4} {5,6}}}, invoking
  252.      * {@code setSubMatrix(subMatrix,1,1))} will result in</p>
  253.      *
  254.      * <pre>
  255.      * 1  2  3  4
  256.      * 5  3  4  8
  257.      * 9  5  6  2
  258.      * </pre>
  259.      *
  260.      * @param subMatrix Array containing the submatrix replacement data.
  261.      * @param row Row coordinate of the top-left element to be replaced.
  262.      * @param column Column coordinate of the top-left element to be replaced.
  263.      * @throws MathIllegalArgumentException if {@code subMatrix} does not fit into this
  264.      * matrix from element in {@code (row, column)}.
  265.      * @throws MathIllegalArgumentException if a row or column of {@code subMatrix} is empty.
  266.      * @throws MathIllegalArgumentException if {@code subMatrix} is not
  267.      * rectangular (not all rows have the same length).
  268.      * @throws NullArgumentException if {@code subMatrix} is {@code null}.
  269.      */
  270.     void setSubMatrix(T[][] subMatrix, int row, int column)
  271.         throws MathIllegalArgumentException, NullArgumentException;

  272.    /**
  273.     * Get the entries in row number {@code row}
  274.     * as a row matrix.
  275.     *
  276.     * @param row Row to be fetched.
  277.     * @return a row matrix.
  278.     * @throws MathIllegalArgumentException if the specified row index is invalid.
  279.     */
  280.    FieldMatrix<T> getRowMatrix(int row) throws MathIllegalArgumentException;

  281.    /**
  282.     * Set the entries in row number {@code row}
  283.     * as a row matrix.
  284.     *
  285.     * @param row Row to be set.
  286.     * @param matrix Row matrix (must have one row and the same number
  287.     * of columns as the instance).
  288.     * @throws MathIllegalArgumentException if the specified row index is invalid.
  289.     * @throws MathIllegalArgumentException
  290.     * if the matrix dimensions do not match one instance row.
  291.     */
  292.    void setRowMatrix(int row, FieldMatrix<T> matrix)
  293.    throws MathIllegalArgumentException;

  294.    /**
  295.     * Get the entries in column number {@code column}
  296.     * as a column matrix.
  297.     *
  298.     * @param column Column to be fetched.
  299.     * @return a column matrix.
  300.     * @throws MathIllegalArgumentException if the specified column index is invalid.
  301.     */
  302.    FieldMatrix<T> getColumnMatrix(int column) throws MathIllegalArgumentException;

  303.    /**
  304.     * Set the entries in column number {@code column}
  305.     * as a column matrix.
  306.     *
  307.     * @param column Column to be set.
  308.     * @param matrix column matrix (must have one column and the same
  309.     * number of rows as the instance).
  310.     * @throws MathIllegalArgumentException if the specified column index is invalid.
  311.     * @throws MathIllegalArgumentException if the matrix dimensions do
  312.     * not match one instance column.
  313.     */
  314.    void setColumnMatrix(int column, FieldMatrix<T> matrix)
  315.    throws MathIllegalArgumentException;

  316.    /**
  317.     * Get the entries in row number {@code row}
  318.     * as a vector.
  319.     *
  320.     * @param row Row to be fetched
  321.     * @return a row vector.
  322.     * @throws MathIllegalArgumentException if the specified row index is invalid.
  323.     */
  324.    FieldVector<T> getRowVector(int row) throws MathIllegalArgumentException;

  325.    /**
  326.     * Set the entries in row number {@code row}
  327.     * as a vector.
  328.     *
  329.     * @param row Row to be set.
  330.     * @param vector row vector (must have the same number of columns
  331.     * as the instance).
  332.     * @throws MathIllegalArgumentException if the specified row index is invalid.
  333.     * @throws MathIllegalArgumentException if the vector dimension does not
  334.     * match one instance row.
  335.     */
  336.    void setRowVector(int row, FieldVector<T> vector)
  337.    throws MathIllegalArgumentException;

  338.    /**
  339.     * Returns the entries in column number {@code column}
  340.     * as a vector.
  341.     *
  342.     * @param column Column to be fetched.
  343.     * @return a column vector.
  344.     * @throws MathIllegalArgumentException if the specified column index is invalid.
  345.     */
  346.    FieldVector<T> getColumnVector(int column) throws MathIllegalArgumentException;

  347.    /**
  348.     * Set the entries in column number {@code column}
  349.     * as a vector.
  350.     *
  351.     * @param column Column to be set.
  352.     * @param vector Column vector (must have the same number of rows
  353.     * as the instance).
  354.     * @throws MathIllegalArgumentException if the specified column index is invalid.
  355.     * @throws MathIllegalArgumentException if the vector dimension does not
  356.     * match one instance column.
  357.     */
  358.    void setColumnVector(int column, FieldVector<T> vector)
  359.    throws MathIllegalArgumentException;

  360.     /**
  361.      * Get the entries in row number {@code row} as an array.
  362.      *
  363.      * @param row Row to be fetched.
  364.      * @return array of entries in the row.
  365.      * @throws MathIllegalArgumentException if the specified row index is not valid.
  366.      */
  367.     T[] getRow(int row) throws MathIllegalArgumentException;

  368.     /**
  369.      * Set the entries in row number {@code row}
  370.      * as a row matrix.
  371.      *
  372.      * @param row Row to be set.
  373.      * @param array Row matrix (must have the same number of columns as
  374.      * the instance).
  375.      * @throws MathIllegalArgumentException if the specified row index is invalid.
  376.      * @throws MathIllegalArgumentException if the array size does not match
  377.      * one instance row.
  378.      */
  379.     void setRow(int row, T[] array) throws MathIllegalArgumentException;

  380.     /**
  381.      * Get the entries in column number {@code col} as an array.
  382.      *
  383.      * @param column the column to be fetched
  384.      * @return array of entries in the column
  385.      * @throws MathIllegalArgumentException if the specified column index is not valid.
  386.      */
  387.     T[] getColumn(int column) throws MathIllegalArgumentException;

  388.     /**
  389.      * Set the entries in column number {@code column}
  390.      * as a column matrix.
  391.      *
  392.      * @param column the column to be set
  393.      * @param array column array (must have the same number of rows as the instance)
  394.      * @throws MathIllegalArgumentException if the specified column index is invalid.
  395.      * @throws MathIllegalArgumentException if the array size does not match
  396.      * one instance column.
  397.      */
  398.     void setColumn(int column, T[] array) throws MathIllegalArgumentException;

  399.     /**
  400.      * Returns the entry in the specified row and column.
  401.      *
  402.      * @param row  row location of entry to be fetched
  403.      * @param column  column location of entry to be fetched
  404.      * @return matrix entry in row,column
  405.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  406.      */
  407.     T getEntry(int row, int column) throws MathIllegalArgumentException;

  408.     /**
  409.      * Set the entry in the specified row and column.
  410.      *
  411.      * @param row  row location of entry to be set
  412.      * @param column  column location of entry to be set
  413.      * @param value matrix entry to be set in row,column
  414.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  415.      */
  416.     void setEntry(int row, int column, T value) throws MathIllegalArgumentException;

  417.     /**
  418.      * Change an entry in the specified row and column.
  419.      *
  420.      * @param row Row location of entry to be set.
  421.      * @param column Column location of entry to be set.
  422.      * @param increment Value to add to the current matrix entry in
  423.      * {@code (row, column)}.
  424.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  425.      */
  426.     void addToEntry(int row, int column, T increment) throws MathIllegalArgumentException;

  427.     /**
  428.      * Change an entry in the specified row and column.
  429.      *
  430.      * @param row Row location of entry to be set.
  431.      * @param column Column location of entry to be set.
  432.      * @param factor Multiplication factor for the current matrix entry
  433.      * in {@code (row,column)}
  434.      * @throws MathIllegalArgumentException if the row or column index is not valid.
  435.      */
  436.     void multiplyEntry(int row, int column, T factor) throws MathIllegalArgumentException;

  437.     /**
  438.      * Returns the transpose of this matrix.
  439.      *
  440.      * @return transpose matrix
  441.      */
  442.     FieldMatrix<T> transpose();

  443.     /**
  444.      * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
  445.      * trace</a> of the matrix (the sum of the elements on the main diagonal).
  446.      *
  447.      * @return trace
  448.      * @throws MathIllegalArgumentException if the matrix is not square.
  449.      */
  450.     T getTrace() throws MathIllegalArgumentException;

  451.     /**
  452.      * Returns the result of multiplying this by the vector {@code v}.
  453.      *
  454.      * @param v the vector to operate on
  455.      * @return {@code this * v}
  456.      * @throws MathIllegalArgumentException if the number of columns of
  457.      * {@code this} matrix is not equal to the size of the vector {@code v}.
  458.      */
  459.     T[] operate(T[] v) throws MathIllegalArgumentException;

  460.     /**
  461.      * Returns the result of multiplying this by the vector {@code v}.
  462.      *
  463.      * @param v the vector to operate on
  464.      * @return {@code this * v}
  465.      * @throws MathIllegalArgumentException if the number of columns of
  466.      * {@code this} matrix is not equal to the size of the vector {@code v}.
  467.      */
  468.     FieldVector<T> operate(FieldVector<T> v) throws MathIllegalArgumentException;

  469.     /**
  470.      * Returns the (row) vector result of premultiplying this by the vector
  471.      * {@code v}.
  472.      *
  473.      * @param v the row vector to premultiply by
  474.      * @return {@code v * this}
  475.      * @throws MathIllegalArgumentException if the number of rows of {@code this}
  476.      * matrix is not equal to the size of the vector {@code v}
  477.      */
  478.     T[] preMultiply(T[] v) throws MathIllegalArgumentException;

  479.     /**
  480.      * Returns the (row) vector result of premultiplying this by the vector
  481.      * {@code v}.
  482.      *
  483.      * @param v the row vector to premultiply by
  484.      * @return {@code v * this}
  485.      * @throws MathIllegalArgumentException if the number of rows of {@code this}
  486.      * matrix is not equal to the size of the vector {@code v}
  487.      */
  488.     FieldVector<T> preMultiply(FieldVector<T> v) throws MathIllegalArgumentException;

  489.     /**
  490.      * Visit (and possibly change) all matrix entries in row order.
  491.      * <p>Row order starts at upper left and iterating through all elements
  492.      * of a row from left to right before going to the leftmost element
  493.      * of the next row.</p>
  494.      * @param visitor visitor used to process all matrix entries
  495.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  496.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  497.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  498.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  499.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  500.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  501.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  502.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  503.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  504.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  505.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  506.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  507.      * of the walk
  508.      */
  509.     T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor);

  510.     /**
  511.      * Visit (but don't change) all matrix entries in row order.
  512.      * <p>Row order starts at upper left and iterating through all elements
  513.      * of a row from left to right before going to the leftmost element
  514.      * of the next row.</p>
  515.      * @param visitor visitor used to process all matrix entries
  516.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  517.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  518.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  519.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  520.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  521.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  522.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  523.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  524.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  525.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  526.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  527.      * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
  528.      * of the walk
  529.      */
  530.     T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor);

  531.     /**
  532.      * Visit (and possibly change) some matrix entries in row order.
  533.      * <p>Row order starts at upper left and iterating through all elements
  534.      * of a row from left to right before going to the leftmost element
  535.      * of the next row.</p>
  536.      * @param visitor visitor used to process all matrix entries
  537.      * @param startRow Initial row index
  538.      * @param endRow Final row index (inclusive)
  539.      * @param startColumn Initial column index
  540.      * @param endColumn Final column index
  541.      * @throws MathIllegalArgumentException if the indices are not valid.
  542.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  543.      * {@code endColumn < startColumn}.
  544.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  545.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  546.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  547.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  548.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  549.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  550.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  551.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  552.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  553.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  554.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  555.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  556.      * of the walk
  557.      */
  558.     T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor,
  559.                      int startRow, int endRow, int startColumn, int endColumn)
  560.     throws MathIllegalArgumentException;

  561.     /**
  562.      * Visit (but don't change) some matrix entries in row order.
  563.      * <p>Row order starts at upper left and iterating through all elements
  564.      * of a row from left to right before going to the leftmost element
  565.      * of the next row.</p>
  566.      * @param visitor visitor used to process all matrix entries
  567.      * @param startRow Initial row index
  568.      * @param endRow Final row index (inclusive)
  569.      * @param startColumn Initial column index
  570.      * @param endColumn Final column index
  571.      * @throws MathIllegalArgumentException if the indices are not valid.
  572.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  573.      * {@code endColumn < startColumn}.
  574.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  575.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  576.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  577.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  578.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  579.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  580.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  581.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  582.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  583.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  584.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  585.      * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
  586.      * of the walk
  587.      */
  588.     T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor,
  589.                      int startRow, int endRow, int startColumn, int endColumn)
  590.     throws MathIllegalArgumentException;

  591.     /**
  592.      * Visit (and possibly change) all matrix entries in column order.
  593.      * <p>Column order starts at upper left and iterating through all elements
  594.      * of a column from top to bottom before going to the topmost element
  595.      * of the next column.</p>
  596.      * @param visitor visitor used to process all matrix entries
  597.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  598.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  599.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  600.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  601.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  602.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  603.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  604.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  605.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  606.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  607.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  608.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  609.      * of the walk
  610.      */
  611.     T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor);

  612.     /**
  613.      * Visit (but don't change) all matrix entries in column order.
  614.      * <p>Column order starts at upper left and iterating through all elements
  615.      * of a column from top to bottom before going to the topmost element
  616.      * of the next column.</p>
  617.      * @param visitor visitor used to process all matrix entries
  618.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  619.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  620.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  621.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  622.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  623.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  624.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  625.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  626.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  627.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  628.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  629.      * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
  630.      * of the walk
  631.      */
  632.     T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor);

  633.     /**
  634.      * Visit (and possibly change) some matrix entries in column order.
  635.      * <p>Column order starts at upper left and iterating through all elements
  636.      * of a column from top to bottom before going to the topmost element
  637.      * of the next column.</p>
  638.      * @param visitor visitor used to process all matrix entries
  639.      * @param startRow Initial row index
  640.      * @param endRow Final row index (inclusive)
  641.      * @param startColumn Initial column index
  642.      * @param endColumn Final column index
  643.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  644.      * {@code endColumn < startColumn}.
  645.      * @throws MathIllegalArgumentException if the indices are not valid.
  646.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  647.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  648.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  649.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  650.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  651.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  652.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  653.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  654.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  655.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  656.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  657.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  658.      * of the walk
  659.      */
  660.     T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor,
  661.                         int startRow, int endRow, int startColumn, int endColumn)
  662.     throws MathIllegalArgumentException;

  663.     /**
  664.      * Visit (but don't change) some matrix entries in column order.
  665.      * <p>Column order starts at upper left and iterating through all elements
  666.      * of a column from top to bottom before going to the topmost element
  667.      * of the next column.</p>
  668.      * @param visitor visitor used to process all matrix entries
  669.      * @param startRow Initial row index
  670.      * @param endRow Final row index (inclusive)
  671.      * @param startColumn Initial column index
  672.      * @param endColumn Final column index
  673.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  674.      * {@code endColumn < startColumn}.
  675.      * @throws MathIllegalArgumentException if the indices are not valid.
  676.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  677.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  678.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  679.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  680.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  681.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  682.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  683.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  684.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  685.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  686.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  687.      * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
  688.      * of the walk
  689.      */
  690.     T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor,
  691.                         int startRow, int endRow, int startColumn, int endColumn)
  692.     throws MathIllegalArgumentException;

  693.     /**
  694.      * Visit (and possibly change) all matrix entries using the fastest possible order.
  695.      * <p>The fastest walking order depends on the exact matrix class. It may be
  696.      * different from traditional row or column orders.</p>
  697.      * @param visitor visitor used to process all matrix entries
  698.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  699.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  700.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  701.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  702.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  703.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  704.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  705.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  706.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  707.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  708.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  709.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  710.      * of the walk
  711.      */
  712.     T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor);

  713.     /**
  714.      * Visit (but don't change) all matrix entries using the fastest possible order.
  715.      * <p>The fastest walking order depends on the exact matrix class. It may be
  716.      * different from traditional row or column orders.</p>
  717.      * @param visitor visitor used to process all matrix entries
  718.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  719.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  720.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  721.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  722.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  723.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  724.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  725.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  726.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  727.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
  728.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  729.      * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
  730.      * of the walk
  731.      */
  732.     T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor);

  733.     /**
  734.      * Visit (and possibly change) some matrix entries using the fastest possible order.
  735.      * <p>The fastest walking order depends on the exact matrix class. It may be
  736.      * different from traditional row or column orders.</p>
  737.      * @param visitor visitor used to process all matrix entries
  738.      * @param startRow Initial row index
  739.      * @param endRow Final row index (inclusive)
  740.      * @param startColumn Initial column index
  741.      * @param endColumn Final column index (inclusive)
  742.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  743.      * {@code endColumn < startColumn}.
  744.      * @throws MathIllegalArgumentException if the indices are not valid.
  745.      * @see #walkInRowOrder(FieldMatrixChangingVisitor)
  746.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
  747.      * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
  748.      * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  749.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
  750.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
  751.      * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
  752.      * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  753.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
  754.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
  755.      * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
  756.      * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
  757.      * of the walk
  758.      */
  759.     T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor,
  760.                            int startRow, int endRow, int startColumn, int endColumn)
  761.     throws MathIllegalArgumentException;

  762.     /**
  763.      * Visit (but don't change) some matrix entries using the fastest possible order.
  764.      * <p>The fastest walking order depends on the exact matrix class. It may be
  765.      * different from traditional row or column orders.</p>
  766.      * @param visitor visitor used to process all matrix entries
  767.      * @param startRow Initial row index
  768.      * @param endRow Final row index (inclusive)
  769.      * @param startColumn Initial column index
  770.      * @param endColumn Final column index (inclusive)
  771.      * @throws MathIllegalArgumentException if {@code endRow < startRow} or
  772.      * {@code endColumn < startColumn}.
  773.      * @throws MathIllegalArgumentException if the indices are not valid.
  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(FieldMatrixPreservingVisitor)
  784.      * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, 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.                            int startRow, int endRow, int startColumn, int endColumn)
  790.     throws MathIllegalArgumentException;

  791.     /**
  792.      * Acts as if implemented as:
  793.      * <pre>
  794.      *  return copy().mapToSelf(function);
  795.      * </pre>
  796.      * Returns a new matrix. Does not change instance data.
  797.      *
  798.      * @param function Function to apply to each entry.
  799.      * @return a new matrix.
  800.      * @since 1.7
  801.      */
  802.     default FieldMatrix<T> map(Function<T, T> function) {
  803.         return copy().mapToSelf(function);
  804.     }

  805.     /**
  806.      * Replace each entry by the result of applying the function to it.
  807.      *
  808.      * @param function Function to apply to each entry.
  809.      * @return a reference to this matrix.
  810.      * @since 1.7
  811.      */
  812.     default FieldMatrix<T> mapToSelf(final Function<T,T> function) {
  813.         walkInOptimizedOrder(new FieldMatrixChangingVisitor<T>() {

  814.             /** {@inheritDoc} */
  815.             @Override
  816.             public T visit(int row, int column, T value) {
  817.                 // apply the function to the current entry
  818.                 return function.apply(value);
  819.             }

  820.             /** {@inheritDoc} */
  821.             @Override
  822.             public void start(int rows, int columns, int startRow, int endRow,
  823.                               int startColumn, int endColumn) {
  824.             }

  825.             /** {@inheritDoc} */
  826.             @Override
  827.             public T end() {
  828.                 return getField().getZero();
  829.             }

  830.         });

  831.         return this;

  832.     }

  833. }