001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.math4.legacy.linear;
019
020import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
021import org.apache.commons.math4.legacy.exception.NoDataException;
022import org.apache.commons.math4.legacy.exception.NotPositiveException;
023import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
024import org.apache.commons.math4.legacy.exception.NullArgumentException;
025import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
026import org.apache.commons.math4.legacy.exception.OutOfRangeException;
027
028/**
029 * Interface defining a real-valued matrix with basic algebraic operations.
030 * <p>
031 * Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
032 * returns the element in the first row, first column of the matrix.</p>
033 *
034 */
035public interface RealMatrix extends AnyMatrix {
036
037    /**
038     * Create a new RealMatrix of the same type as the instance with the
039     * supplied
040     * row and column dimensions.
041     *
042     * @param rowDimension the number of rows in the new matrix
043     * @param columnDimension the number of columns in the new matrix
044     * @return a new matrix of the same type as the instance
045     * @throws NotStrictlyPositiveException if row or column dimension is not
046     * positive.
047     * @since 2.0
048     */
049    RealMatrix createMatrix(int rowDimension, int columnDimension)
050        throws NotStrictlyPositiveException;
051
052    /**
053     * Returns a (deep) copy of this.
054     *
055     * @return matrix copy
056     */
057    RealMatrix copy();
058
059    /**
060     * Returns the sum of {@code this} and {@code m}.
061     *
062     * @param m matrix to be added
063     * @return {@code this + m}
064     * @throws MatrixDimensionMismatchException if {@code m} is not the same
065     * size as {@code this}.
066     */
067    RealMatrix add(RealMatrix m)
068        throws MatrixDimensionMismatchException;
069
070    /**
071     * Returns {@code this} minus {@code m}.
072     *
073     * @param m matrix to be subtracted
074     * @return {@code this - m}
075     * @throws MatrixDimensionMismatchException if {@code m} is not the same
076     * size as {@code this}.
077     */
078    RealMatrix subtract(RealMatrix m)
079        throws MatrixDimensionMismatchException;
080
081    /**
082     * Returns the result of adding {@code d} to each entry of {@code this}.
083     *
084     * @param d value to be added to each entry
085     * @return {@code d + this}
086     */
087    RealMatrix scalarAdd(double d);
088
089    /**
090     * Returns the result of multiplying each entry of {@code this} by
091     * {@code d}.
092     *
093     * @param d value to multiply all entries by
094     * @return {@code d * this}
095     */
096    RealMatrix scalarMultiply(double d);
097
098    /**
099     * Returns the result of postmultiplying {@code this} by {@code m}.
100     *
101     * @param m matrix to postmultiply by
102     * @return {@code this * m}
103     * @throws DimensionMismatchException if
104     * {@code columnDimension(this) != rowDimension(m)}
105     */
106    RealMatrix multiply(RealMatrix m)
107        throws DimensionMismatchException;
108
109    /**
110     * Returns the result of premultiplying {@code this} by {@code m}.
111     *
112     * @param m matrix to premultiply by
113     * @return {@code m * this}
114     * @throws DimensionMismatchException if
115     * {@code rowDimension(this) != columnDimension(m)}
116     */
117    RealMatrix preMultiply(RealMatrix m)
118        throws DimensionMismatchException;
119
120    /**
121     * Returns the result of multiplying {@code this} with itself {@code p}
122     * times. Depending on the underlying storage, instability for high powers
123     * might occur.
124     *
125     * @param p raise {@code this} to power {@code p}
126     * @return {@code this^p}
127     * @throws NotPositiveException if {@code p < 0}
128     * @throws NonSquareMatrixException if the matrix is not square
129     */
130    RealMatrix power(int p)
131        throws NotPositiveException, NonSquareMatrixException;
132
133    /**
134     * Returns matrix entries as a two-dimensional array.
135     *
136     * @return 2-dimensional array of entries
137     */
138    double[][] getData();
139
140    /**
141     * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
142     * maximum absolute row sum norm</a> of the matrix.
143     *
144     * @return norm
145     */
146    double getNorm();
147
148    /**
149     * Returns the <a href="http://mathworld.wolfram.com/FrobeniusNorm.html">
150     * Frobenius norm</a> of the matrix.
151     *
152     * @return norm
153     */
154    double getFrobeniusNorm();
155
156    /**
157     * Gets a submatrix. Rows and columns are indicated
158     * counting from 0 to n-1.
159     *
160     * @param startRow Initial row index
161     * @param endRow Final row index (inclusive)
162     * @param startColumn Initial column index
163     * @param endColumn Final column index (inclusive)
164     * @return The subMatrix containing the data of the
165     * specified rows and columns.
166     * @throws OutOfRangeException if the indices are not valid.
167     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
168     * {@code endColumn < startColumn}.
169     */
170    RealMatrix getSubMatrix(int startRow, int endRow, int startColumn,
171                            int endColumn)
172        throws OutOfRangeException, NumberIsTooSmallException;
173
174    /**
175     * Gets a submatrix. Rows and columns are indicated counting from 0 to n-1.
176     *
177     * @param selectedRows Array of row indices.
178     * @param selectedColumns Array of column indices.
179     * @return The subMatrix containing the data in the specified rows and
180     * columns
181     * @throws NullArgumentException if the row or column selections are
182     * {@code null}
183     * @throws NoDataException if the row or column selections are empty (zero
184     * length).
185     * @throws OutOfRangeException if the indices are not valid.
186     */
187    RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
188        throws NullArgumentException, NoDataException, OutOfRangeException;
189
190    /**
191     * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
192     *
193     * @param startRow Initial row index
194     * @param endRow Final row index (inclusive)
195     * @param startColumn Initial column index
196     * @param endColumn Final column index (inclusive)
197     * @param destination The arrays where the submatrix data should be copied
198     * (if larger than rows/columns counts, only the upper-left part will be
199     * used)
200     * @throws OutOfRangeException if the indices are not valid.
201     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
202     * {@code endColumn < startColumn}.
203     * @throws MatrixDimensionMismatchException if the destination array is too
204     * small.
205     */
206    void copySubMatrix(int startRow, int endRow, int startColumn,
207                       int endColumn, double[][] destination)
208        throws OutOfRangeException, NumberIsTooSmallException,
209        MatrixDimensionMismatchException;
210
211    /**
212     * Copy a submatrix. Rows and columns are indicated counting from 0 to n-1.
213     *
214     * @param selectedRows Array of row indices.
215     * @param selectedColumns Array of column indices.
216     * @param destination The arrays where the submatrix data should be copied
217     * (if larger than rows/columns counts, only the upper-left part will be
218     * used)
219     * @throws NullArgumentException if the row or column selections are
220     * {@code null}
221     * @throws NoDataException if the row or column selections are empty (zero
222     * length).
223     * @throws OutOfRangeException if the indices are not valid.
224     * @throws MatrixDimensionMismatchException if the destination array is too
225     * small.
226     */
227    void copySubMatrix(int[] selectedRows, int[] selectedColumns,
228                       double[][] destination)
229        throws OutOfRangeException, NullArgumentException, NoDataException,
230        MatrixDimensionMismatchException;
231
232   /**
233    * Replace the submatrix starting at {@code row, column} using data in the
234    * input {@code subMatrix} array. Indexes are 0-based.
235    * <p>
236    * Example:<br>
237    * Starting with <pre>
238    * 1  2  3  4
239    * 5  6  7  8
240    * 9  0  1  2
241    * </pre>
242    * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
243    * {@code setSubMatrix(subMatrix,1,1))} will result in <pre>
244    * 1  2  3  4
245    * 5  3  4  8
246    * 9  5  6  2
247    * </pre>
248    *
249    * @param subMatrix  array containing the submatrix replacement data
250    * @param row  row coordinate of the top, left element to be replaced
251    * @param column  column coordinate of the top, left element to be replaced
252    * @throws NoDataException if {@code subMatrix} is empty.
253    * @throws OutOfRangeException if {@code subMatrix} does not fit into
254    * this matrix from element in {@code (row, column)}.
255    * @throws DimensionMismatchException if {@code subMatrix} is not rectangular
256    * (not all rows have the same length) or empty.
257    * @throws NullArgumentException if {@code subMatrix} is {@code null}.
258    * @since 2.0
259    */
260    void setSubMatrix(double[][] subMatrix, int row, int column)
261        throws NoDataException, OutOfRangeException,
262        DimensionMismatchException, NullArgumentException;
263
264   /**
265    * Get the entries at the given row index as a row matrix.  Row indices start
266    * at 0.
267    *
268    * @param row Row to be fetched.
269    * @return row Matrix.
270    * @throws OutOfRangeException if the specified row index is invalid.
271    */
272   RealMatrix getRowMatrix(int row) throws OutOfRangeException;
273
274    /**
275     * Sets the specified {@code row} of {@code this} matrix to the entries of
276     * the specified row {@code matrix}. Row indices start at 0.
277     *
278     * @param row Row to be set.
279     * @param matrix Row matrix to be copied (must have one row and the same
280     * number of columns as the instance).
281     * @throws OutOfRangeException if the specified row index is invalid.
282     * @throws MatrixDimensionMismatchException if the row dimension of the
283     * {@code matrix} is not {@code 1}, or the column dimensions of {@code this}
284     * and {@code matrix} do not match.
285     */
286    void setRowMatrix(int row, RealMatrix matrix)
287        throws OutOfRangeException, MatrixDimensionMismatchException;
288
289    /**
290     * Get the entries at the given column index as a column matrix. Column
291     * indices start at 0.
292     *
293     * @param column Column to be fetched.
294     * @return column Matrix.
295     * @throws OutOfRangeException if the specified column index is invalid.
296     */
297    RealMatrix getColumnMatrix(int column)
298        throws OutOfRangeException;
299
300    /**
301     * Sets the specified {@code column} of {@code this} matrix to the entries
302     * of the specified column {@code matrix}. Column indices start at 0.
303     *
304     * @param column Column to be set.
305     * @param matrix Column matrix to be copied (must have one column and the
306     * same number of rows as the instance).
307     * @throws OutOfRangeException if the specified column index is invalid.
308     * @throws MatrixDimensionMismatchException if the column dimension of the
309     * {@code matrix} is not {@code 1}, or the row dimensions of {@code this}
310     * and {@code matrix} do not match.
311     */
312    void setColumnMatrix(int column, RealMatrix matrix)
313        throws OutOfRangeException, MatrixDimensionMismatchException;
314
315    /**
316     * Returns the entries in row number {@code row} as a vector. Row indices
317     * start at 0.
318     *
319     * @param row Row to be fetched.
320     * @return a row vector.
321     * @throws OutOfRangeException if the specified row index is invalid.
322     */
323    RealVector getRowVector(int row)
324        throws OutOfRangeException;
325
326    /**
327     * Sets the specified {@code row} of {@code this} matrix to the entries of
328     * the specified {@code vector}. Row indices start at 0.
329     *
330     * @param row Row to be set.
331     * @param vector row vector to be copied (must have the same number of
332     * column as the instance).
333     * @throws OutOfRangeException if the specified row index is invalid.
334     * @throws MatrixDimensionMismatchException if the {@code vector} dimension
335     * does not match the column dimension of {@code this} matrix.
336     */
337    void setRowVector(int row, RealVector vector)
338        throws OutOfRangeException, MatrixDimensionMismatchException;
339
340    /**
341     * Get the entries at the given column index as a vector. Column indices
342     * start at 0.
343     *
344     * @param column Column to be fetched.
345     * @return a column vector.
346     * @throws OutOfRangeException if the specified column index is invalid
347     */
348    RealVector getColumnVector(int column)
349        throws OutOfRangeException;
350
351    /**
352     * Sets the specified {@code column} of {@code this} matrix to the entries
353     * of the specified {@code vector}. Column indices start at 0.
354     *
355     * @param column Column to be set.
356     * @param vector column vector to be copied (must have the same number of
357     * rows as the instance).
358     * @throws OutOfRangeException if the specified column index is invalid.
359     * @throws MatrixDimensionMismatchException if the {@code vector} dimension
360     * does not match the row dimension of {@code this} matrix.
361     */
362    void setColumnVector(int column, RealVector vector)
363        throws OutOfRangeException, MatrixDimensionMismatchException;
364
365    /**
366     * Get the entries at the given row index. Row indices start at 0.
367     *
368     * @param row Row to be fetched.
369     * @return the array of entries in the row.
370     * @throws OutOfRangeException if the specified row index is not valid.
371     */
372    double[] getRow(int row) throws OutOfRangeException;
373
374    /**
375     * Sets the specified {@code row} of {@code this} matrix to the entries
376     * of the specified {@code array}. Row indices start at 0.
377     *
378     * @param row Row to be set.
379     * @param array Row matrix to be copied (must have the same number of
380     * columns as the instance)
381     * @throws OutOfRangeException if the specified row index is invalid.
382     * @throws MatrixDimensionMismatchException if the {@code array} length does
383     * not match the column dimension of {@code this} matrix.
384     */
385    void setRow(int row, double[] array)
386        throws OutOfRangeException, MatrixDimensionMismatchException;
387
388    /**
389     * Get the entries at the given column index as an array. Column indices
390     * start at 0.
391     *
392     * @param column Column to be fetched.
393     * @return the array of entries in the column.
394     * @throws OutOfRangeException if the specified column index is not valid.
395     */
396    double[] getColumn(int column) throws OutOfRangeException;
397
398    /**
399     * Sets the specified {@code column} of {@code this} matrix to the entries
400     * of the specified {@code array}. Column indices start at 0.
401     *
402     * @param column Column to be set.
403     * @param array Column array to be copied (must have the same number of
404     * rows as the instance).
405     * @throws OutOfRangeException if the specified column index is invalid.
406     * @throws MatrixDimensionMismatchException if the {@code array} length does
407     * not match the row dimension of {@code this} matrix.
408     */
409    void setColumn(int column, double[] array)
410        throws OutOfRangeException, MatrixDimensionMismatchException;
411
412    /**
413     * Get the entry in the specified row and column. Row and column indices
414     * start at 0.
415     *
416     * @param row Row index of entry to be fetched.
417     * @param column Column index of entry to be fetched.
418     * @return the matrix entry at {@code (row, column)}.
419     * @throws OutOfRangeException if the row or column index is not valid.
420     */
421    double getEntry(int row, int column) throws OutOfRangeException;
422
423    /**
424     * Set the entry in the specified row and column. Row and column indices
425     * start at 0.
426     *
427     * @param row Row index of entry to be set.
428     * @param column Column index of entry to be set.
429     * @param value the new value of the entry.
430     * @throws OutOfRangeException if the row or column index is not valid
431     * @since 2.0
432     */
433    void setEntry(int row, int column, double value) throws OutOfRangeException;
434
435    /**
436     * Adds (in place) the specified value to the specified entry of
437     * {@code this} matrix. Row and column indices start at 0.
438     *
439     * @param row Row index of the entry to be modified.
440     * @param column Column index of the entry to be modified.
441     * @param increment value to add to the matrix entry.
442     * @throws OutOfRangeException if the row or column index is not valid.
443     * @since 2.0
444     */
445    void addToEntry(int row, int column, double increment) throws OutOfRangeException;
446
447    /**
448     * Multiplies (in place) the specified entry of {@code this} matrix by the
449     * specified value. Row and column indices start at 0.
450     *
451     * @param row Row index of the entry to be modified.
452     * @param column Column index of the entry to be modified.
453     * @param factor Multiplication factor for the matrix entry.
454     * @throws OutOfRangeException if the row or column index is not valid.
455     * @since 2.0
456     */
457    void multiplyEntry(int row, int column, double factor) throws OutOfRangeException;
458
459    /**
460     * Returns the transpose of this matrix.
461     *
462     * @return transpose matrix
463     */
464    RealMatrix transpose();
465
466    /**
467     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
468     * trace</a> of the matrix (the sum of the elements on the main diagonal).
469     *
470     * @return the trace.
471     * @throws NonSquareMatrixException if the matrix is not square.
472     */
473    double getTrace() throws NonSquareMatrixException;
474
475    /**
476     * Returns the result of multiplying this by the vector {@code v}.
477     *
478     * @param v the vector to operate on
479     * @return {@code this * v}
480     * @throws DimensionMismatchException if the length of {@code v} does not
481     * match the column dimension of {@code this}.
482     */
483    double[] operate(double[] v) throws DimensionMismatchException;
484
485    /**
486     * Returns the result of multiplying this by the vector {@code v}.
487     *
488     * @param v the vector to operate on
489     * @return {@code this * v}
490     * @throws DimensionMismatchException if the dimension of {@code v} does not
491     * match the column dimension of {@code this}.
492     */
493    RealVector operate(RealVector v) throws DimensionMismatchException;
494
495    /**
496     * Returns the (row) vector result of premultiplying this by the vector {@code v}.
497     *
498     * @param v the row vector to premultiply by
499     * @return {@code v * this}
500     * @throws DimensionMismatchException if the length of {@code v} does not
501     * match the row dimension of {@code this}.
502     */
503    double[] preMultiply(double[] v) throws DimensionMismatchException;
504
505    /**
506     * Returns the (row) vector result of premultiplying this by the vector {@code v}.
507     *
508     * @param v the row vector to premultiply by
509     * @return {@code v * this}
510     * @throws DimensionMismatchException if the dimension of {@code v} does not
511     * match the row dimension of {@code this}.
512     */
513    RealVector preMultiply(RealVector v) throws DimensionMismatchException;
514
515    /**
516     * Visit (and possibly change) all matrix entries in row order.
517     * <p>Row order starts at upper left and iterating through all elements
518     * of a row from left to right before going to the leftmost element
519     * of the next row.</p>
520     * @param visitor visitor used to process all matrix entries
521     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
522     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
523     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
524     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
525     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
526     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
527     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
528     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
529     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
530     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
531     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
532     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
533     * of the walk
534     */
535    double walkInRowOrder(RealMatrixChangingVisitor visitor);
536
537    /**
538     * Visit (but don't change) all matrix entries in row order.
539     * <p>Row order starts at upper left and iterating through all elements
540     * of a row from left to right before going to the leftmost element
541     * of the next row.</p>
542     * @param visitor visitor used to process all matrix entries
543     * @see #walkInRowOrder(RealMatrixChangingVisitor)
544     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
545     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
546     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
547     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
548     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
549     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
550     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
551     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
552     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
553     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
554     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
555     * of the walk
556     */
557    double walkInRowOrder(RealMatrixPreservingVisitor visitor);
558
559    /**
560     * Visit (and possibly change) some matrix entries in row order.
561     * <p>Row order starts at upper left and iterating through all elements
562     * of a row from left to right before going to the leftmost element
563     * of the next row.</p>
564     * @param visitor visitor used to process all matrix entries
565     * @param startRow Initial row index
566     * @param endRow Final row index (inclusive)
567     * @param startColumn Initial column index
568     * @param endColumn Final column index
569     * @throws OutOfRangeException if the indices are not valid.
570     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
571     * {@code endColumn < startColumn}.
572     * @see #walkInRowOrder(RealMatrixChangingVisitor)
573     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
574     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
575     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
576     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
577     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
578     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
579     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
580     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
581     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
582     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
583     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
584     * of the walk
585     */
586    double walkInRowOrder(RealMatrixChangingVisitor visitor, int startRow,
587        int endRow, int startColumn, int endColumn)
588        throws OutOfRangeException, NumberIsTooSmallException;
589
590    /**
591     * Visit (but don't change) some matrix entries in row order.
592     * <p>Row order starts at upper left and iterating through all elements
593     * of a row from left to right before going to the leftmost element
594     * of the next row.</p>
595     * @param visitor visitor used to process all matrix entries
596     * @param startRow Initial row index
597     * @param endRow Final row index (inclusive)
598     * @param startColumn Initial column index
599     * @param endColumn Final column index
600     * @throws OutOfRangeException if the indices are not valid.
601     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
602     * {@code endColumn < startColumn}.
603     * @see #walkInRowOrder(RealMatrixChangingVisitor)
604     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
605     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
606     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
607     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
608     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
609     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
610     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
611     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
612     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
613     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
614     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
615     * of the walk
616     */
617    double walkInRowOrder(RealMatrixPreservingVisitor visitor, int startRow,
618        int endRow, int startColumn, int endColumn)
619        throws OutOfRangeException, NumberIsTooSmallException;
620
621    /**
622     * Visit (and possibly change) all matrix entries in column order.
623     * <p>Column order starts at upper left and iterating through all elements
624     * of a column from top to bottom before going to the topmost element
625     * of the next column.</p>
626     * @param visitor visitor used to process all matrix entries
627     * @see #walkInRowOrder(RealMatrixChangingVisitor)
628     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
629     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
630     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
631     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
632     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
633     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
634     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
635     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
636     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
637     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
638     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
639     * of the walk
640     */
641    double walkInColumnOrder(RealMatrixChangingVisitor visitor);
642
643    /**
644     * Visit (but don't change) all matrix entries in column order.
645     * <p>Column order starts at upper left and iterating through all elements
646     * of a column from top to bottom before going to the topmost element
647     * of the next column.</p>
648     * @param visitor visitor used to process all matrix entries
649     * @see #walkInRowOrder(RealMatrixChangingVisitor)
650     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
651     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
652     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
653     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
654     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
655     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
656     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
657     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
658     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
659     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
660     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
661     * of the walk
662     */
663    double walkInColumnOrder(RealMatrixPreservingVisitor visitor);
664
665    /**
666     * Visit (and possibly change) some matrix entries in column order.
667     * <p>Column order starts at upper left and iterating through all elements
668     * of a column from top to bottom before going to the topmost element
669     * of the next column.</p>
670     * @param visitor visitor used to process all matrix entries
671     * @param startRow Initial row index
672     * @param endRow Final row index (inclusive)
673     * @param startColumn Initial column index
674     * @param endColumn Final column index
675     * @throws OutOfRangeException if the indices are not valid.
676     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
677     * {@code endColumn < startColumn}.
678     * @see #walkInRowOrder(RealMatrixChangingVisitor)
679     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
680     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
681     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
682     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
683     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
684     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
685     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
686     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
687     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
688     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
689     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
690     * of the walk
691     */
692    double walkInColumnOrder(RealMatrixChangingVisitor visitor, int startRow,
693        int endRow, int startColumn, int endColumn)
694        throws OutOfRangeException, NumberIsTooSmallException;
695
696    /**
697     * Visit (but don't change) some matrix entries in column order.
698     * <p>Column order starts at upper left and iterating through all elements
699     * of a column from top to bottom before going to the topmost element
700     * of the next column.</p>
701     * @param visitor visitor used to process all matrix entries
702     * @param startRow Initial row index
703     * @param endRow Final row index (inclusive)
704     * @param startColumn Initial column index
705     * @param endColumn Final column index
706     * @throws OutOfRangeException if the indices are not valid.
707     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
708     * {@code endColumn < startColumn}.
709     * @see #walkInRowOrder(RealMatrixChangingVisitor)
710     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
711     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
712     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
713     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
714     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
715     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
716     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
717     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
718     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
719     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
720     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
721     * of the walk
722     */
723    double walkInColumnOrder(RealMatrixPreservingVisitor visitor, int startRow,
724        int endRow, int startColumn, int endColumn)
725        throws OutOfRangeException, NumberIsTooSmallException;
726
727    /**
728     * Visit (and possibly change) all matrix entries using the fastest possible order.
729     * <p>The fastest walking order depends on the exact matrix class. It may be
730     * different from traditional row or column orders.</p>
731     * @param visitor visitor used to process all matrix entries
732     * @see #walkInRowOrder(RealMatrixChangingVisitor)
733     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
734     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
735     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
736     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
737     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
738     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
739     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
740     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
741     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
742     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
743     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
744     * of the walk
745     */
746    double walkInOptimizedOrder(RealMatrixChangingVisitor visitor);
747
748    /**
749     * Visit (but don't change) all matrix entries using the fastest possible order.
750     * <p>The fastest walking order depends on the exact matrix class. It may be
751     * different from traditional row or column orders.</p>
752     * @param visitor visitor used to process all matrix entries
753     * @see #walkInRowOrder(RealMatrixChangingVisitor)
754     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
755     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
756     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
757     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
758     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
759     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
760     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
761     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
762     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
763     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
764     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
765     * of the walk
766     */
767    double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor);
768
769    /**
770     * Visit (and possibly change) some matrix entries using the fastest possible order.
771     * <p>The fastest walking order depends on the exact matrix class. It may be
772     * different from traditional row or column orders.</p>
773     * @param visitor visitor used to process all matrix entries
774     * @param startRow Initial row index
775     * @param endRow Final row index (inclusive)
776     * @param startColumn Initial column index
777     * @param endColumn Final column index (inclusive)
778     * @throws OutOfRangeException if the indices are not valid.
779     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
780     * {@code endColumn < startColumn}.
781     * @see #walkInRowOrder(RealMatrixChangingVisitor)
782     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
783     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
784     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
785     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
786     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
787     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
788     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
789     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
790     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
791     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor, int, int, int, int)
792     * @return the value returned by {@link RealMatrixChangingVisitor#end()} at the end
793     * of the walk
794     */
795    double walkInOptimizedOrder(RealMatrixChangingVisitor visitor,
796        int startRow, int endRow, int startColumn, int endColumn)
797        throws OutOfRangeException, NumberIsTooSmallException;
798
799    /**
800     * Visit (but don't change) some matrix entries using the fastest possible order.
801     * <p>The fastest walking order depends on the exact matrix class. It may be
802     * different from traditional row or column orders.</p>
803     * @param visitor visitor used to process all matrix entries
804     * @param startRow Initial row index
805     * @param endRow Final row index (inclusive)
806     * @param startColumn Initial column index
807     * @param endColumn Final column index (inclusive)
808     * @throws OutOfRangeException if the indices are not valid.
809     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
810     * {@code endColumn < startColumn}.
811     * @see #walkInRowOrder(RealMatrixChangingVisitor)
812     * @see #walkInRowOrder(RealMatrixPreservingVisitor)
813     * @see #walkInRowOrder(RealMatrixChangingVisitor, int, int, int, int)
814     * @see #walkInRowOrder(RealMatrixPreservingVisitor, int, int, int, int)
815     * @see #walkInColumnOrder(RealMatrixChangingVisitor)
816     * @see #walkInColumnOrder(RealMatrixPreservingVisitor)
817     * @see #walkInColumnOrder(RealMatrixChangingVisitor, int, int, int, int)
818     * @see #walkInColumnOrder(RealMatrixPreservingVisitor, int, int, int, int)
819     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor)
820     * @see #walkInOptimizedOrder(RealMatrixPreservingVisitor)
821     * @see #walkInOptimizedOrder(RealMatrixChangingVisitor, int, int, int, int)
822     * @return the value returned by {@link RealMatrixPreservingVisitor#end()} at the end
823     * of the walk
824     */
825    double walkInOptimizedOrder(RealMatrixPreservingVisitor visitor,
826        int startRow, int endRow, int startColumn, int endColumn)
827        throws OutOfRangeException, NumberIsTooSmallException;
828}