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