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.math3.linear;
019
020
021import org.apache.commons.math3.Field;
022import org.apache.commons.math3.FieldElement;
023import org.apache.commons.math3.exception.DimensionMismatchException;
024import org.apache.commons.math3.exception.NoDataException;
025import org.apache.commons.math3.exception.NotPositiveException;
026import org.apache.commons.math3.exception.NotStrictlyPositiveException;
027import org.apache.commons.math3.exception.NullArgumentException;
028import org.apache.commons.math3.exception.NumberIsTooSmallException;
029import org.apache.commons.math3.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 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(final int rowDimension, final 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(final 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 indicated
180    * counting from 0 to n-1.
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 arrays where the submatrix data should be copied
187    * (if larger than rows/columns counts, only the upper-left part will be used).
188    * @throws MatrixDimensionMismatchException if the dimensions of
189    * {@code destination} do not match those of {@code this}.
190    * @throws NumberIsTooSmallException is {@code endRow < startRow} of
191    * {@code endColumn < startColumn}.
192    * @throws OutOfRangeException if the indices are not valid.
193    * @exception IllegalArgumentException if the destination array is too small.
194    */
195    void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
196                       T[][] destination)
197    throws MatrixDimensionMismatchException, NumberIsTooSmallException,
198    OutOfRangeException;
199
200  /**
201   * Copy a submatrix. Rows and columns are indicated
202   * counting from 0 to n - 1.
203   *
204   * @param selectedRows Array of row indices.
205   * @param selectedColumns Array of column indices.
206   * @param destination Arrays where the submatrix data should be copied
207   * (if larger than rows/columns counts, only the upper-left part will be used)
208   * @throws MatrixDimensionMismatchException if the dimensions of
209   * {@code destination} do not match those of {@code this}.
210   * @throws NoDataException if {@code selectedRows} or
211   * {@code selectedColumns} is empty
212   * @throws NullArgumentException if {@code selectedRows} or
213   * {@code selectedColumns} is {@code null}.
214   * @throws OutOfRangeException if the indices are not valid.
215   */
216  void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
217  throws MatrixDimensionMismatchException, NoDataException, NullArgumentException,
218  OutOfRangeException;
219
220    /**
221     * Replace the submatrix starting at {@code (row, column)} using data in the
222     * input {@code subMatrix} array. Indexes are 0-based.
223     * <p>
224     * Example:<br>
225     * Starting with
226     *
227     * <pre>
228     * 1  2  3  4
229     * 5  6  7  8
230     * 9  0  1  2
231     * </pre>
232     *
233     * and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
234     * <code>setSubMatrix(subMatrix,1,1))</code> will result in
235     *
236     * <pre>
237     * 1  2  3  4
238     * 5  3  4  8
239     * 9  5  6  2
240     * </pre>
241     *
242     * </p>
243     *
244     * @param subMatrix Array containing the submatrix replacement data.
245     * @param row Row coordinate of the top-left element to be replaced.
246     * @param column Column coordinate of the top-left element to be replaced.
247     * @throws OutOfRangeException if {@code subMatrix} does not fit into this
248     * matrix from element in {@code (row, column)}.
249     * @throws NoDataException if a row or column of {@code subMatrix} is empty.
250     * @throws DimensionMismatchException if {@code subMatrix} is not
251     * rectangular (not all rows have the same length).
252     * @throws NullArgumentException if {@code subMatrix} is {@code null}.
253     * @since 2.0
254     */
255    void setSubMatrix(T[][] subMatrix, int row, int column)
256        throws DimensionMismatchException, OutOfRangeException,
257        NoDataException, NullArgumentException;
258
259   /**
260    * Get the entries in row number {@code row}
261    * as a row matrix.
262    *
263    * @param row Row to be fetched.
264    * @return a row matrix.
265    * @throws OutOfRangeException if the specified row index is invalid.
266    */
267   FieldMatrix<T> getRowMatrix(int row) throws OutOfRangeException;
268
269   /**
270    * Set the entries in row number {@code row}
271    * as a row matrix.
272    *
273    * @param row Row to be set.
274    * @param matrix Row matrix (must have one row and the same number
275    * of columns as the instance).
276    * @throws OutOfRangeException if the specified row index is invalid.
277    * @throws MatrixDimensionMismatchException
278    * if the matrix dimensions do not match one instance row.
279    */
280   void setRowMatrix(int row, FieldMatrix<T> matrix)
281   throws MatrixDimensionMismatchException, OutOfRangeException;
282
283   /**
284    * Get the entries in column number {@code column}
285    * as a column matrix.
286    *
287    * @param column Column to be fetched.
288    * @return a column matrix.
289    * @throws OutOfRangeException if the specified column index is invalid.
290    */
291   FieldMatrix<T> getColumnMatrix(int column) throws OutOfRangeException;
292
293   /**
294    * Set the entries in column number {@code column}
295    * as a column matrix.
296    *
297    * @param column Column to be set.
298    * @param matrix column matrix (must have one column and the same
299    * number of rows as the instance).
300    * @throws OutOfRangeException if the specified column index is invalid.
301    * @throws MatrixDimensionMismatchException if the matrix dimensions do
302    * not match one instance column.
303    */
304   void setColumnMatrix(int column, FieldMatrix<T> matrix)
305   throws MatrixDimensionMismatchException, OutOfRangeException;
306
307   /**
308    * Get the entries in row number {@code row}
309    * as a vector.
310    *
311    * @param row Row to be fetched
312    * @return a row vector.
313    * @throws OutOfRangeException if the specified row index is invalid.
314    */
315   FieldVector<T> getRowVector(int row) throws OutOfRangeException;
316
317   /**
318    * Set the entries in row number {@code row}
319    * as a vector.
320    *
321    * @param row Row to be set.
322    * @param vector row vector (must have the same number of columns
323    * as the instance).
324    * @throws OutOfRangeException if the specified row index is invalid.
325    * @throws MatrixDimensionMismatchException if the vector dimension does not
326    * match one instance row.
327    */
328   void setRowVector(int row, FieldVector<T> vector)
329   throws MatrixDimensionMismatchException, OutOfRangeException;
330
331   /**
332    * Returns the entries in column number {@code column}
333    * as a vector.
334    *
335    * @param column Column to be fetched.
336    * @return a column vector.
337    * @throws OutOfRangeException if the specified column index is invalid.
338    */
339   FieldVector<T> getColumnVector(int column) throws OutOfRangeException;
340
341   /**
342    * Set the entries in column number {@code column}
343    * as a vector.
344    *
345    * @param column Column to be set.
346    * @param vector Column vector (must have the same number of rows
347    * as the instance).
348    * @throws OutOfRangeException if the specified column index is invalid.
349    * @throws MatrixDimensionMismatchException if the vector dimension does not
350    * match one instance column.
351    */
352   void setColumnVector(int column, FieldVector<T> vector)
353   throws MatrixDimensionMismatchException, OutOfRangeException;
354
355    /**
356     * Get the entries in row number {@code row} as an array.
357     *
358     * @param row Row to be fetched.
359     * @return array of entries in the row.
360     * @throws OutOfRangeException if the specified row index is not valid.
361     */
362    T[] getRow(int row) throws OutOfRangeException;
363
364    /**
365     * Set the entries in row number {@code row}
366     * as a row matrix.
367     *
368     * @param row Row to be set.
369     * @param array Row matrix (must have the same number of columns as
370     * the instance).
371     * @throws OutOfRangeException if the specified row index is invalid.
372     * @throws MatrixDimensionMismatchException if the array size does not match
373     * one instance row.
374     */
375    void setRow(int row, T[] array) throws MatrixDimensionMismatchException,
376    OutOfRangeException;
377
378    /**
379     * Get the entries in column number {@code col} as an array.
380     *
381     * @param column the column to be fetched
382     * @return array of entries in the column
383     * @throws OutOfRangeException if the specified column index is not valid.
384     */
385    T[] getColumn(int column) throws OutOfRangeException;
386
387    /**
388     * Set the entries in column number {@code column}
389     * as a column matrix.
390     *
391     * @param column the column to be set
392     * @param array column array (must have the same number of rows as the instance)
393     * @throws OutOfRangeException if the specified column index is invalid.
394     * @throws MatrixDimensionMismatchException if the array size does not match
395     * one instance column.
396     */
397    void setColumn(int column, T[] array) throws MatrixDimensionMismatchException,
398    OutOfRangeException;
399
400    /**
401     * Returns the entry in the specified row and column.
402     *
403     * @param row  row location of entry to be fetched
404     * @param column  column location of entry to be fetched
405     * @return matrix entry in row,column
406     * @throws OutOfRangeException if the row or column index is not valid.
407     */
408    T getEntry(int row, int column) throws OutOfRangeException;
409
410    /**
411     * Set the entry in the specified row and column.
412     *
413     * @param row  row location of entry to be set
414     * @param column  column location of entry to be set
415     * @param value matrix entry to be set in row,column
416     * @throws OutOfRangeException if the row or column index is not valid.
417     * @since 2.0
418     */
419    void setEntry(int row, int column, T value) throws OutOfRangeException;
420
421    /**
422     * Change an entry in the specified row and column.
423     *
424     * @param row Row location of entry to be set.
425     * @param column Column location of entry to be set.
426     * @param increment Value to add to the current matrix entry in
427     * {@code (row, column)}.
428     * @throws OutOfRangeException if the row or column index is not valid.
429     * @since 2.0
430     */
431    void addToEntry(int row, int column, T increment) throws OutOfRangeException;
432
433    /**
434     * Change an entry in the specified row and column.
435     *
436     * @param row Row location of entry to be set.
437     * @param column Column location of entry to be set.
438     * @param factor Multiplication factor for the current matrix entry
439     * in {@code (row,column)}
440     * @throws OutOfRangeException if the row or column index is not valid.
441     * @since 2.0
442     */
443    void multiplyEntry(int row, int column, T factor) throws OutOfRangeException;
444
445    /**
446     * Returns the transpose of this matrix.
447     *
448     * @return transpose matrix
449     */
450    FieldMatrix<T> transpose();
451
452    /**
453     * Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
454     * trace</a> of the matrix (the sum of the elements on the main diagonal).
455     *
456     * @return trace
457     * @throws NonSquareMatrixException if the matrix is not square.
458     */
459    T getTrace() throws NonSquareMatrixException;
460
461    /**
462     * Returns the result of multiplying this by the vector {@code v}.
463     *
464     * @param v the vector to operate on
465     * @return {@code this * v}
466     * @throws DimensionMismatchException if the number of columns of
467     * {@code this} matrix is not equal to the size of the vector {@code v}.
468     */
469    T[] operate(T[] v) throws DimensionMismatchException;
470
471    /**
472     * Returns the result of multiplying this by the vector {@code v}.
473     *
474     * @param v the vector to operate on
475     * @return {@code this * v}
476     * @throws DimensionMismatchException if the number of columns of
477     * {@code this} matrix is not equal to the size of the vector {@code v}.
478     */
479    FieldVector<T> operate(FieldVector<T> v) throws DimensionMismatchException;
480
481    /**
482     * Returns the (row) vector result of premultiplying this by the vector
483     * {@code v}.
484     *
485     * @param v the row vector to premultiply by
486     * @return {@code v * this}
487     * @throws DimensionMismatchException if the number of rows of {@code this}
488     * matrix is not equal to the size of the vector {@code v}
489     */
490    T[] preMultiply(T[] v) throws DimensionMismatchException;
491
492    /**
493     * Returns the (row) vector result of premultiplying this by the vector
494     * {@code v}.
495     *
496     * @param v the row vector to premultiply by
497     * @return {@code v * this}
498     * @throws DimensionMismatchException if the number of rows of {@code this}
499     * matrix is not equal to the size of the vector {@code v}
500     */
501    FieldVector<T> preMultiply(FieldVector<T> v) throws DimensionMismatchException;
502
503    /**
504     * Visit (and possibly change) all matrix entries in row order.
505     * <p>Row order starts at upper left and iterating through all elements
506     * of a row from left to right before going to the leftmost element
507     * of the next row.</p>
508     * @param visitor visitor used to process all matrix entries
509     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
510     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
511     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
512     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
513     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
514     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
515     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
516     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
517     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
518     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
519     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
520     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
521     * of the walk
522     */
523    T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor);
524
525    /**
526     * Visit (but don't change) all matrix entries in row order.
527     * <p>Row order starts at upper left and iterating through all elements
528     * of a row from left to right before going to the leftmost element
529     * of the next row.</p>
530     * @param visitor visitor used to process all matrix entries
531     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
532     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
533     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
534     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
535     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
536     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
537     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
538     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
539     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
540     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
541     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
542     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
543     * of the walk
544     */
545    T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor);
546
547    /**
548     * Visit (and possibly change) some matrix entries in row order.
549     * <p>Row order starts at upper left and iterating through all elements
550     * of a row from left to right before going to the leftmost element
551     * of the next row.</p>
552     * @param visitor visitor used to process all matrix entries
553     * @param startRow Initial row index
554     * @param endRow Final row index (inclusive)
555     * @param startColumn Initial column index
556     * @param endColumn Final column index
557     * @throws OutOfRangeException if the indices are not valid.
558     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
559     * {@code endColumn < startColumn}.
560     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
561     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
562     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
563     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
564     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
565     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
566     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
567     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
568     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
569     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
570     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
571     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
572     * of the walk
573     */
574    T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor,
575                     int startRow, int endRow, int startColumn, int endColumn)
576    throws OutOfRangeException, NumberIsTooSmallException;
577
578    /**
579     * Visit (but don't change) some matrix entries in row order.
580     * <p>Row order starts at upper left and iterating through all elements
581     * of a row from left to right before going to the leftmost element
582     * of the next row.</p>
583     * @param visitor visitor used to process all matrix entries
584     * @param startRow Initial row index
585     * @param endRow Final row index (inclusive)
586     * @param startColumn Initial column index
587     * @param endColumn Final column index
588     * @throws OutOfRangeException if the indices are not valid.
589     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
590     * {@code endColumn < startColumn}.
591     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
592     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
593     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
594     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
595     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
596     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
597     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
598     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
599     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
600     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
601     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
602     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
603     * of the walk
604     */
605    T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor,
606                     int startRow, int endRow, int startColumn, int endColumn)
607    throws OutOfRangeException, NumberIsTooSmallException;
608
609    /**
610     * Visit (and possibly change) all matrix entries in column order.
611     * <p>Column order starts at upper left and iterating through all elements
612     * of a column from top to bottom before going to the topmost element
613     * of the next column.</p>
614     * @param visitor visitor used to process all matrix entries
615     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
616     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
617     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
618     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
619     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
620     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
621     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
622     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
623     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
624     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
625     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
626     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
627     * of the walk
628     */
629    T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor);
630
631    /**
632     * Visit (but don't change) all matrix entries in column order.
633     * <p>Column order starts at upper left and iterating through all elements
634     * of a column from top to bottom before going to the topmost element
635     * of the next column.</p>
636     * @param visitor visitor used to process all matrix entries
637     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
638     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
639     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
640     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
641     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
642     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
643     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
644     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
645     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
646     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
647     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
648     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
649     * of the walk
650     */
651    T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor);
652
653    /**
654     * Visit (and possibly change) some matrix entries in column order.
655     * <p>Column order starts at upper left and iterating through all elements
656     * of a column from top to bottom before going to the topmost element
657     * of the next column.</p>
658     * @param visitor visitor used to process all matrix entries
659     * @param startRow Initial row index
660     * @param endRow Final row index (inclusive)
661     * @param startColumn Initial column index
662     * @param endColumn Final column index
663     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
664     * {@code endColumn < startColumn}.
665     * @throws OutOfRangeException if the indices are not valid.
666     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
667     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
668     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
669     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
670     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
671     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
672     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
673     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
674     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
675     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
676     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
677     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
678     * of the walk
679     */
680    T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor,
681                        int startRow, int endRow, int startColumn, int endColumn)
682    throws NumberIsTooSmallException, OutOfRangeException;
683
684    /**
685     * Visit (but don't change) some matrix entries in column order.
686     * <p>Column order starts at upper left and iterating through all elements
687     * of a column from top to bottom before going to the topmost element
688     * of the next column.</p>
689     * @param visitor visitor used to process all matrix entries
690     * @param startRow Initial row index
691     * @param endRow Final row index (inclusive)
692     * @param startColumn Initial column index
693     * @param endColumn Final column index
694     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
695     * {@code endColumn < startColumn}.
696     * @throws OutOfRangeException if the indices are not valid.
697     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
698     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
699     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
700     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
701     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
702     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
703     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
704     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
705     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
706     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
707     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
708     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
709     * of the walk
710     */
711    T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor,
712                        int startRow, int endRow, int startColumn, int endColumn)
713    throws NumberIsTooSmallException, OutOfRangeException;
714
715    /**
716     * Visit (and possibly change) all matrix entries using the fastest possible order.
717     * <p>The fastest walking order depends on the exact matrix class. It may be
718     * different from traditional row or column orders.</p>
719     * @param visitor visitor used to process all matrix entries
720     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
721     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
722     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
723     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
724     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
725     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
726     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
727     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
728     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
729     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
730     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
731     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
732     * of the walk
733     */
734    T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor);
735
736    /**
737     * Visit (but don't change) all matrix entries using the fastest possible order.
738     * <p>The fastest walking order depends on the exact matrix class. It may be
739     * different from traditional row or column orders.</p>
740     * @param visitor visitor used to process all matrix entries
741     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
742     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
743     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
744     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
745     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
746     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
747     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
748     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
749     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
750     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
751     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
752     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
753     * of the walk
754     */
755    T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor);
756
757    /**
758     * Visit (and possibly change) some matrix entries using the fastest possible order.
759     * <p>The fastest walking order depends on the exact matrix class. It may be
760     * different from traditional row or column orders.</p>
761     * @param visitor visitor used to process all matrix entries
762     * @param startRow Initial row index
763     * @param endRow Final row index (inclusive)
764     * @param startColumn Initial column index
765     * @param endColumn Final column index (inclusive)
766     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
767     * {@code endColumn < startColumn}.
768     * @throws OutOfRangeException if the indices are not valid.
769     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
770     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
771     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
772     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
773     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
774     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
775     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
776     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
777     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
778     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
779     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
780     * @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
781     * of the walk
782     */
783    T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor,
784                           int startRow, int endRow, int startColumn, int endColumn)
785    throws NumberIsTooSmallException, OutOfRangeException;
786
787    /**
788     * Visit (but don't change) some matrix entries using the fastest possible order.
789     * <p>The fastest walking order depends on the exact matrix class. It may be
790     * different from traditional row or column orders.</p>
791     * @param visitor visitor used to process all matrix entries
792     * @param startRow Initial row index
793     * @param endRow Final row index (inclusive)
794     * @param startColumn Initial column index
795     * @param endColumn Final column index (inclusive)
796     * @throws NumberIsTooSmallException if {@code endRow < startRow} or
797     * {@code endColumn < startColumn}.
798     * @throws OutOfRangeException if the indices are not valid.
799     * @see #walkInRowOrder(FieldMatrixChangingVisitor)
800     * @see #walkInRowOrder(FieldMatrixPreservingVisitor)
801     * @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
802     * @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
803     * @see #walkInColumnOrder(FieldMatrixChangingVisitor)
804     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
805     * @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
806     * @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
807     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
808     * @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
809     * @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
810     * @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
811     * of the walk
812     */
813    T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor,
814                           int startRow, int endRow, int startColumn, int endColumn)
815    throws NumberIsTooSmallException, OutOfRangeException;
816}