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