added support for any kind of field in linear algebra
we can now use FieldMatrix<Fraction> and use exact LU-decomposition on such matrices to solve linear systems git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@766485 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d60149c7f8
commit
2d343b1a30
|
@ -109,6 +109,16 @@
|
|||
<Method name="getDataRef" params="" returns="double[][]" />
|
||||
<Bug pattern="EI_EXPOSE_REP" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Class name="org.apache.commons.math.linear.FieldMatrixImpl"/>
|
||||
<Method name="<init>" params="org.apache.commons.math.FieldElement[][],boolean" returns="void" />
|
||||
<Bug pattern="EI_EXPOSE_REP2" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Class name="org.apache.commons.math.linear.FieldMatrixImpl"/>
|
||||
<Method name="getDataRef" params="" returns="org.apache.commons.math.FieldElement[][]" />
|
||||
<Bug pattern="EI_EXPOSE_REP" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Class name="org.apache.commons.math.linear.DenseRealMatrix"/>
|
||||
<Method name="<init>" params="int,int,double[][],boolean" returns="void" />
|
||||
|
@ -127,6 +137,11 @@
|
|||
<Method name="getDataRef" params="" returns="double[]" />
|
||||
<Bug pattern="EI_EXPOSE_REP" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Class name="org.apache.commons.math.linear.FieldVectorImpl"/>
|
||||
<Method name="getDataRef" params="" returns="org.apache.commons.math.FieldElement[]" />
|
||||
<Bug pattern="EI_EXPOSE_REP" />
|
||||
</Match>
|
||||
|
||||
<!-- The following cases are intentional unit tests for null parameters -->
|
||||
<Match>
|
||||
|
|
|
@ -230,6 +230,12 @@ public class MessagesResources_fr
|
|||
{ "too small integration interval: length = {0}",
|
||||
"intervalle d''int\u00e9gration trop petit : {0}" },
|
||||
|
||||
// org.apache.commons.math.ode.stiff.BDFIntegrator
|
||||
{ "unsupported order {0} for BDF methods, must be between {1} and {2}",
|
||||
"ordre {0} non support\u00e9 pour les m\u00e9thodes BDF, doit \u00eatre entre {1} et {2}" },
|
||||
{ "corrector failed to converge after {0} iterations at t = {1}",
|
||||
"\u00e9chec de convergence du correcteur apr\u00e8s {0} it\u00e9rations \u00e0 t = {1}" },
|
||||
|
||||
// org.apache.commons.math.ode.ContinuousOutputModel
|
||||
// org.apache.commons.math.optimization.direct.DirectSearchOptimizer
|
||||
{ "unexpected exception caught",
|
||||
|
@ -276,6 +282,7 @@ public class MessagesResources_fr
|
|||
"dimension de vecteur erronn\u00e9e : {0} \u00e0 la place de {1}" },
|
||||
|
||||
// org.apache.commons.math.linear.RealVectorImpl
|
||||
// org.apache.commons.math.linear.FieldVectorImpl
|
||||
// org.apache.commons.math.linear.SparseRealVector
|
||||
{ "index {0} out of allowed range [{1}, {2}]",
|
||||
"index {0} hors de la plage autoris\u00e9e [{1}, {2}]" },
|
||||
|
@ -285,6 +292,7 @@ public class MessagesResources_fr
|
|||
"la position {0} et la taille {1} sont incompatibles avec la taille du tableau d''entr\u00e9e {2}"},
|
||||
|
||||
// org.apache.commons.math.linear.AbstractRealMatrix
|
||||
// org.apache.commons.math.linear.AbstractFieldMatrix
|
||||
{ "invalid row dimension: {0} (must be positive)",
|
||||
"nombre de lignes invalide : {0} (doit \u00eatre positif)" },
|
||||
{ "invalid column dimension: {0} (must be positive)",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,7 +27,10 @@ import java.math.BigDecimal;
|
|||
* returns the element in the first row, first column of the matrix.</p>
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
* @deprecated as of 2.0, replaced by {@link FieldMatrix} with a {@link
|
||||
* org.apache.commons.math.util.BigReal} parameter
|
||||
*/
|
||||
@Deprecated
|
||||
public interface BigMatrix {
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,8 +49,11 @@ import org.apache.commons.math.linear.decomposition.SingularMatrixException;
|
|||
* is 0-based -- e.g., <code>getEntry(0, 0)</code>
|
||||
* returns the element in the first row, first column of the matrix.</li></ul></p>
|
||||
*
|
||||
* @deprecated as of 2.0, replaced by {@link FieldMatrixImpl} with a {@link
|
||||
* org.apache.commons.math.util.BigReal} parameter
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
@Deprecated
|
||||
public class BigMatrixImpl implements BigMatrix, Serializable {
|
||||
|
||||
/** Serialization id */
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link FieldMatrixChangingVisitor} interface.
|
||||
* <p>
|
||||
* This class is a convenience to create custom visitors without defining all
|
||||
* methods. This class provides default implementations that do nothing.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultFieldMatrixChangingVisitor<T extends FieldElement<T>>
|
||||
implements FieldMatrixChangingVisitor<T> {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -7138694000397476118L;
|
||||
|
||||
/** Zero element of the field. */
|
||||
private final T zero;
|
||||
|
||||
/** Build a new instance.
|
||||
* @param zero additive identity of the field
|
||||
*/
|
||||
public DefaultFieldMatrixChangingVisitor(final T zero) {
|
||||
this.zero = zero;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void start(int rows, int columns,
|
||||
int startRow, int endRow, int startColumn, int endColumn) {
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T visit(int row, int column, T value)
|
||||
throws MatrixVisitorException {
|
||||
return value;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T end() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link FieldMatrixPreservingVisitor} interface.
|
||||
* <p>
|
||||
* This class is a convenience to create custom visitors without defining all
|
||||
* methods. This class provides default implementations that do nothing.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultFieldMatrixPreservingVisitor<T extends FieldElement<T>>
|
||||
implements FieldMatrixPreservingVisitor<T> {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 7998898965168636198L;
|
||||
|
||||
/** Zero element of the field. */
|
||||
private final T zero;
|
||||
|
||||
/** Build a new instance.
|
||||
* @param zero additive identity of the field
|
||||
*/
|
||||
public DefaultFieldMatrixPreservingVisitor(final T zero) {
|
||||
this.zero = zero;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void start(int rows, int columns,
|
||||
int startRow, int endRow, int startColumn, int endColumn) {
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void visit(int row, int column, T value)
|
||||
throws MatrixVisitorException {
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T end() {
|
||||
return zero;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,819 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.linear.decomposition.NonSquareMatrixException;
|
||||
|
||||
/**
|
||||
* Interface defining field-valued matrix with basic algebraic operations.
|
||||
* <p>
|
||||
* Matrix element indexing is 0-based -- e.g., <code>getEntry(0, 0)</code>
|
||||
* returns the element in the first row, first column of the matrix.</p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public interface FieldMatrix<T extends FieldElement<T>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Get the type of field elements of the matrix.
|
||||
* @return type of field elements of the matrix
|
||||
*/
|
||||
Field<T> getField();
|
||||
|
||||
/**
|
||||
* Create a new FieldMatrix<T> of the same type as the instance with the supplied
|
||||
* row and column dimensions.
|
||||
*
|
||||
* @param rowDimension the number of rows in the new matrix
|
||||
* @param columnDimension the number of columns in the new matrix
|
||||
* @return a new matrix of the same type as the instance
|
||||
* @throws IllegalArgumentException if row or column dimension is not positive
|
||||
* @since 2.0
|
||||
*/
|
||||
FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension);
|
||||
|
||||
/**
|
||||
* Returns a (deep) copy of this.
|
||||
*
|
||||
* @return matrix copy
|
||||
*/
|
||||
FieldMatrix<T> copy();
|
||||
|
||||
/**
|
||||
* Compute the sum of this and m.
|
||||
*
|
||||
* @param m matrix to be added
|
||||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute this minus m.
|
||||
*
|
||||
* @param m matrix to be subtracted
|
||||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
FieldMatrix<T> subtract(FieldMatrix<T> m) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the result of adding d to each entry of this.
|
||||
*
|
||||
* @param d value to be added to each entry
|
||||
* @return d + this
|
||||
*/
|
||||
FieldMatrix<T> scalarAdd(T d);
|
||||
|
||||
/**
|
||||
* Returns the result multiplying each entry of this by d.
|
||||
*
|
||||
* @param d value to multiply all entries by
|
||||
* @return d * this
|
||||
*/
|
||||
FieldMatrix<T> scalarMultiply(T d);
|
||||
|
||||
/**
|
||||
* Returns the result of postmultiplying this by m.
|
||||
*
|
||||
* @param m matrix to postmultiply by
|
||||
* @return this * m
|
||||
* @throws IllegalArgumentException
|
||||
* if columnDimension(this) != rowDimension(m)
|
||||
*/
|
||||
FieldMatrix<T> multiply(FieldMatrix<T> m) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the result premultiplying this by <code>m</code>.
|
||||
* @param m matrix to premultiply by
|
||||
* @return m * this
|
||||
* @throws IllegalArgumentException
|
||||
* if rowDimension(this) != columnDimension(m)
|
||||
*/
|
||||
public FieldMatrix<T> preMultiply(FieldMatrix<T> m) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns matrix entries as a two-dimensional array.
|
||||
*
|
||||
* @return 2-dimensional array of entries
|
||||
*/
|
||||
T[][] getData();
|
||||
|
||||
/**
|
||||
* Gets a submatrix. Rows and columns are indicated
|
||||
* counting from 0 to n-1.
|
||||
*
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
* @return The subMatrix containing the data of the
|
||||
* specified rows and columns
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
*/
|
||||
FieldMatrix<T> getSubMatrix(int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Gets a submatrix. Rows and columns are indicated
|
||||
* counting from 0 to n-1.
|
||||
*
|
||||
* @param selectedRows Array of row indices.
|
||||
* @param selectedColumns Array of column indices.
|
||||
* @return The subMatrix containing the data in the
|
||||
* specified rows and columns
|
||||
* @exception MatrixIndexException if row or column selections are not valid
|
||||
*/
|
||||
FieldMatrix<T> getSubMatrix(int[] selectedRows, int[] selectedColumns)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Copy a submatrix. Rows and columns are indicated
|
||||
* counting from 0 to n-1.
|
||||
*
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
* @param destination The arrays where the submatrix data should be copied
|
||||
* (if larger than rows/columns counts, only the upper-left part will be used)
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @exception IllegalArgumentException if the destination array is too small
|
||||
*/
|
||||
void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
|
||||
T[][] destination)
|
||||
throws MatrixIndexException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Copy a submatrix. Rows and columns are indicated
|
||||
* counting from 0 to n-1.
|
||||
*
|
||||
* @param selectedRows Array of row indices.
|
||||
* @param selectedColumns Array of column indices.
|
||||
* @param destination The arrays where the submatrix data should be copied
|
||||
* (if larger than rows/columns counts, only the upper-left part will be used)
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @exception IllegalArgumentException if the destination array is too small
|
||||
*/
|
||||
void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination)
|
||||
throws MatrixIndexException, IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Replace the submatrix starting at <code>row, column</code> using data in
|
||||
* the input <code>subMatrix</code> array. Indexes are 0-based.
|
||||
* <p>
|
||||
* Example:<br>
|
||||
* Starting with <pre>
|
||||
* 1 2 3 4
|
||||
* 5 6 7 8
|
||||
* 9 0 1 2
|
||||
* </pre>
|
||||
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
|
||||
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
|
||||
* 1 2 3 4
|
||||
* 5 3 4 8
|
||||
* 9 5 6 2
|
||||
* </pre></p>
|
||||
*
|
||||
* @param subMatrix array containing the submatrix replacement data
|
||||
* @param row row coordinate of the top, left element to be replaced
|
||||
* @param column column coordinate of the top, left element to be replaced
|
||||
* @throws MatrixIndexException if subMatrix does not fit into this
|
||||
* matrix from element in (row, column)
|
||||
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
|
||||
* (not all rows have the same length) or empty
|
||||
* @throws NullPointerException if <code>subMatrix</code> is null
|
||||
* @since 2.0
|
||||
*/
|
||||
void setSubMatrix(T[][] subMatrix, int row, int column)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the entries in row number <code>row</code>
|
||||
* as a row matrix. Row indices start at 0.
|
||||
*
|
||||
* @param row the row to be fetched
|
||||
* @return row matrix
|
||||
* @throws MatrixIndexException if the specified row index is invalid
|
||||
*/
|
||||
FieldMatrix<T> getRowMatrix(int row) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in row number <code>row</code>
|
||||
* as a row matrix. Row indices start at 0.
|
||||
*
|
||||
* @param row the row to be set
|
||||
* @param matrix row matrix (must have one row and the same number of columns
|
||||
* as the instance)
|
||||
* @throws MatrixIndexException if the specified row index is invalid
|
||||
* @throws InvalidMatrixException if the matrix dimensions do not match one
|
||||
* instance row
|
||||
*/
|
||||
void setRowMatrix(int row, FieldMatrix<T> matrix)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entries in column number <code>column</code>
|
||||
* as a column matrix. Column indices start at 0.
|
||||
*
|
||||
* @param column the column to be fetched
|
||||
* @return column matrix
|
||||
* @throws MatrixIndexException if the specified column index is invalid
|
||||
*/
|
||||
FieldMatrix<T> getColumnMatrix(int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in column number <code>column</code>
|
||||
* as a column matrix. Column indices start at 0.
|
||||
*
|
||||
* @param column the column to be set
|
||||
* @param matrix column matrix (must have one column and the same number of rows
|
||||
* as the instance)
|
||||
* @throws MatrixIndexException if the specified column index is invalid
|
||||
* @throws InvalidMatrixException if the matrix dimensions do not match one
|
||||
* instance column
|
||||
*/
|
||||
void setColumnMatrix(int column, FieldMatrix<T> matrix)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entries in row number <code>row</code>
|
||||
* as a vector. Row indices start at 0.
|
||||
*
|
||||
* @param row the row to be fetched
|
||||
* @return row vector
|
||||
* @throws MatrixIndexException if the specified row index is invalid
|
||||
*/
|
||||
FieldVector<T> getRowVector(int row) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in row number <code>row</code>
|
||||
* as a vector. Row indices start at 0.
|
||||
*
|
||||
* @param row the row to be set
|
||||
* @param vector row vector (must have the same number of columns
|
||||
* as the instance)
|
||||
* @throws MatrixIndexException if the specified row index is invalid
|
||||
* @throws InvalidMatrixException if the vector dimension does not match one
|
||||
* instance row
|
||||
*/
|
||||
void setRowVector(int row, FieldVector<T> vector)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entries in column number <code>column</code>
|
||||
* as a vector. Column indices start at 0.
|
||||
*
|
||||
* @param column the column to be fetched
|
||||
* @return column vector
|
||||
* @throws MatrixIndexException if the specified column index is invalid
|
||||
*/
|
||||
FieldVector<T> getColumnVector(int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in column number <code>column</code>
|
||||
* as a vector. Column indices start at 0.
|
||||
*
|
||||
* @param column the column to be set
|
||||
* @param vector column vector (must have the same number of rows as the instance)
|
||||
* @throws MatrixIndexException if the specified column index is invalid
|
||||
* @throws InvalidMatrixException if the vector dimension does not match one
|
||||
* instance column
|
||||
*/
|
||||
void setColumnVector(int column, FieldVector<T> vector)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entries in row number <code>row</code> as an array.
|
||||
* <p>
|
||||
* Row indices start at 0. A <code>MatrixIndexException</code> is thrown
|
||||
* unless <code>0 <= row < rowDimension.</code></p>
|
||||
*
|
||||
* @param row the row to be fetched
|
||||
* @return array of entries in the row
|
||||
* @throws MatrixIndexException if the specified row index is not valid
|
||||
*/
|
||||
T[] getRow(int row) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in row number <code>row</code>
|
||||
* as a row matrix. Row indices start at 0.
|
||||
*
|
||||
* @param row the row to be set
|
||||
* @param array row matrix (must have the same number of columns as the instance)
|
||||
* @throws MatrixIndexException if the specified row index is invalid
|
||||
* @throws InvalidMatrixException if the array size does not match one
|
||||
* instance row
|
||||
*/
|
||||
void setRow(int row, T[] array)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entries in column number <code>col</code> as an array.
|
||||
* <p>
|
||||
* Column indices start at 0. A <code>MatrixIndexException</code> is thrown
|
||||
* unless <code>0 <= column < columnDimension.</code></p>
|
||||
*
|
||||
* @param column the column to be fetched
|
||||
* @return array of entries in the column
|
||||
* @throws MatrixIndexException if the specified column index is not valid
|
||||
*/
|
||||
T[] getColumn(int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Sets the entries in column number <code>column</code>
|
||||
* as a column matrix. Column indices start at 0.
|
||||
*
|
||||
* @param column the column to be set
|
||||
* @param array column array (must have the same number of rows as the instance)
|
||||
* @throws MatrixIndexException if the specified column index is invalid
|
||||
* @throws InvalidMatrixException if the array size does not match one
|
||||
* instance column
|
||||
*/
|
||||
void setColumn(int column, T[] array)
|
||||
throws MatrixIndexException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the entry in the specified row and column.
|
||||
* <p>
|
||||
* Row and column indices start at 0 and must satisfy
|
||||
* <ul>
|
||||
* <li><code>0 <= row < rowDimension</code></li>
|
||||
* <li><code> 0 <= column < columnDimension</code></li>
|
||||
* </ul>
|
||||
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
|
||||
*
|
||||
* @param row row location of entry to be fetched
|
||||
* @param column column location of entry to be fetched
|
||||
* @return matrix entry in row,column
|
||||
* @throws MatrixIndexException if the row or column index is not valid
|
||||
*/
|
||||
T getEntry(int row, int column) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set the entry in the specified row and column.
|
||||
* <p>
|
||||
* Row and column indices start at 0 and must satisfy
|
||||
* <ul>
|
||||
* <li><code>0 <= row < rowDimension</code></li>
|
||||
* <li><code> 0 <= column < columnDimension</code></li>
|
||||
* </ul>
|
||||
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
|
||||
*
|
||||
* @param row row location of entry to be set
|
||||
* @param column column location of entry to be set
|
||||
* @param value matrix entry to be set in row,column
|
||||
* @throws MatrixIndexException if the row or column index is not valid
|
||||
* @since 2.0
|
||||
*/
|
||||
void setEntry(int row, int column, T value) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Change an entry in the specified row and column.
|
||||
* <p>
|
||||
* Row and column indices start at 0 and must satisfy
|
||||
* <ul>
|
||||
* <li><code>0 <= row < rowDimension</code></li>
|
||||
* <li><code> 0 <= column < columnDimension</code></li>
|
||||
* </ul>
|
||||
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
|
||||
*
|
||||
* @param row row location of entry to be set
|
||||
* @param column column location of entry to be set
|
||||
* @param increment value to add to the current matrix entry in row,column
|
||||
* @throws MatrixIndexException if the row or column index is not valid
|
||||
* @since 2.0
|
||||
*/
|
||||
void addToEntry(int row, int column, T increment) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Change an entry in the specified row and column.
|
||||
* <p>
|
||||
* Row and column indices start at 0 and must satisfy
|
||||
* <ul>
|
||||
* <li><code>0 <= row < rowDimension</code></li>
|
||||
* <li><code> 0 <= column < columnDimension</code></li>
|
||||
* </ul>
|
||||
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
|
||||
*
|
||||
* @param row row location of entry to be set
|
||||
* @param column column location of entry to be set
|
||||
* @param factor multiplication factor for the current matrix entry in row,column
|
||||
* @throws MatrixIndexException if the row or column index is not valid
|
||||
* @since 2.0
|
||||
*/
|
||||
void multiplyEntry(int row, int column, T factor) throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the transpose of this matrix.
|
||||
*
|
||||
* @return transpose matrix
|
||||
*/
|
||||
FieldMatrix<T> transpose();
|
||||
|
||||
/**
|
||||
* Is this a square matrix?
|
||||
* @return true if the matrix is square (rowDimension = columnDimension)
|
||||
*/
|
||||
boolean isSquare();
|
||||
|
||||
/**
|
||||
* Returns the number of rows in the matrix.
|
||||
*
|
||||
* @return rowDimension
|
||||
*/
|
||||
int getRowDimension();
|
||||
|
||||
/**
|
||||
* Returns the number of columns in the matrix.
|
||||
*
|
||||
* @return columnDimension
|
||||
*/
|
||||
int getColumnDimension();
|
||||
|
||||
/**
|
||||
* Returns the <a href="http://mathworld.wolfram.com/MatrixTrace.html">
|
||||
* trace</a> of the matrix (the sum of the elements on the main diagonal).
|
||||
*
|
||||
* @return trace
|
||||
* @throws NonSquareMatrixException if the matrix is not square
|
||||
*/
|
||||
T getTrace() throws NonSquareMatrixException;
|
||||
|
||||
/**
|
||||
* Returns the result of multiplying this by the vector <code>v</code>.
|
||||
*
|
||||
* @param v the vector to operate on
|
||||
* @return this*v
|
||||
* @throws IllegalArgumentException if columnDimension != v.size()
|
||||
*/
|
||||
T[] operate(T[] v) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the result of multiplying this by the vector <code>v</code>.
|
||||
*
|
||||
* @param v the vector to operate on
|
||||
* @return this*v
|
||||
* @throws IllegalArgumentException if columnDimension != v.size()
|
||||
*/
|
||||
FieldVector<T> operate(FieldVector<T> v) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
|
||||
*
|
||||
* @param v the row vector to premultiply by
|
||||
* @return v*this
|
||||
* @throws IllegalArgumentException if rowDimension != v.size()
|
||||
*/
|
||||
T[] preMultiply(T[] v) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the (row) vector result of premultiplying this by the vector <code>v</code>.
|
||||
*
|
||||
* @param v the row vector to premultiply by
|
||||
* @return v*this
|
||||
* @throws IllegalArgumentException if rowDimension != v.size()
|
||||
*/
|
||||
FieldVector<T> preMultiply(FieldVector<T> v) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) all matrix entries in row order.
|
||||
* <p>Row order starts at upper left and iterating through all elements
|
||||
* of a row from left to right before going to the leftmost element
|
||||
* of the next row.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) all matrix entries in row order.
|
||||
* <p>Row order starts at upper left and iterating through all elements
|
||||
* of a row from left to right before going to the leftmost element
|
||||
* of the next row.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) some matrix entries in row order.
|
||||
* <p>Row order starts at upper left and iterating through all elements
|
||||
* of a row from left to right before going to the leftmost element
|
||||
* of the next row.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInRowOrder(FieldMatrixChangingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) some matrix entries in row order.
|
||||
* <p>Row order starts at upper left and iterating through all elements
|
||||
* of a row from left to right before going to the leftmost element
|
||||
* of the next row.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInRowOrder(FieldMatrixPreservingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) all matrix entries in column order.
|
||||
* <p>Column order starts at upper left and iterating through all elements
|
||||
* of a column from top to bottom before going to the topmost element
|
||||
* of the next column.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) all matrix entries in column order.
|
||||
* <p>Column order starts at upper left and iterating through all elements
|
||||
* of a column from top to bottom before going to the topmost element
|
||||
* of the next column.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) some matrix entries in column order.
|
||||
* <p>Column order starts at upper left and iterating through all elements
|
||||
* of a column from top to bottom before going to the topmost element
|
||||
* of the next column.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInColumnOrder(FieldMatrixChangingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) some matrix entries in column order.
|
||||
* <p>Column order starts at upper left and iterating through all elements
|
||||
* of a column from top to bottom before going to the topmost element
|
||||
* of the next column.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInColumnOrder(FieldMatrixPreservingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) all matrix entries using the fastest possible order.
|
||||
* <p>The fastest walking order depends on the exact matrix class. It may be
|
||||
* different from traditional row or column orders.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) all matrix entries using the fastest possible order.
|
||||
* <p>The fastest walking order depends on the exact matrix class. It may be
|
||||
* different from traditional row or column orders.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (and possibly change) some matrix entries using the fastest possible order.
|
||||
* <p>The fastest walking order depends on the exact matrix class. It may be
|
||||
* different from traditional row or column orders.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixChangingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInOptimizedOrder(FieldMatrixChangingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* Visit (but don't change) some matrix entries using the fastest possible order.
|
||||
* <p>The fastest walking order depends on the exact matrix class. It may be
|
||||
* different from traditional row or column orders.</p>
|
||||
* @param visitor visitor used to process all matrix entries
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
* @exception MatrixVisitorException if the visitor cannot process an entry
|
||||
* @exception MatrixIndexException if the indices are not valid
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInRowOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInRowOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInColumnOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @see #walkInColumnOrder(FieldMatrixPreservingVisitor, int, int, int, int)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixPreservingVisitor)
|
||||
* @see #walkInOptimizedOrder(FieldMatrixChangingVisitor, int, int, int, int)
|
||||
* @return the value returned by {@link FieldMatrixPreservingVisitor#end()} at the end
|
||||
* of the walk
|
||||
*/
|
||||
T walkInOptimizedOrder(FieldMatrixPreservingVisitor<T> visitor,
|
||||
int startRow, int endRow, int startColumn, int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException;
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
|
||||
/**
|
||||
* Interface defining a visitor for matrix entries.
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface FieldMatrixChangingVisitor<T extends FieldElement<?>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Start visiting a matrix.
|
||||
* <p>This method is called once before any entry of the matrix is visited.</p>
|
||||
* @param rows number of rows of the matrix
|
||||
* @param columns number of columns of the matrix
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
*/
|
||||
void start(int rows, int columns,
|
||||
int startRow, int endRow, int startColumn, int endColumn);
|
||||
|
||||
/**
|
||||
* Visit one matrix entry.
|
||||
* @param row row index of the entry
|
||||
* @param column column index of the entry
|
||||
* @param value current value of the entry
|
||||
* @return the new value to be set for the entry
|
||||
* @throws MatrixVisitorException if something wrong occurs
|
||||
*/
|
||||
T visit(int row, int column, T value)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* End visiting a matrix.
|
||||
* <p>This method is called once after all entries of the matrix have been visited.</p>
|
||||
* @return the value that the <code>walkInXxxOrder</code> must return
|
||||
*/
|
||||
T end();
|
||||
|
||||
}
|
|
@ -0,0 +1,655 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
|
||||
/**
|
||||
* Implementation of FieldMatrix<T> using a {@link FieldElement}[][] array to store entries.
|
||||
* <p>
|
||||
* As specified in the {@link FieldMatrix} interface, matrix element indexing
|
||||
* is 0-based -- e.g., <code>getEntry(0, 0)</code>
|
||||
* returns the element in the first row, first column of the matrix.</li></ul>
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class FieldMatrixImpl<T extends FieldElement<T>> extends AbstractFieldMatrix<T> {
|
||||
|
||||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = 7260756672015356458L;
|
||||
|
||||
/** Entries of the matrix */
|
||||
protected T[][] data;
|
||||
|
||||
/**
|
||||
* Get the elements type from an array.
|
||||
* @param d data array
|
||||
* @return field to which array elements belong
|
||||
* @exception IllegalArgumentException if array is empty
|
||||
*/
|
||||
private static Field<? extends FieldElement<?>> extractField(final FieldElement<? extends FieldElement<?>>[][] d)
|
||||
throws IllegalArgumentException {
|
||||
if (d.length == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
|
||||
}
|
||||
if (d[0].length == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column");
|
||||
}
|
||||
return d[0][0].getField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elements type from an array.
|
||||
* @param d data array
|
||||
* @return field to which array elements belong
|
||||
* @exception IllegalArgumentException if array is empty
|
||||
*/
|
||||
private static Field<? extends FieldElement<?>> extractField(final FieldElement<? extends FieldElement<?>>[] d)
|
||||
throws IllegalArgumentException {
|
||||
if (d.length == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
|
||||
}
|
||||
return d[0].getField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a matrix with no data
|
||||
* @param field field to which the elements belong
|
||||
*/
|
||||
public FieldMatrixImpl(final Field<T> field) {
|
||||
super(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FieldMatrix<T> with the supplied row and column dimensions.
|
||||
*
|
||||
* @param field field to which the elements belong
|
||||
* @param rowDimension the number of rows in the new matrix
|
||||
* @param columnDimension the number of columns in the new matrix
|
||||
* @throws IllegalArgumentException if row or column dimension is not
|
||||
* positive
|
||||
*/
|
||||
public FieldMatrixImpl(final Field<T> field,
|
||||
final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException {
|
||||
super(field, rowDimension, columnDimension);
|
||||
data = buildArray(rowDimension, columnDimension);
|
||||
final T zero = field.getZero();
|
||||
for (int i = 0; i < rowDimension; ++i) {
|
||||
Arrays.fill(data[i], zero);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FieldMatrix<T> using the input array as the underlying
|
||||
* data array.
|
||||
* <p>The input array is copied, not referenced. This constructor has
|
||||
* the same effect as calling {@link #FieldMatrixImpl(T[][], boolean)}
|
||||
* with the second argument set to <code>true</code>.</p>
|
||||
*
|
||||
* @param d data for new matrix
|
||||
* @throws IllegalArgumentException if <code>d</code> is not rectangular
|
||||
* (not all rows have the same length) or empty
|
||||
* @throws NullPointerException if <code>d</code> is null
|
||||
* @see #FieldMatrixImpl(T[][], boolean)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public FieldMatrixImpl(final T[][] d)
|
||||
throws IllegalArgumentException, NullPointerException {
|
||||
super((Field<T>) extractField(d));
|
||||
copyIn(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FieldMatrix<T> using the input array as the underlying
|
||||
* data array.
|
||||
* <p>If an array is built specially in order to be embedded in a
|
||||
* FieldMatrix<T> and not used directly, the <code>copyArray</code> may be
|
||||
* set to <code>false</code. This will prevent the copying and improve
|
||||
* performance as no new array will be built and no data will be copied.</p>
|
||||
* @param d data for new matrix
|
||||
* @param copyArray if true, the input array will be copied, otherwise
|
||||
* it will be referenced
|
||||
* @throws IllegalArgumentException if <code>d</code> is not rectangular
|
||||
* (not all rows have the same length) or empty
|
||||
* @throws NullPointerException if <code>d</code> is null
|
||||
* @see #FieldMatrixImpl(T[][])
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public FieldMatrixImpl(final T[][] d, final boolean copyArray)
|
||||
throws IllegalArgumentException, NullPointerException {
|
||||
super((Field<T>) extractField(d));
|
||||
if (copyArray) {
|
||||
copyIn(d);
|
||||
} else {
|
||||
if (d == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
final int nRows = d.length;
|
||||
if (nRows == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
|
||||
}
|
||||
final int nCols = d[0].length;
|
||||
if (nCols == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column");
|
||||
}
|
||||
for (int r = 1; r < nRows; r++) {
|
||||
if (d[r].length != nCols) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"some rows have length {0} while others have length {1}",
|
||||
nCols, d[r].length);
|
||||
}
|
||||
}
|
||||
data = d;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new (column) FieldMatrix<T> using <code>v</code> as the
|
||||
* data for the unique column of the <code>v.length x 1</code> matrix
|
||||
* created.
|
||||
* <p>The input array is copied, not referenced.</p>
|
||||
*
|
||||
* @param v column vector holding data for new matrix
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public FieldMatrixImpl(final T[] v) {
|
||||
super((Field<T>) extractField(v));
|
||||
final int nRows = v.length;
|
||||
data = buildArray(nRows, 1);
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
data[row][0] = v[row];
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension)
|
||||
throws IllegalArgumentException {
|
||||
return new FieldMatrixImpl<T>(getField(), rowDimension, columnDimension);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public FieldMatrix<T> copy() {
|
||||
return new FieldMatrixImpl<T>(copyOut(), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public FieldMatrix<T> add(final FieldMatrix<T> m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return add((FieldMatrixImpl<T>) m);
|
||||
} catch (ClassCastException cce) {
|
||||
return super.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the sum of this and <code>m</code>.
|
||||
*
|
||||
* @param m matrix to be added
|
||||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
public FieldMatrixImpl<T> add(final FieldMatrixImpl<T> m)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
// safety check
|
||||
checkAdditionCompatible(m);
|
||||
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final T[][] outData = buildArray(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final T[] dataRow = data[row];
|
||||
final T[] mRow = m.data[row];
|
||||
final T[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col].add(mRow[col]);
|
||||
}
|
||||
}
|
||||
|
||||
return new FieldMatrixImpl<T>(outData, false);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public FieldMatrix<T> subtract(final FieldMatrix<T> m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return subtract((FieldMatrixImpl<T>) m);
|
||||
} catch (ClassCastException cce) {
|
||||
return super.subtract(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute this minus <code>m</code>.
|
||||
*
|
||||
* @param m matrix to be subtracted
|
||||
* @return this + m
|
||||
* @throws IllegalArgumentException if m is not the same size as this
|
||||
*/
|
||||
public FieldMatrixImpl<T> subtract(final FieldMatrixImpl<T> m)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
// safety check
|
||||
checkSubtractionCompatible(m);
|
||||
|
||||
final int rowCount = getRowDimension();
|
||||
final int columnCount = getColumnDimension();
|
||||
final T[][] outData = buildArray(rowCount, columnCount);
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
final T[] dataRow = data[row];
|
||||
final T[] mRow = m.data[row];
|
||||
final T[] outDataRow = outData[row];
|
||||
for (int col = 0; col < columnCount; col++) {
|
||||
outDataRow[col] = dataRow[col].subtract(mRow[col]);
|
||||
}
|
||||
}
|
||||
|
||||
return new FieldMatrixImpl<T>(outData, false);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public FieldMatrix<T> multiply(final FieldMatrix<T> m)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return multiply((FieldMatrixImpl<T>) m);
|
||||
} catch (ClassCastException cce) {
|
||||
return super.multiply(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of postmultiplying this by <code>m</code>.
|
||||
* @param m matrix to postmultiply by
|
||||
* @return this*m
|
||||
* @throws IllegalArgumentException
|
||||
* if columnDimension(this) != rowDimension(m)
|
||||
*/
|
||||
public FieldMatrixImpl<T> multiply(final FieldMatrixImpl<T> m)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
// safety check
|
||||
checkMultiplicationCompatible(m);
|
||||
|
||||
final int nRows = this.getRowDimension();
|
||||
final int nCols = m.getColumnDimension();
|
||||
final int nSum = this.getColumnDimension();
|
||||
final T[][] outData = buildArray(nRows, nCols);
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final T[] dataRow = data[row];
|
||||
final T[] outDataRow = outData[row];
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
T sum = getField().getZero();
|
||||
for (int i = 0; i < nSum; i++) {
|
||||
sum = sum.add(dataRow[i].multiply(m.data[i][col]));
|
||||
}
|
||||
outDataRow[col] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return new FieldMatrixImpl<T>(outData, false);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T[][] getData() {
|
||||
return copyOut();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the underlying data array.
|
||||
* <p>
|
||||
* Does <strong>not</strong> make a fresh copy of the underlying data.</p>
|
||||
*
|
||||
* @return 2-dimensional array of entries
|
||||
*/
|
||||
public T[][] getDataRef() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setSubMatrix(final T[][] subMatrix, final int row, final int column)
|
||||
throws MatrixIndexException {
|
||||
if (data == null) {
|
||||
if (row > 0) {
|
||||
throw MathRuntimeException.createIllegalStateException(
|
||||
"first {0} rows are not initialized yet",
|
||||
row);
|
||||
}
|
||||
if (column > 0) {
|
||||
throw MathRuntimeException.createIllegalStateException(
|
||||
"first {0} columns are not initialized yet",
|
||||
column);
|
||||
}
|
||||
final int nRows = subMatrix.length;
|
||||
if (nRows == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one row");
|
||||
}
|
||||
|
||||
final int nCols = subMatrix[0].length;
|
||||
if (nCols == 0) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("matrix must have at least one column");
|
||||
}
|
||||
data = buildArray(subMatrix.length, nCols);
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
if (subMatrix[i].length != nCols) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"some rows have length {0} while others have length {1}",
|
||||
nCols, subMatrix[i].length);
|
||||
}
|
||||
System.arraycopy(subMatrix[i], 0, data[i + row], column, nCols);
|
||||
}
|
||||
} else {
|
||||
super.setSubMatrix(subMatrix, row, column);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T getEntry(final int row, final int column)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
return data[row][column];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new MatrixIndexException(
|
||||
"no entry at indices ({0}, {1}) in a {2}x{3} matrix",
|
||||
row, column, getRowDimension(), getColumnDimension());
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setEntry(final int row, final int column, final T value)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
data[row][column] = value;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new MatrixIndexException(
|
||||
"no entry at indices ({0}, {1}) in a {2}x{3} matrix",
|
||||
row, column, getRowDimension(), getColumnDimension());
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void addToEntry(final int row, final int column, final T increment)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
data[row][column] = data[row][column].add(increment);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new MatrixIndexException(
|
||||
"no entry at indices ({0}, {1}) in a {2}x{3} matrix",
|
||||
row, column, getRowDimension(), getColumnDimension());
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void multiplyEntry(final int row, final int column, final T factor)
|
||||
throws MatrixIndexException {
|
||||
try {
|
||||
data[row][column] = data[row][column].multiply(factor);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new MatrixIndexException(
|
||||
"no entry at indices ({0}, {1}) in a {2}x{3} matrix",
|
||||
row, column, getRowDimension(), getColumnDimension());
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int getRowDimension() {
|
||||
return (data == null) ? 0 : data.length;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public int getColumnDimension() {
|
||||
return ((data == null) || (data[0] == null)) ? 0 : data[0].length;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T[] operate(final T[] v)
|
||||
throws IllegalArgumentException {
|
||||
final int nRows = this.getRowDimension();
|
||||
final int nCols = this.getColumnDimension();
|
||||
if (v.length != nCols) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector length mismatch: got {0} but expected {1}",
|
||||
v.length, nCols);
|
||||
}
|
||||
final T[] out = buildArray(nRows);
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
final T[] dataRow = data[row];
|
||||
T sum = getField().getZero();
|
||||
for (int i = 0; i < nCols; i++) {
|
||||
sum = sum.add(dataRow[i].multiply(v[i]));
|
||||
}
|
||||
out[row] = sum;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T[] preMultiply(final T[] v)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
final int nRows = getRowDimension();
|
||||
final int nCols = getColumnDimension();
|
||||
if (v.length != nRows) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector length mismatch: got {0} but expected {1}",
|
||||
v.length, nRows);
|
||||
}
|
||||
|
||||
final T[] out = buildArray(nCols);
|
||||
for (int col = 0; col < nCols; ++col) {
|
||||
T sum = getField().getZero();
|
||||
for (int i = 0; i < nRows; ++i) {
|
||||
sum = sum.add(data[i][col].multiply(v[i]));
|
||||
}
|
||||
out[col] = sum;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor)
|
||||
throws MatrixVisitorException {
|
||||
final int rows = getRowDimension();
|
||||
final int columns = getColumnDimension();
|
||||
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
for (int j = 0; j < columns; ++j) {
|
||||
rowI[j] = visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor)
|
||||
throws MatrixVisitorException {
|
||||
final int rows = getRowDimension();
|
||||
final int columns = getColumnDimension();
|
||||
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
for (int j = 0; j < columns; ++j) {
|
||||
visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
|
||||
final int startRow, final int endRow,
|
||||
final int startColumn, final int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException {
|
||||
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
|
||||
visitor.start(getRowDimension(), getColumnDimension(),
|
||||
startRow, endRow, startColumn, endColumn);
|
||||
for (int i = startRow; i <= endRow; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
for (int j = startColumn; j <= endColumn; ++j) {
|
||||
rowI[j] = visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
|
||||
final int startRow, final int endRow,
|
||||
final int startColumn, final int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException {
|
||||
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
|
||||
visitor.start(getRowDimension(), getColumnDimension(),
|
||||
startRow, endRow, startColumn, endColumn);
|
||||
for (int i = startRow; i <= endRow; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
for (int j = startColumn; j <= endColumn; ++j) {
|
||||
visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor)
|
||||
throws MatrixVisitorException {
|
||||
final int rows = getRowDimension();
|
||||
final int columns = getColumnDimension();
|
||||
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
|
||||
for (int j = 0; j < columns; ++j) {
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
rowI[j] = visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor)
|
||||
throws MatrixVisitorException {
|
||||
final int rows = getRowDimension();
|
||||
final int columns = getColumnDimension();
|
||||
visitor.start(rows, columns, 0, rows - 1, 0, columns - 1);
|
||||
for (int j = 0; j < columns; ++j) {
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
visitor.visit(i, j, data[i][j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInColumnOrder(final FieldMatrixChangingVisitor<T> visitor,
|
||||
final int startRow, final int endRow,
|
||||
final int startColumn, final int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException {
|
||||
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
|
||||
visitor.start(getRowDimension(), getColumnDimension(),
|
||||
startRow, endRow, startColumn, endColumn);
|
||||
for (int j = startColumn; j <= endColumn; ++j) {
|
||||
for (int i = startRow; i <= endRow; ++i) {
|
||||
final T[] rowI = data[i];
|
||||
rowI[j] = visitor.visit(i, j, rowI[j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public T walkInColumnOrder(final FieldMatrixPreservingVisitor<T> visitor,
|
||||
final int startRow, final int endRow,
|
||||
final int startColumn, final int endColumn)
|
||||
throws MatrixIndexException, MatrixVisitorException {
|
||||
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
|
||||
visitor.start(getRowDimension(), getColumnDimension(),
|
||||
startRow, endRow, startColumn, endColumn);
|
||||
for (int j = startColumn; j <= endColumn; ++j) {
|
||||
for (int i = startRow; i <= endRow; ++i) {
|
||||
visitor.visit(i, j, data[i][j]);
|
||||
}
|
||||
}
|
||||
return visitor.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fresh copy of the underlying data array.
|
||||
*
|
||||
* @return a copy of the underlying data array.
|
||||
*/
|
||||
private T[][] copyOut() {
|
||||
final int nRows = this.getRowDimension();
|
||||
final T[][] out = buildArray(nRows, getColumnDimension());
|
||||
// can't copy 2-d array in one shot, otherwise get row references
|
||||
for (int i = 0; i < nRows; i++) {
|
||||
System.arraycopy(data[i], 0, out[i], 0, data[i].length);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces data with a fresh copy of the input array.
|
||||
* <p>
|
||||
* Verifies that the input array is rectangular and non-empty.</p>
|
||||
*
|
||||
* @param in data to copy in
|
||||
* @throws IllegalArgumentException if input array is empty or not
|
||||
* rectangular
|
||||
* @throws NullPointerException if input array is null
|
||||
*/
|
||||
private void copyIn(final T[][] in) {
|
||||
setSubMatrix(in, 0, 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
|
||||
/**
|
||||
* Interface defining a visitor for matrix entries.
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface FieldMatrixPreservingVisitor<T extends FieldElement<?>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Start visiting a matrix.
|
||||
* <p>This method is called once before any entry of the matrix is visited.</p>
|
||||
* @param rows number of rows of the matrix
|
||||
* @param columns number of columns of the matrix
|
||||
* @param startRow Initial row index
|
||||
* @param endRow Final row index (inclusive)
|
||||
* @param startColumn Initial column index
|
||||
* @param endColumn Final column index (inclusive)
|
||||
*/
|
||||
void start(int rows, int columns,
|
||||
int startRow, int endRow, int startColumn, int endColumn);
|
||||
|
||||
/**
|
||||
* Visit one matrix entry.
|
||||
* @param row row index of the entry
|
||||
* @param column column index of the entry
|
||||
* @param value current value of the entry
|
||||
* @throws MatrixVisitorException if something wrong occurs
|
||||
*/
|
||||
void visit(int row, int column, T value)
|
||||
throws MatrixVisitorException;
|
||||
|
||||
/**
|
||||
* End visiting a matrix.
|
||||
* <p>This method is called once after all entries of the matrix have been visited.</p>
|
||||
* @return the value that the <code>walkInXxxOrder</code> must return
|
||||
*/
|
||||
T end();
|
||||
|
||||
}
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
|
||||
/**
|
||||
* Interface defining a field-valued vector with basic algebraic operations.
|
||||
* <p>
|
||||
* vector element indexing is 0-based -- e.g., <code>getEntry(0)</code>
|
||||
* returns the first element of the vector.
|
||||
* </p>
|
||||
* <p>
|
||||
* The various <code>mapXxx</code> and <code>mapXxxToSelf</code> methods operate
|
||||
* on vectors element-wise, i.e. they perform the same operation (adding a scalar,
|
||||
* applying a function ...) on each element in turn. The <code>mapXxx</code>
|
||||
* versions create a new vector to hold the result and do not change the instance.
|
||||
* The <code>mapXxxToSelf</code> versions use the instance itself to store the
|
||||
* results, so the instance is changed by these methods. In both cases, the result
|
||||
* vector is returned by the methods, this allows to use the <i>fluent API</i>
|
||||
* style, like this:
|
||||
* </p>
|
||||
* <pre>
|
||||
* RealVector result = v.mapAddToSelf(3.0).mapTanToSelf().mapSquareToSelf();
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface FieldVector<T extends FieldElement<T>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Get the type of field elements of the vector.
|
||||
* @return type of field elements of the vector
|
||||
*/
|
||||
Field<T> getField();
|
||||
|
||||
/**
|
||||
* Returns a (deep) copy of this.
|
||||
* @return vector copy
|
||||
*/
|
||||
FieldVector<T> copy();
|
||||
|
||||
/**
|
||||
* Compute the sum of this and v.
|
||||
* @param v vector to be added
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> add(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute the sum of this and v.
|
||||
* @param v vector to be added
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> add(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute this minus v.
|
||||
* @param v vector to be subtracted
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> subtract(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute this minus v.
|
||||
* @param v vector to be subtracted
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> subtract(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Map an addition operation to each entry.
|
||||
* @param d value to be added to each entry
|
||||
* @return this + d
|
||||
*/
|
||||
FieldVector<T> mapAdd(T d);
|
||||
|
||||
/**
|
||||
* Map an addition operation to each entry.
|
||||
* <p>The instance <strong>is</strong> changed by this method.</p>
|
||||
* @param d value to be added to each entry
|
||||
* @return for convenience, return this
|
||||
*/
|
||||
FieldVector<T> mapAddToSelf(T d);
|
||||
|
||||
/**
|
||||
* Map a subtraction operation to each entry.
|
||||
* @param d value to be subtracted to each entry
|
||||
* @return this - d
|
||||
*/
|
||||
FieldVector<T> mapSubtract(T d);
|
||||
|
||||
/**
|
||||
* Map a subtraction operation to each entry.
|
||||
* <p>The instance <strong>is</strong> changed by this method.</p>
|
||||
* @param d value to be subtracted to each entry
|
||||
* @return for convenience, return this
|
||||
*/
|
||||
FieldVector<T> mapSubtractToSelf(T d);
|
||||
|
||||
/**
|
||||
* Map a multiplication operation to each entry.
|
||||
* @param d value to multiply all entries by
|
||||
* @return this * d
|
||||
*/
|
||||
FieldVector<T> mapMultiply(T d);
|
||||
|
||||
/**
|
||||
* Map a multiplication operation to each entry.
|
||||
* <p>The instance <strong>is</strong> changed by this method.</p>
|
||||
* @param d value to multiply all entries by
|
||||
* @return for convenience, return this
|
||||
*/
|
||||
FieldVector<T> mapMultiplyToSelf(T d);
|
||||
|
||||
/**
|
||||
* Map a division operation to each entry.
|
||||
* @param d value to divide all entries by
|
||||
* @return this / d
|
||||
*/
|
||||
FieldVector<T> mapDivide(T d);
|
||||
|
||||
/**
|
||||
* Map a division operation to each entry.
|
||||
* <p>The instance <strong>is</strong> changed by this method.</p>
|
||||
* @param d value to divide all entries by
|
||||
* @return for convenience, return this
|
||||
*/
|
||||
FieldVector<T> mapDivideToSelf(T d);
|
||||
|
||||
/**
|
||||
* Map the 1/x function to each entry.
|
||||
* @return a vector containing the result of applying the function to each entry
|
||||
*/
|
||||
FieldVector<T> mapInv();
|
||||
|
||||
/**
|
||||
* Map the 1/x function to each entry.
|
||||
* <p>The instance <strong>is</strong> changed by this method.</p>
|
||||
* @return for convenience, return this
|
||||
*/
|
||||
FieldVector<T> mapInvToSelf();
|
||||
|
||||
/**
|
||||
* Element-by-element multiplication.
|
||||
* @param v vector by which instance elements must be multiplied
|
||||
* @return a vector containing this[i] * v[i] for all i
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVector<T> ebeMultiply(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Element-by-element multiplication.
|
||||
* @param v vector by which instance elements must be multiplied
|
||||
* @return a vector containing this[i] * v[i] for all i
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVector<T> ebeMultiply(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Element-by-element division.
|
||||
* @param v vector by which instance elements must be divided
|
||||
* @return a vector containing this[i] / v[i] for all i
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVector<T> ebeDivide(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Element-by-element division.
|
||||
* @param v vector by which instance elements must be divided
|
||||
* @return a vector containing this[i] / v[i] for all i
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVector<T> ebeDivide(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns vector entries as a T array.
|
||||
* @return T array of entries
|
||||
*/
|
||||
T[] getData();
|
||||
|
||||
/**
|
||||
* Compute the dot product.
|
||||
* @param v vector with which dot product should be computed
|
||||
* @return the scalar dot product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
T dotProduct(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute the dot product.
|
||||
* @param v vector with which dot product should be computed
|
||||
* @return the scalar dot product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
T dotProduct(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/** Find the orthogonal projection of this vector onto another vector.
|
||||
* @param v vector onto which instance must be projected
|
||||
* @return projection of the instance onto v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> projection(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/** Find the orthogonal projection of this vector onto another vector.
|
||||
* @param v vector onto which instance must be projected
|
||||
* @return projection of the instance onto v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldVector<T> projection(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute the outer product.
|
||||
* @param v vector with which outer product should be computed
|
||||
* @return the square matrix outer product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldMatrix<T> outerProduct(FieldVector<T> v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Compute the outer product.
|
||||
* @param v vector with which outer product should be computed
|
||||
* @return the square matrix outer product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
FieldMatrix<T> outerProduct(T[] v)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Returns the entry in the specified index.
|
||||
* <p>
|
||||
* The index start at 0 and must be lesser than the size,
|
||||
* otherwise a {@link MatrixIndexException} is thrown.
|
||||
* </p>
|
||||
* @param index index location of entry to be fetched
|
||||
* @return vector entry at index
|
||||
* @throws MatrixIndexException if the index is not valid
|
||||
* @see #setEntry(int, T)
|
||||
*/
|
||||
T getEntry(int index)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set a single element.
|
||||
* @param index element index.
|
||||
* @param value new value for the element.
|
||||
* @exception MatrixIndexException if the index is
|
||||
* inconsistent with vector size
|
||||
* @see #getEntry(int)
|
||||
*/
|
||||
void setEntry(int index, T value)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Returns the size of the vector.
|
||||
* @return size
|
||||
*/
|
||||
int getDimension();
|
||||
|
||||
/**
|
||||
* Construct a vector by appending a vector to this vector.
|
||||
* @param v vector to append to this one.
|
||||
* @return a new vector
|
||||
*/
|
||||
FieldVector<T> append(FieldVector<T> v);
|
||||
|
||||
/**
|
||||
* Construct a vector by appending a T to this vector.
|
||||
* @param d T to append.
|
||||
* @return a new vector
|
||||
*/
|
||||
FieldVector<T> append(T d);
|
||||
|
||||
/**
|
||||
* Construct a vector by appending a T array to this vector.
|
||||
* @param a T array to append.
|
||||
* @return a new vector
|
||||
*/
|
||||
FieldVector<T> append(T[] a);
|
||||
|
||||
/**
|
||||
* Get a subvector from consecutive elements.
|
||||
* @param index index of first element.
|
||||
* @param n number of elements to be retrieved.
|
||||
* @return a vector containing n elements.
|
||||
* @exception MatrixIndexException if the index is
|
||||
* inconsistent with vector size
|
||||
*/
|
||||
FieldVector<T> getSubVector(int index, int n)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set a set of consecutive elements.
|
||||
* @param index index of first element to be set.
|
||||
* @param v vector containing the values to set.
|
||||
* @exception MatrixIndexException if the index is
|
||||
* inconsistent with vector size
|
||||
* @see #setSubVector(int, T[])
|
||||
*/
|
||||
void setSubVector(int index, FieldVector<T> v)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set a set of consecutive elements.
|
||||
* @param index index of first element to be set.
|
||||
* @param v vector containing the values to set.
|
||||
* @exception MatrixIndexException if the index is
|
||||
* inconsistent with vector size
|
||||
* @see #setSubVector(int, FieldVector)
|
||||
*/
|
||||
void setSubVector(int index, T[] v)
|
||||
throws MatrixIndexException;
|
||||
|
||||
/**
|
||||
* Set all elements to a single value.
|
||||
* @param value single value to set for all elements
|
||||
*/
|
||||
void set(T value);
|
||||
|
||||
/**
|
||||
* Convert the vector to a T array.
|
||||
* <p>The array is independent from vector data, it's elements
|
||||
* are copied.</p>
|
||||
* @return array containing a copy of vector elements
|
||||
*/
|
||||
T[] toArray();
|
||||
|
||||
}
|
|
@ -0,0 +1,802 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
|
||||
/**
|
||||
* This class implements the {@link FieldVector<T>} interface with a {@link FieldElement} array.
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FieldVectorImpl<T extends FieldElement<T>> implements FieldVector<T> {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 7648186910365927050L;
|
||||
|
||||
/** Field to which the elements belong. */
|
||||
private final Field<T> field;
|
||||
|
||||
/** Entries of the vector. */
|
||||
protected T[] data;
|
||||
|
||||
/** Build an array of elements.
|
||||
* @param length size of the array to build
|
||||
* @return a new array
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private T[] buildArray(final int length) {
|
||||
return (T[]) Array.newInstance(field.getZero().getClass(), length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a 0-length vector.
|
||||
* <p>Zero-length vectors may be used to initialized construction of vectors
|
||||
* by data gathering. We start with zero-length and use either the {@link
|
||||
* #FieldVectorImpl(FieldVectorImpl<T>, FieldVectorImpl<T>)} constructor
|
||||
* or one of the <code>append</code> method ({@link #append(double)}, {@link
|
||||
* #append(T[])}, {@link #append(FieldVectorImpl<T>)}) to gather data
|
||||
* into this vector.</p>
|
||||
* @param field field to which the elements belong
|
||||
*/
|
||||
public FieldVectorImpl(final Field<T> field) {
|
||||
this(field, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a (size)-length vector of zeros.
|
||||
* @param field field to which the elements belong
|
||||
* @param size size of the vector
|
||||
*/
|
||||
public FieldVectorImpl(Field<T> field, int size) {
|
||||
this.field = field;
|
||||
data = buildArray(size);
|
||||
Arrays.fill(data, field.getZero());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an (size)-length vector with preset values.
|
||||
* @param size size of the vector
|
||||
* @param preset fill the vector with this scalar value
|
||||
*/
|
||||
public FieldVectorImpl(int size, T preset) {
|
||||
this(preset.getField(), size);
|
||||
Arrays.fill(data, preset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector from an array, copying the input array.
|
||||
* @param d array of Ts.
|
||||
* @throws IllegalArgumentException if <code>d</code> is empty
|
||||
*/
|
||||
public FieldVectorImpl(T[] d)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
field = d[0].getField();
|
||||
data = d.clone();
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector must have at least one element");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FieldVectorImpl using the input array as the underlying
|
||||
* data array.
|
||||
* <p>If an array is built specially in order to be embedded in a
|
||||
* FieldVectorImpl and not used directly, the <code>copyArray</code> may be
|
||||
* set to <code>false</code. This will prevent the copying and improve
|
||||
* performance as no new array will be built and no data will be copied.</p>
|
||||
* @param d data for new vector
|
||||
* @param copyArray if true, the input array will be copied, otherwise
|
||||
* it will be referenced
|
||||
* @throws IllegalArgumentException if <code>d</code> is empty
|
||||
* @throws NullPointerException if <code>d</code> is null
|
||||
* @see #FieldVectorImpl(T[])
|
||||
*/
|
||||
public FieldVectorImpl(T[] d, boolean copyArray)
|
||||
throws NullPointerException, IllegalArgumentException {
|
||||
try {
|
||||
field = d[0].getField();
|
||||
data = copyArray ? d.clone() : d;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector must have at least one element");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector from part of a array.
|
||||
* @param d array of Ts.
|
||||
* @param pos position of first entry
|
||||
* @param size number of entries to copy
|
||||
*/
|
||||
public FieldVectorImpl(T[] d, int pos, int size) {
|
||||
if (d.length < pos + size) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"position {0} and size {1} don't fit to the size of the input array {2}",
|
||||
pos, size, d.length);
|
||||
}
|
||||
field = d[0].getField();
|
||||
data = buildArray(size);
|
||||
System.arraycopy(d, pos, data, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector from another vector, using a deep copy.
|
||||
* @param v vector to copy
|
||||
*/
|
||||
public FieldVectorImpl(FieldVector<T> v) {
|
||||
field = v.getField();
|
||||
data = buildArray(v.getDimension());
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
data[i] = v.getEntry(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector from another vector, using a deep copy.
|
||||
* @param v vector to copy
|
||||
*/
|
||||
public FieldVectorImpl(FieldVectorImpl<T> v) {
|
||||
field = v.getField();
|
||||
data = v.data.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector from another vector.
|
||||
* @param v vector to copy
|
||||
* @param deep if true perform a deep copy otherwise perform a shallow copy
|
||||
*/
|
||||
public FieldVectorImpl(FieldVectorImpl<T> v, boolean deep) {
|
||||
field = v.getField();
|
||||
data = deep ? v.data.clone() : v.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector by appending one vector to another vector.
|
||||
* @param v1 first vector (will be put in front of the new vector)
|
||||
* @param v2 second vector (will be put at back of the new vector)
|
||||
*/
|
||||
public FieldVectorImpl(FieldVectorImpl<T> v1, FieldVectorImpl<T> v2) {
|
||||
field = v1.getField();
|
||||
data = buildArray(v1.data.length + v2.data.length);
|
||||
System.arraycopy(v1.data, 0, data, 0, v1.data.length);
|
||||
System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector by appending one vector to another vector.
|
||||
* @param v1 first vector (will be put in front of the new vector)
|
||||
* @param v2 second vector (will be put at back of the new vector)
|
||||
*/
|
||||
public FieldVectorImpl(FieldVectorImpl<T> v1, T[] v2) {
|
||||
field = v1.getField();
|
||||
data = buildArray(v1.data.length + v2.length);
|
||||
System.arraycopy(v1.data, 0, data, 0, v1.data.length);
|
||||
System.arraycopy(v2, 0, data, v1.data.length, v2.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector by appending one vector to another vector.
|
||||
* @param v1 first vector (will be put in front of the new vector)
|
||||
* @param v2 second vector (will be put at back of the new vector)
|
||||
*/
|
||||
public FieldVectorImpl(T[] v1, FieldVectorImpl<T> v2) {
|
||||
field = v2.getField();
|
||||
data = buildArray(v1.length + v2.data.length);
|
||||
System.arraycopy(v1, 0, data, 0, v1.length);
|
||||
System.arraycopy(v2.data, 0, data, v1.length, v2.data.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector by appending one vector to another vector.
|
||||
* @param v1 first vector (will be put in front of the new vector)
|
||||
* @param v2 second vector (will be put at back of the new vector)
|
||||
* @exception IllegalArgumentException if both vectors are empty
|
||||
*/
|
||||
public FieldVectorImpl(T[] v1, T[] v2) {
|
||||
try {
|
||||
data = buildArray(v1.length + v2.length);
|
||||
System.arraycopy(v1, 0, data, 0, v1.length);
|
||||
System.arraycopy(v2, 0, data, v1.length, v2.length);
|
||||
field = data[0].getField();
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector must have at least one element");
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Field<T> getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> copy() {
|
||||
return new FieldVectorImpl<T>(this, true);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
|
||||
try {
|
||||
return add((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].add(v.getEntry(i));
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> add(T[] v) throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].add(v[i]);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the sum of this and v.
|
||||
* @param v vector to be added
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVectorImpl<T> add(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return (FieldVectorImpl<T>) add((T[]) v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException {
|
||||
try {
|
||||
return subtract((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].subtract(v.getEntry(i));
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].subtract(v[i]);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute this minus v.
|
||||
* @param v vector to be subtracted
|
||||
* @return this + v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVectorImpl<T> subtract(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return (FieldVectorImpl<T>) subtract((T[]) v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapAdd(T d) {
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].add(d);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapAddToSelf(T d) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = data[i].add(d);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapSubtract(T d) {
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].subtract(d);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapSubtractToSelf(T d) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = data[i].subtract(d);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapMultiply(T d) {
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].multiply(d);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapMultiplyToSelf(T d) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = data[i].multiply(d);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapDivide(T d) {
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].divide(d);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapDivideToSelf(T d) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = data[i].divide(d);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapInv() {
|
||||
T[] out = buildArray(data.length);
|
||||
final T one = field.getOne();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = one.divide(data[i]);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> mapInvToSelf() {
|
||||
final T one = field.getOne();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = one.divide(data[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> ebeMultiply(FieldVector<T> v)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return ebeMultiply((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].multiply(v.getEntry(i));
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> ebeMultiply(T[] v)
|
||||
throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].multiply(v[i]);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element-by-element multiplication.
|
||||
* @param v vector by which instance elements must be multiplied
|
||||
* @return a vector containing this[i] * v[i] for all i
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVectorImpl<T> ebeMultiply(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return (FieldVectorImpl<T>) ebeMultiply(v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> ebeDivide(FieldVector<T> v)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return ebeDivide((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].divide(v.getEntry(i));
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> ebeDivide(T[] v)
|
||||
throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].divide(v[i]);
|
||||
}
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element-by-element division.
|
||||
* @param v vector by which instance elements must be divided
|
||||
* @return a vector containing this[i] / v[i] for all i
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVectorImpl<T> ebeDivide(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return (FieldVectorImpl<T>) ebeDivide(v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T[] getData() {
|
||||
return data.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the underlying data array.
|
||||
* <p>Does not make a fresh copy of the underlying data.</p>
|
||||
* @return array of entries
|
||||
*/
|
||||
public T[] getDataRef() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T dotProduct(FieldVector<T> v)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return dotProduct((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
T dot = field.getZero();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
dot = dot.add(data[i].multiply(v.getEntry(i)));
|
||||
}
|
||||
return dot;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T dotProduct(T[] v)
|
||||
throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
T dot = field.getZero();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
dot = dot.add(data[i].multiply(v[i]));
|
||||
}
|
||||
return dot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the dot product.
|
||||
* @param v vector with which dot product should be computed
|
||||
* @return the scalar dot product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public T dotProduct(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return dotProduct(v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> projection(FieldVector<T> v) {
|
||||
return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> projection(T[] v) {
|
||||
return projection(new FieldVectorImpl<T>(v, false));
|
||||
}
|
||||
|
||||
/** Find the orthogonal projection of this vector onto another vector.
|
||||
* @param v vector onto which instance must be projected
|
||||
* @return projection of the instance onto v
|
||||
* @throws IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldVectorImpl<T> projection(FieldVectorImpl<T> v) {
|
||||
return (FieldVectorImpl<T>) v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> outerProduct(FieldVector<T> v)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return outerProduct((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
checkVectorDimensions(v);
|
||||
final int m = data.length;
|
||||
final FieldMatrix<T> out = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
for (int j = 0; j < data.length; j++) {
|
||||
out.setEntry(i, j, data[i].multiply(v.getEntry(j)));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the outer product.
|
||||
* @param v vector with which outer product should be computed
|
||||
* @return the square matrix outer product between instance and v
|
||||
* @exception IllegalArgumentException if v is not the same size as this
|
||||
*/
|
||||
public FieldMatrix<T> outerProduct(FieldVectorImpl<T> v)
|
||||
throws IllegalArgumentException {
|
||||
return outerProduct(v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> outerProduct(T[] v)
|
||||
throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.length);
|
||||
final int m = data.length;
|
||||
final FieldMatrix<T> out = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
for (int j = 0; j < data.length; j++) {
|
||||
out.setEntry(i, j, data[i].multiply(v[j]));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T getEntry(int index) throws MatrixIndexException {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getDimension() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> append(FieldVector<T> v) {
|
||||
try {
|
||||
return append((FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
return new FieldVectorImpl<T>(this,new FieldVectorImpl<T>(v));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a vector by appending a vector to this vector.
|
||||
* @param v vector to append to this one.
|
||||
* @return a new vector
|
||||
*/
|
||||
public FieldVectorImpl<T> append(FieldVectorImpl<T> v) {
|
||||
return new FieldVectorImpl<T>(this, v);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> append(T in) {
|
||||
final T[] out = buildArray(data.length + 1);
|
||||
System.arraycopy(data, 0, out, 0, data.length);
|
||||
out[data.length] = in;
|
||||
return new FieldVectorImpl<T>(out);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> append(T[] in) {
|
||||
return new FieldVectorImpl<T>(this, in);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldVector<T> getSubVector(int index, int n) {
|
||||
FieldVectorImpl<T> out = new FieldVectorImpl<T>(field, n);
|
||||
try {
|
||||
System.arraycopy(data, index, out.data, 0, n);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkIndex(index);
|
||||
checkIndex(index + n - 1);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setEntry(int index, T value) {
|
||||
try {
|
||||
data[index] = value;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setSubVector(int index, FieldVector<T> v) {
|
||||
try {
|
||||
try {
|
||||
set(index, (FieldVectorImpl<T>) v);
|
||||
} catch (ClassCastException cce) {
|
||||
for (int i = index; i < index + v.getDimension(); ++i) {
|
||||
data[i] = v.getEntry(i-index);
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkIndex(index);
|
||||
checkIndex(index + v.getDimension() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void setSubVector(int index, T[] v) {
|
||||
try {
|
||||
System.arraycopy(v, 0, data, index, v.length);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
checkIndex(index);
|
||||
checkIndex(index + v.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a set of consecutive elements.
|
||||
*
|
||||
* @param index index of first element to be set.
|
||||
* @param v vector containing the values to set.
|
||||
* @exception MatrixIndexException if the index is
|
||||
* inconsistent with vector size
|
||||
*/
|
||||
public void set(int index, FieldVectorImpl<T> v)
|
||||
throws MatrixIndexException {
|
||||
setSubVector(index, v.data);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void set(T value) {
|
||||
Arrays.fill(data, value);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T[] toArray(){
|
||||
return data.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if instance and specified vectors have the same dimension.
|
||||
* @param v vector to compare instance with
|
||||
* @exception IllegalArgumentException if the vectors do not
|
||||
* have the same dimension
|
||||
*/
|
||||
protected void checkVectorDimensions(FieldVector<T> v)
|
||||
throws IllegalArgumentException {
|
||||
checkVectorDimensions(v.getDimension());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if instance dimension is equal to some expected value.
|
||||
*
|
||||
* @param n expected dimension.
|
||||
* @exception IllegalArgumentException if the dimension is
|
||||
* inconsistent with vector size
|
||||
*/
|
||||
protected void checkVectorDimensions(int n)
|
||||
throws IllegalArgumentException {
|
||||
if (data.length != n) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector length mismatch: got {0} but expected {1}",
|
||||
data.length, n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the equality of two real vectors.
|
||||
* <p>
|
||||
* If all coordinates of two real vectors are exactly the same, and none are
|
||||
* <code>Double.NaN</code>, the two real vectors are considered to be equal.
|
||||
* </p>
|
||||
* <p>
|
||||
* <code>NaN</code> coordinates are considered to affect globally the vector
|
||||
* and be equals to each other - i.e, if either (or all) coordinates of the
|
||||
* real vector are equal to <code>Double.NaN</code>, the real vector is equal to
|
||||
* a vector with all <code>Double.NaN</code> coordinates.
|
||||
* </p>
|
||||
*
|
||||
* @param other Object to test for equality to this
|
||||
* @return true if two 3D vector objects are equal, false if
|
||||
* object is null, not an instance of Vector3D, or
|
||||
* not equal to this Vector3D instance
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
FieldVector<T> rhs = (FieldVector<T>) other;
|
||||
if (data.length != rhs.getDimension()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
if (!data[i].equals(rhs.getEntry(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
} catch (ClassCastException ex) {
|
||||
// ignore exception
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hashCode for the real vector.
|
||||
* <p>All NaN values have the same hash code.</p>
|
||||
* @return a hash code value for this object
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = 3542;
|
||||
for (final T a : data) {
|
||||
h = h ^ a.hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an index is valid.
|
||||
* @param index index to check
|
||||
* @exception MatrixIndexException if index is not valid
|
||||
*/
|
||||
private void checkIndex(final int index)
|
||||
throws MatrixIndexException {
|
||||
if (index < 0 || index >= getDimension()) {
|
||||
throw new MatrixIndexException(
|
||||
"index {0} out of allowed range [{1}, {2}]",
|
||||
index, 0, getDimension() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear.decomposition;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.linear.FieldMatrix;
|
||||
import org.apache.commons.math.linear.FieldVector;
|
||||
import org.apache.commons.math.linear.InvalidMatrixException;
|
||||
|
||||
|
||||
/**
|
||||
* Interface handling decomposition algorithms that can solve A × X = B.
|
||||
* <p>Decomposition algorithms decompose an A matrix has a product of several specific
|
||||
* matrices from which they can solve A × X = B in least squares sense: they find X
|
||||
* such that ||A × X - B|| is minimal.</p>
|
||||
* <p>Some solvers like {@link LUDecomposition} can only find the solution for
|
||||
* square matrices and when the solution is an exact linear solution, i.e. when
|
||||
* ||A × X - B|| is exactly 0. Other solvers can also find solutions
|
||||
* with non-square matrix A and with non-null minimal norm. If an exact linear
|
||||
* solution exists it is also the minimal norm solution.</p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface FieldDecompositionSolver<T extends FieldElement<T>> extends Serializable {
|
||||
|
||||
/** Solve the linear equation A × X = B for matrices A.
|
||||
* <p>The A matrix is implicit, it is provided by the underlying
|
||||
* decomposition algorithm.</p>
|
||||
* @param b right-hand side of the equation A × X = B
|
||||
* @return a vector X that minimizes the two norm of A × X - B
|
||||
* @exception IllegalArgumentException if matrices dimensions don't match
|
||||
* @exception InvalidMatrixException if decomposed matrix is singular
|
||||
*/
|
||||
T[] solve(final T[] b)
|
||||
throws IllegalArgumentException, InvalidMatrixException;
|
||||
|
||||
/** Solve the linear equation A × X = B for matrices A.
|
||||
* <p>The A matrix is implicit, it is provided by the underlying
|
||||
* decomposition algorithm.</p>
|
||||
* @param b right-hand side of the equation A × X = B
|
||||
* @return a vector X that minimizes the two norm of A × X - B
|
||||
* @exception IllegalArgumentException if matrices dimensions don't match
|
||||
* @exception InvalidMatrixException if decomposed matrix is singular
|
||||
*/
|
||||
FieldVector<T> solve(final FieldVector<T> b)
|
||||
throws IllegalArgumentException, InvalidMatrixException;
|
||||
|
||||
/** Solve the linear equation A × X = B for matrices A.
|
||||
* <p>The A matrix is implicit, it is provided by the underlying
|
||||
* decomposition algorithm.</p>
|
||||
* @param b right-hand side of the equation A × X = B
|
||||
* @return a matrix X that minimizes the two norm of A × X - B
|
||||
* @exception IllegalArgumentException if matrices dimensions don't match
|
||||
* @exception InvalidMatrixException if decomposed matrix is singular
|
||||
*/
|
||||
FieldMatrix<T> solve(final FieldMatrix<T> b)
|
||||
throws IllegalArgumentException, InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Check if the decomposed matrix is non-singular.
|
||||
* @return true if the decomposed matrix is non-singular
|
||||
*/
|
||||
boolean isNonSingular();
|
||||
|
||||
/** Get the inverse (or pseudo-inverse) of the decomposed matrix.
|
||||
* @return inverse matrix
|
||||
* @throws InvalidMatrixException if decomposed matrix is singular
|
||||
*/
|
||||
FieldMatrix<T> getInverse()
|
||||
throws InvalidMatrixException;
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear.decomposition;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.linear.FieldMatrix;
|
||||
|
||||
/**
|
||||
* An interface to classes that implement an algorithm to calculate the
|
||||
* LU-decomposition of a real matrix.
|
||||
* <p>The LU-decomposition of matrix A is a set of three matrices: P, L and U
|
||||
* such that P×A = L×U. P is a rows permutation matrix that is used
|
||||
* to rearrange the rows of A before so that it can be decomposed. L is a lower
|
||||
* triangular matrix with unit diagonal terms and U is an upper triangular matrix.</p>
|
||||
* <p>This interface is based on the class with similar name from the now defunct
|
||||
* <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library.</p>
|
||||
* <ul>
|
||||
* <li>a {@link #getP() getP} method has been added,</li>
|
||||
* <li>the <code>det</code> method has been renamed as {@link #getDeterminant()
|
||||
* getDeterminant},</li>
|
||||
* <li>the <code>getDoublePivot</code> method has been removed (but the int based
|
||||
* {@link #getPivot() getPivot} method has been kept),</li>
|
||||
* <li>the <code>solve</code> and <code>isNonSingular</code> methods have been replaced
|
||||
* by a {@link #getSolver() getSolver} method and the equivalent methods provided by
|
||||
* the returned {@link DecompositionSolver}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @see <a href="http://mathworld.wolfram.com/LUDecomposition.html">MathWorld</a>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/LU_decomposition">Wikipedia</a>
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface FieldLUDecomposition<T extends FieldElement<T>> extends Serializable {
|
||||
|
||||
/**
|
||||
* Returns the matrix L of the decomposition.
|
||||
* <p>L is an lower-triangular matrix</p>
|
||||
* @return the L matrix (or null if decomposed matrix is singular)
|
||||
*/
|
||||
FieldMatrix<T> getL();
|
||||
|
||||
/**
|
||||
* Returns the matrix U of the decomposition.
|
||||
* <p>U is an upper-triangular matrix</p>
|
||||
* @return the U matrix (or null if decomposed matrix is singular)
|
||||
*/
|
||||
FieldMatrix<T> getU();
|
||||
|
||||
/**
|
||||
* Returns the P rows permutation matrix.
|
||||
* <p>P is a sparse matrix with exactly one element set to 1.0 in
|
||||
* each row and each column, all other elements being set to 0.0.</p>
|
||||
* <p>The positions of the 1 elements are given by the {@link #getPivot()
|
||||
* pivot permutation vector}.</p>
|
||||
* @return the P rows permutation matrix (or null if decomposed matrix is singular)
|
||||
* @see #getPivot()
|
||||
*/
|
||||
FieldMatrix<T> getP();
|
||||
|
||||
/**
|
||||
* Returns the pivot permutation vector.
|
||||
* @return the pivot permutation vector
|
||||
* @see #getP()
|
||||
*/
|
||||
int[] getPivot();
|
||||
|
||||
/**
|
||||
* Return the determinant of the matrix
|
||||
* @return determinant of the matrix
|
||||
*/
|
||||
T getDeterminant();
|
||||
|
||||
/**
|
||||
* Get a solver for finding the A × X = B solution in exact linear sense.
|
||||
* @return a solver
|
||||
*/
|
||||
FieldDecompositionSolver<T> getSolver();
|
||||
|
||||
}
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear.decomposition;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
import org.apache.commons.math.linear.FieldMatrix;
|
||||
import org.apache.commons.math.linear.FieldMatrixImpl;
|
||||
import org.apache.commons.math.linear.FieldVector;
|
||||
import org.apache.commons.math.linear.FieldVectorImpl;
|
||||
import org.apache.commons.math.linear.InvalidMatrixException;
|
||||
|
||||
/**
|
||||
* Calculates the LUP-decomposition of a square matrix.
|
||||
* <p>The LUP-decomposition of a matrix A consists of three matrices
|
||||
* L, U and P that satisfy: PA = LU, L is lower triangular, and U is
|
||||
* upper triangular and P is a permutation matrix. All matrices are
|
||||
* m×m.</p>
|
||||
* <p>Since {@link FieldElement field elements} do not provide an ordering
|
||||
* operator, the permutation matrix is computed here only in order to avoid
|
||||
* a zero pivot element, no attempt is done to get the largest pivot element.</p>
|
||||
*
|
||||
* @param <T> the type of the field elements
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.0
|
||||
*/
|
||||
public class FieldLUDecompositionImpl<T extends FieldElement<T>> implements FieldLUDecomposition<T> {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 1954692554563387537L;
|
||||
|
||||
/** Field to which the elements belong. */
|
||||
private final Field<T> field;
|
||||
|
||||
/** Entries of LU decomposition. */
|
||||
private T lu[][];
|
||||
|
||||
/** Pivot permutation associated with LU decomposition */
|
||||
private int[] pivot;
|
||||
|
||||
/** Parity of the permutation associated with the LU decomposition */
|
||||
private boolean even;
|
||||
|
||||
/** Singularity indicator. */
|
||||
private boolean singular;
|
||||
|
||||
/** Cached value of L. */
|
||||
private FieldMatrix<T> cachedL;
|
||||
|
||||
/** Cached value of U. */
|
||||
private FieldMatrix<T> cachedU;
|
||||
|
||||
/** Cached value of P. */
|
||||
private FieldMatrix<T> cachedP;
|
||||
|
||||
/**
|
||||
* Calculates the LU-decomposition of the given matrix.
|
||||
* @param matrix The matrix to decompose.
|
||||
* @exception NonSquareMatrixException if matrix is not square
|
||||
*/
|
||||
public FieldLUDecompositionImpl(FieldMatrix<T> matrix)
|
||||
throws NonSquareMatrixException {
|
||||
|
||||
if (!matrix.isSquare()) {
|
||||
throw new NonSquareMatrixException(matrix.getRowDimension(), matrix.getColumnDimension());
|
||||
}
|
||||
|
||||
final int m = matrix.getColumnDimension();
|
||||
field = matrix.getField();
|
||||
lu = matrix.getData();
|
||||
pivot = new int[m];
|
||||
cachedL = null;
|
||||
cachedU = null;
|
||||
cachedP = null;
|
||||
|
||||
// Initialize permutation array and parity
|
||||
for (int row = 0; row < m; row++) {
|
||||
pivot[row] = row;
|
||||
}
|
||||
even = true;
|
||||
singular = false;
|
||||
|
||||
// Loop over columns
|
||||
for (int col = 0; col < m; col++) {
|
||||
|
||||
T sum = field.getZero();
|
||||
|
||||
// upper
|
||||
for (int row = 0; row < col; row++) {
|
||||
final T[] luRow = lu[row];
|
||||
sum = luRow[col];
|
||||
for (int i = 0; i < row; i++) {
|
||||
sum = sum.subtract(luRow[i].multiply(lu[i][col]));
|
||||
}
|
||||
luRow[col] = sum;
|
||||
}
|
||||
|
||||
// lower
|
||||
int nonZero = col; // permutation row
|
||||
for (int row = col; row < m; row++) {
|
||||
final T[] luRow = lu[row];
|
||||
sum = luRow[col];
|
||||
for (int i = 0; i < col; i++) {
|
||||
sum = sum.subtract(luRow[i].multiply(lu[i][col]));
|
||||
}
|
||||
luRow[col] = sum;
|
||||
|
||||
if (lu[nonZero][col].equals(field.getZero())) {
|
||||
// try to select a better permutation choice
|
||||
++nonZero;
|
||||
}
|
||||
}
|
||||
|
||||
// Singularity check
|
||||
if (nonZero >= m) {
|
||||
singular = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pivot if necessary
|
||||
if (nonZero != col) {
|
||||
T tmp = field.getZero();
|
||||
for (int i = 0; i < m; i++) {
|
||||
tmp = lu[nonZero][i];
|
||||
lu[nonZero][i] = lu[col][i];
|
||||
lu[col][i] = tmp;
|
||||
}
|
||||
int temp = pivot[nonZero];
|
||||
pivot[nonZero] = pivot[col];
|
||||
pivot[col] = temp;
|
||||
even = !even;
|
||||
}
|
||||
|
||||
// Divide the lower elements by the "winning" diagonal elt.
|
||||
final T luDiag = lu[col][col];
|
||||
for (int row = col + 1; row < m; row++) {
|
||||
final T[] luRow = lu[row];
|
||||
luRow[col] = luRow[col].divide(luDiag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> getL() {
|
||||
if ((cachedL == null) && !singular) {
|
||||
final int m = pivot.length;
|
||||
cachedL = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < m; ++i) {
|
||||
final T[] luI = lu[i];
|
||||
for (int j = 0; j < i; ++j) {
|
||||
cachedL.setEntry(i, j, luI[j]);
|
||||
}
|
||||
cachedL.setEntry(i, i, field.getOne());
|
||||
}
|
||||
}
|
||||
return cachedL;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> getU() {
|
||||
if ((cachedU == null) && !singular) {
|
||||
final int m = pivot.length;
|
||||
cachedU = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < m; ++i) {
|
||||
final T[] luI = lu[i];
|
||||
for (int j = i; j < m; ++j) {
|
||||
cachedU.setEntry(i, j, luI[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cachedU;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> getP() {
|
||||
if ((cachedP == null) && !singular) {
|
||||
final int m = pivot.length;
|
||||
cachedP = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < m; ++i) {
|
||||
cachedP.setEntry(i, pivot[i], field.getOne());
|
||||
}
|
||||
}
|
||||
return cachedP;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int[] getPivot() {
|
||||
return pivot.clone();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public T getDeterminant() {
|
||||
if (singular) {
|
||||
return field.getZero();
|
||||
} else {
|
||||
final int m = pivot.length;
|
||||
T determinant = even ? field.getOne() : field.getZero().subtract(field.getOne());
|
||||
for (int i = 0; i < m; i++) {
|
||||
determinant = determinant.multiply(lu[i][i]);
|
||||
}
|
||||
return determinant;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldDecompositionSolver<T> getSolver() {
|
||||
return new Solver<T>(field, lu, pivot, singular);
|
||||
}
|
||||
|
||||
/** Specialized solver. */
|
||||
private static class Solver<T extends FieldElement<T>> implements FieldDecompositionSolver<T> {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -6353105415121373022L;
|
||||
|
||||
/** Field to which the elements belong. */
|
||||
private final Field<T> field;
|
||||
|
||||
/** Entries of LU decomposition. */
|
||||
private final T lu[][];
|
||||
|
||||
/** Pivot permutation associated with LU decomposition. */
|
||||
private final int[] pivot;
|
||||
|
||||
/** Singularity indicator. */
|
||||
private final boolean singular;
|
||||
|
||||
/**
|
||||
* Build a solver from decomposed matrix.
|
||||
* @param field field to which the matrix elements belong
|
||||
* @param lu entries of LU decomposition
|
||||
* @param pivot pivot permutation associated with LU decomposition
|
||||
* @param singular singularity indicator
|
||||
*/
|
||||
private Solver(final Field<T> field, final T[][] lu,
|
||||
final int[] pivot, final boolean singular) {
|
||||
this.field = field;
|
||||
this.lu = lu;
|
||||
this.pivot = pivot;
|
||||
this.singular = singular;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isNonSingular() {
|
||||
return !singular;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@SuppressWarnings("unchecked")
|
||||
public T[] solve(T[] b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
|
||||
final int m = pivot.length;
|
||||
if (b.length != m) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector length mismatch: got {0} but expected {1}",
|
||||
b.length, m);
|
||||
}
|
||||
if (singular) {
|
||||
throw new SingularMatrixException();
|
||||
}
|
||||
|
||||
final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m);
|
||||
|
||||
// Apply permutations to b
|
||||
for (int row = 0; row < m; row++) {
|
||||
bp[row] = b[pivot[row]];
|
||||
}
|
||||
|
||||
// Solve LY = b
|
||||
for (int col = 0; col < m; col++) {
|
||||
final T bpCol = bp[col];
|
||||
for (int i = col + 1; i < m; i++) {
|
||||
bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
|
||||
}
|
||||
}
|
||||
|
||||
// Solve UX = Y
|
||||
for (int col = m - 1; col >= 0; col--) {
|
||||
bp[col] = bp[col].divide(lu[col][col]);
|
||||
final T bpCol = bp[col];
|
||||
for (int i = 0; i < col; i++) {
|
||||
bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
|
||||
}
|
||||
}
|
||||
|
||||
return bp;
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@SuppressWarnings("unchecked")
|
||||
public FieldVector<T> solve(FieldVector<T> b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
try {
|
||||
return solve((FieldVectorImpl<T>) b);
|
||||
} catch (ClassCastException cce) {
|
||||
|
||||
final int m = pivot.length;
|
||||
if (b.getDimension() != m) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"vector length mismatch: got {0} but expected {1}",
|
||||
b.getDimension(), m);
|
||||
}
|
||||
if (singular) {
|
||||
throw new SingularMatrixException();
|
||||
}
|
||||
|
||||
final T[] bp = (T[]) Array.newInstance(field.getZero().getClass(), m);
|
||||
|
||||
// Apply permutations to b
|
||||
for (int row = 0; row < m; row++) {
|
||||
bp[row] = b.getEntry(pivot[row]);
|
||||
}
|
||||
|
||||
// Solve LY = b
|
||||
for (int col = 0; col < m; col++) {
|
||||
final T bpCol = bp[col];
|
||||
for (int i = col + 1; i < m; i++) {
|
||||
bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
|
||||
}
|
||||
}
|
||||
|
||||
// Solve UX = Y
|
||||
for (int col = m - 1; col >= 0; col--) {
|
||||
bp[col] = bp[col].divide(lu[col][col]);
|
||||
final T bpCol = bp[col];
|
||||
for (int i = 0; i < col; i++) {
|
||||
bp[i] = bp[i].subtract(bpCol.multiply(lu[i][col]));
|
||||
}
|
||||
}
|
||||
|
||||
return new FieldVectorImpl<T>(bp, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/** Solve the linear equation A × X = B.
|
||||
* <p>The A matrix is implicit here. It is </p>
|
||||
* @param b right-hand side of the equation A × X = B
|
||||
* @return a vector X such that A × X = B
|
||||
* @exception IllegalArgumentException if matrices dimensions don't match
|
||||
* @exception InvalidMatrixException if decomposed matrix is singular
|
||||
*/
|
||||
public FieldVectorImpl<T> solve(FieldVectorImpl<T> b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
return new FieldVectorImpl<T>(solve(b.getDataRef()), false);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@SuppressWarnings("unchecked")
|
||||
public FieldMatrix<T> solve(FieldMatrix<T> b)
|
||||
throws IllegalArgumentException, InvalidMatrixException {
|
||||
|
||||
final int m = pivot.length;
|
||||
if (b.getRowDimension() != m) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
|
||||
b.getRowDimension(), b.getColumnDimension(), m, "n");
|
||||
}
|
||||
if (singular) {
|
||||
throw new SingularMatrixException();
|
||||
}
|
||||
|
||||
final int nColB = b.getColumnDimension();
|
||||
|
||||
// Apply permutations to b
|
||||
final T[][] bp = (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { m, nColB });
|
||||
for (int row = 0; row < m; row++) {
|
||||
final T[] bpRow = bp[row];
|
||||
final int pRow = pivot[row];
|
||||
for (int col = 0; col < nColB; col++) {
|
||||
bpRow[col] = b.getEntry(pRow, col);
|
||||
}
|
||||
}
|
||||
|
||||
// Solve LY = b
|
||||
for (int col = 0; col < m; col++) {
|
||||
final T[] bpCol = bp[col];
|
||||
for (int i = col + 1; i < m; i++) {
|
||||
final T[] bpI = bp[i];
|
||||
final T luICol = lu[i][col];
|
||||
for (int j = 0; j < nColB; j++) {
|
||||
bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Solve UX = Y
|
||||
for (int col = m - 1; col >= 0; col--) {
|
||||
final T[] bpCol = bp[col];
|
||||
final T luDiag = lu[col][col];
|
||||
for (int j = 0; j < nColB; j++) {
|
||||
bpCol[j] = bpCol[j].divide(luDiag);
|
||||
}
|
||||
for (int i = 0; i < col; i++) {
|
||||
final T[] bpI = bp[i];
|
||||
final T luICol = lu[i][col];
|
||||
for (int j = 0; j < nColB; j++) {
|
||||
bpI[j] = bpI[j].subtract(bpCol[j].multiply(luICol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new FieldMatrixImpl<T>(bp, false);
|
||||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public FieldMatrix<T> getInverse() throws InvalidMatrixException {
|
||||
final int m = pivot.length;
|
||||
final T one = field.getOne();
|
||||
FieldMatrix<T> identity = new FieldMatrixImpl<T>(field, m, m);
|
||||
for (int i = 0; i < m; ++i) {
|
||||
identity.setEntry(i, i, one);
|
||||
}
|
||||
return solve(identity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,7 @@ import org.apache.commons.math.linear.RealVectorImpl;
|
|||
/**
|
||||
* Calculates the LUP-decomposition of a square matrix.
|
||||
* <p>The LUP-decomposition of a matrix A consists of three matrices
|
||||
* L, U and P that satisfy: A = LUP, L is lower triangular, and U is
|
||||
* L, U and P that satisfy: PA = LU, L is lower triangular, and U is
|
||||
* upper triangular and P is a permutation matrix. All matrices are
|
||||
* m×m.</p>
|
||||
* <p>As shown by the presence of the P matrix, this decomposition is
|
||||
|
@ -146,10 +146,12 @@ public class LUDecompositionImpl implements LUDecomposition {
|
|||
// Pivot if necessary
|
||||
if (max != col) {
|
||||
double tmp = 0;
|
||||
final double[] luMax = lu[max];
|
||||
final double[] luCol = lu[col];
|
||||
for (int i = 0; i < m; i++) {
|
||||
tmp = lu[max][i];
|
||||
lu[max][i] = lu[col][i];
|
||||
lu[col][i] = tmp;
|
||||
tmp = luMax[i];
|
||||
luMax[i] = luCol[i];
|
||||
luCol[i] = tmp;
|
||||
}
|
||||
int temp = pivot[max];
|
||||
pivot[max] = pivot[col];
|
||||
|
@ -288,16 +290,18 @@ public class LUDecompositionImpl implements LUDecomposition {
|
|||
|
||||
// Solve LY = b
|
||||
for (int col = 0; col < m; col++) {
|
||||
final double bpCol = bp[col];
|
||||
for (int i = col + 1; i < m; i++) {
|
||||
bp[i] -= bp[col] * lu[i][col];
|
||||
bp[i] -= bpCol * lu[i][col];
|
||||
}
|
||||
}
|
||||
|
||||
// Solve UX = Y
|
||||
for (int col = m - 1; col >= 0; col--) {
|
||||
bp[col] /= lu[col][col];
|
||||
final double bpCol = bp[col];
|
||||
for (int i = 0; i < col; i++) {
|
||||
bp[i] -= bp[col] * lu[i][col];
|
||||
bp[i] -= bpCol * lu[i][col];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,16 +335,18 @@ public class LUDecompositionImpl implements LUDecomposition {
|
|||
|
||||
// Solve LY = b
|
||||
for (int col = 0; col < m; col++) {
|
||||
final double bpCol = bp[col];
|
||||
for (int i = col + 1; i < m; i++) {
|
||||
bp[i] -= bp[col] * lu[i][col];
|
||||
bp[i] -= bpCol * lu[i][col];
|
||||
}
|
||||
}
|
||||
|
||||
// Solve UX = Y
|
||||
for (int col = m - 1; col >= 0; col--) {
|
||||
bp[col] /= lu[col][col];
|
||||
final double bpCol = bp[col];
|
||||
for (int i = 0; i < col; i++) {
|
||||
bp[i] -= bp[col] * lu[i][col];
|
||||
bp[i] -= bpCol * lu[i][col];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,10 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="2.0" date="TBD" description="TBD">
|
||||
<action dev="luc" type="add" >
|
||||
Added support for any type of field in linear algebra (FielxMatrix, FieldVector,
|
||||
FieldLUDecomposition)
|
||||
</action>
|
||||
<action dev="luc" type="add" >
|
||||
Added general Field and FieldElement interfaces to allow generic algorithms
|
||||
to operate on fields. The library already provides several implementations:
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
<li><a href="linear.html#a3.3_Real_vectors">3.3 Real vectors</a></li>
|
||||
<li><a href="linear.html#a3.4_Solving_linear_systems">3.4 Solving linear systems</a></li>
|
||||
<li><a href="linear.html#a3.5_Eigenvalueseigenvectors_and_singular_valuessingular_vectors">3.5 Eigenvalues/eigenvectors and singular values/singular vectors</a></li>
|
||||
<li><a href="linear.html#a3.6_Non-real_fields_complex_fractions_...">3.6 Non-real fields (complex, fractions ...)</a></li>
|
||||
</ul></li>
|
||||
<li><a href="analysis.html">4. Numerical Analysis</a>
|
||||
<ul>
|
||||
|
@ -84,7 +85,7 @@
|
|||
<li><a href="utilities.html#a6.2_Double_array_utilities">6.2 Double array utilities</a></li>
|
||||
<li><a href="utilities.html#a6.3_intdouble_hash_map">6.3 int/double hash map</a></li>
|
||||
<li><a href="utilities.html#a6.4_Continued_Fractions">6.4 Continued Fractions</a></li>
|
||||
<li><a href="utilities.html#a6.5_binomial_coefficients,_factorials_and_other_common_math_functions">6.5 binomial coefficients, factorials and other common math functions</a></li>
|
||||
<li><a href="utilities.html#a6.5_binomial_coefficients_factorials_and_other_common_math_functions">6.5 binomial coefficients, factorials and other common math functions</a></li>
|
||||
</ul></li>
|
||||
<li><a href="complex.html">7. Complex Numbers</a>
|
||||
<ul>
|
||||
|
|
|
@ -184,6 +184,19 @@ RealVector solution = solver.solve(constants);
|
|||
vector spaces (which may have different dimensions).
|
||||
</p>
|
||||
</subsection>
|
||||
<subsection name="3.6 Non-real fields (complex, fractions ...)" href="field">
|
||||
<p>
|
||||
In addition to the real field, matrices and vectors using non-real <a
|
||||
href="../apidocs/org/apache/commons/math/FieldElement.html">field elements</a> can be used.
|
||||
The fields already supported by the library are:
|
||||
<ul>
|
||||
<li><a href="../apidocs/org/apache/commons/math/complex/Complex.html">Complex</a></li>
|
||||
<li><a href="../apidocs/org/apache/commons/math/fraction/Fraction.html">Fraction</a></li>
|
||||
<li><a href="../apidocs/org/apache/commons/math/fraction/BigFraction.html">BigFraction</a></li>
|
||||
<li><a href="../apidocs/org/apache/commons/math/util/BigReal.html">BigReal</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
</subsection>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
|
|
|
@ -28,6 +28,7 @@ import junit.framework.AssertionFailedError;
|
|||
|
||||
import org.apache.commons.math.complex.Complex;
|
||||
import org.apache.commons.math.complex.ComplexFormat;
|
||||
import org.apache.commons.math.linear.FieldMatrix;
|
||||
import org.apache.commons.math.linear.RealMatrix;
|
||||
|
||||
/**
|
||||
|
@ -282,6 +283,34 @@ public class TestUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** verifies that two matrices are equal */
|
||||
public static void assertEquals(FieldMatrix<? extends FieldElement<?>> expected,
|
||||
FieldMatrix<? extends FieldElement<?>> observed) {
|
||||
|
||||
if (observed == null) {
|
||||
Assert.fail("Observed is null");
|
||||
}
|
||||
|
||||
if (expected.getColumnDimension() != observed.getColumnDimension() ||
|
||||
expected.getRowDimension() != observed.getRowDimension()) {
|
||||
StringBuffer messageBuffer = new StringBuffer();
|
||||
messageBuffer.append("Observed has incorrect dimensions.");
|
||||
messageBuffer.append("\nobserved is " + observed.getRowDimension() +
|
||||
" x " + observed.getColumnDimension());
|
||||
messageBuffer.append("\nexpected " + expected.getRowDimension() +
|
||||
" x " + expected.getColumnDimension());
|
||||
Assert.fail(messageBuffer.toString());
|
||||
}
|
||||
|
||||
for (int i = 0; i < expected.getRowDimension(); ++i) {
|
||||
for (int j = 0; j < expected.getColumnDimension(); ++j) {
|
||||
FieldElement<?> eij = expected.getEntry(i, j);
|
||||
FieldElement<?> oij = observed.getEntry(i, j);
|
||||
Assert.assertEquals(eij, oij);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** verifies that two arrays are close (sup norm) */
|
||||
public static void assertEquals(String msg, double[] m, double[] n,
|
||||
double tolerance) {
|
||||
|
@ -294,4 +323,15 @@ public class TestUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/** verifies that two arrays are equal */
|
||||
public static void assertEquals(FieldElement<? extends FieldElement<?>>[] m,
|
||||
FieldElement<? extends FieldElement<?>>[] n) {
|
||||
if (m.length != n.length) {
|
||||
Assert.fail("vectors not same length");
|
||||
}
|
||||
for (int i = 0; i < m.length; i++) {
|
||||
Assert.assertEquals(m[i],n[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.apache.commons.math.linear.decomposition.NonSquareMatrixException;
|
|||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
public final class BigMatrixImplTest extends TestCase {
|
||||
|
||||
// Test data for String constructors
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,625 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.linear;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.apache.commons.math.Field;
|
||||
import org.apache.commons.math.FieldElement;
|
||||
import org.apache.commons.math.fraction.Fraction;
|
||||
import org.apache.commons.math.fraction.FractionField;
|
||||
|
||||
/**
|
||||
* Test cases for the {@link FieldVectorImpl} class.
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class FieldVectorImplTest extends TestCase {
|
||||
|
||||
//
|
||||
protected Fraction[][] ma1 = {
|
||||
{new Fraction(1), new Fraction(2), new Fraction(3)},
|
||||
{new Fraction(4), new Fraction(5), new Fraction(6)},
|
||||
{new Fraction(7), new Fraction(8), new Fraction(9)}
|
||||
};
|
||||
protected Fraction[] vec1 = {new Fraction(1), new Fraction(2), new Fraction(3)};
|
||||
protected Fraction[] vec2 = {new Fraction(4), new Fraction(5), new Fraction(6)};
|
||||
protected Fraction[] vec3 = {new Fraction(7), new Fraction(8), new Fraction(9)};
|
||||
protected Fraction[] vec4 = { new Fraction(1), new Fraction(2), new Fraction(3),
|
||||
new Fraction(4), new Fraction(5), new Fraction(6),
|
||||
new Fraction(7), new Fraction(8), new Fraction(9)};
|
||||
protected Fraction[] vec_null = {new Fraction(0), new Fraction(0), new Fraction(0)};
|
||||
protected Fraction[] dvec1 = {new Fraction(1), new Fraction(2), new Fraction(3),
|
||||
new Fraction(4), new Fraction(5), new Fraction(6),
|
||||
new Fraction(7), new Fraction(8), new Fraction(9)};
|
||||
protected Fraction[][] mat1 = {
|
||||
{new Fraction(1), new Fraction(2), new Fraction(3)},
|
||||
{new Fraction(4), new Fraction(5), new Fraction(6)},
|
||||
{new Fraction(7), new Fraction(8), new Fraction(9)}
|
||||
};
|
||||
|
||||
// Testclass to test the FieldVector<Fraction> interface
|
||||
// only with enough content to support the test
|
||||
public static class FieldVectorTestImpl<T extends FieldElement<T>>
|
||||
implements FieldVector<T>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3970959016014158539L;
|
||||
|
||||
private final Field<T> field;
|
||||
|
||||
/** Entries of the vector. */
|
||||
protected T[] data;
|
||||
|
||||
/** Build an array of elements.
|
||||
* @param length size of the array to build
|
||||
* @return a new array
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private T[] buildArray(final int length) {
|
||||
return (T[]) Array.newInstance(field.getZero().getClass(), length);
|
||||
}
|
||||
|
||||
public FieldVectorTestImpl(T[] d) {
|
||||
field = d[0].getField();
|
||||
data = d.clone();
|
||||
}
|
||||
|
||||
public Field<T> getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
private UnsupportedOperationException unsupported() {
|
||||
return new UnsupportedOperationException("Not supported, unneeded for test purposes");
|
||||
}
|
||||
|
||||
public FieldVector<T> copy() {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> add(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> subtract(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapAdd(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapAddToSelf(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapSubtract(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapSubtractToSelf(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapMultiply(T d) {
|
||||
T[] out = buildArray(data.length);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
out[i] = data[i].multiply(d);
|
||||
}
|
||||
return new FieldVectorTestImpl<T>(out);
|
||||
}
|
||||
|
||||
public FieldVector<T> mapMultiplyToSelf(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapDivide(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapDivideToSelf(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapInv() {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> mapInvToSelf() {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> ebeMultiply(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> ebeDivide(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public T[] getData() {
|
||||
return data.clone();
|
||||
}
|
||||
|
||||
public T dotProduct(FieldVector<T> v) throws IllegalArgumentException {
|
||||
T dot = field.getZero();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
dot = dot.add(data[i].multiply(v.getEntry(i)));
|
||||
}
|
||||
return dot;
|
||||
}
|
||||
|
||||
public T dotProduct(T[] v) throws IllegalArgumentException {
|
||||
T dot = field.getZero();
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
dot = dot.add(data[i].multiply(v[i]));
|
||||
}
|
||||
return dot;
|
||||
}
|
||||
|
||||
public FieldVector<T> projection(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> projection(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldMatrix<T> outerProduct(FieldVector<T> v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldMatrix<T> outerProduct(T[] v) throws IllegalArgumentException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public T getEntry(int index) throws MatrixIndexException {
|
||||
return data[index];
|
||||
}
|
||||
|
||||
public int getDimension() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
public FieldVector<T> append(FieldVector<T> v) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> append(T d) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> append(T[] a) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public FieldVector<T> getSubVector(int index, int n) throws MatrixIndexException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public void setEntry(int index, T value) throws MatrixIndexException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public void setSubVector(int index, FieldVector<T> v) throws MatrixIndexException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public void setSubVector(int index, T[] v) throws MatrixIndexException {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
public T[] toArray() {
|
||||
throw unsupported();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(FieldVectorImplTest.class);
|
||||
suite.setName("FieldVectorImpl<Fraction> Tests");
|
||||
return suite;
|
||||
}
|
||||
|
||||
public void testConstructors() {
|
||||
|
||||
FieldVectorImpl<Fraction> v0 = new FieldVectorImpl<Fraction>(FractionField.getInstance());
|
||||
assertEquals(0, v0.getDimension());
|
||||
|
||||
FieldVectorImpl<Fraction> v1 = new FieldVectorImpl<Fraction>(FractionField.getInstance(), 7);
|
||||
assertEquals(7, v1.getDimension());
|
||||
assertEquals(new Fraction(0), v1.getEntry(6));
|
||||
|
||||
FieldVectorImpl<Fraction> v2 = new FieldVectorImpl<Fraction>(5, new Fraction(123, 100));
|
||||
assertEquals(5, v2.getDimension());
|
||||
assertEquals(new Fraction(123, 100), v2.getEntry(4));
|
||||
|
||||
FieldVectorImpl<Fraction> v3 = new FieldVectorImpl<Fraction>(vec1);
|
||||
assertEquals(3, v3.getDimension());
|
||||
assertEquals(new Fraction(2), v3.getEntry(1));
|
||||
|
||||
FieldVectorImpl<Fraction> v4 = new FieldVectorImpl<Fraction>(vec4, 3, 2);
|
||||
assertEquals(2, v4.getDimension());
|
||||
assertEquals(new Fraction(4), v4.getEntry(0));
|
||||
try {
|
||||
new FieldVectorImpl<Fraction>(vec4, 8, 3);
|
||||
fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVector<Fraction> v5_i = new FieldVectorImpl<Fraction>(dvec1);
|
||||
assertEquals(9, v5_i.getDimension());
|
||||
assertEquals(new Fraction(9), v5_i.getEntry(8));
|
||||
|
||||
FieldVectorImpl<Fraction> v5 = new FieldVectorImpl<Fraction>(dvec1);
|
||||
assertEquals(9, v5.getDimension());
|
||||
assertEquals(new Fraction(9), v5.getEntry(8));
|
||||
|
||||
FieldVectorImpl<Fraction> v6 = new FieldVectorImpl<Fraction>(dvec1, 3, 2);
|
||||
assertEquals(2, v6.getDimension());
|
||||
assertEquals(new Fraction(4), v6.getEntry(0));
|
||||
try {
|
||||
new FieldVectorImpl<Fraction>(dvec1, 8, 3);
|
||||
fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVectorImpl<Fraction> v7 = new FieldVectorImpl<Fraction>(v1);
|
||||
assertEquals(7, v7.getDimension());
|
||||
assertEquals(new Fraction(0), v7.getEntry(6));
|
||||
|
||||
FieldVectorTestImpl<Fraction> v7_i = new FieldVectorTestImpl<Fraction>(vec1);
|
||||
|
||||
FieldVectorImpl<Fraction> v7_2 = new FieldVectorImpl<Fraction>(v7_i);
|
||||
assertEquals(3, v7_2.getDimension());
|
||||
assertEquals(new Fraction(2), v7_2.getEntry(1));
|
||||
|
||||
FieldVectorImpl<Fraction> v8 = new FieldVectorImpl<Fraction>(v1, true);
|
||||
assertEquals(7, v8.getDimension());
|
||||
assertEquals(new Fraction(0), v8.getEntry(6));
|
||||
assertNotSame("testData not same object ", v1.data, v8.data);
|
||||
|
||||
FieldVectorImpl<Fraction> v8_2 = new FieldVectorImpl<Fraction>(v1, false);
|
||||
assertEquals(7, v8_2.getDimension());
|
||||
assertEquals(new Fraction(0), v8_2.getEntry(6));
|
||||
assertEquals(v1.data, v8_2.data);
|
||||
|
||||
FieldVectorImpl<Fraction> v9 = new FieldVectorImpl<Fraction>(v1, v3);
|
||||
assertEquals(10, v9.getDimension());
|
||||
assertEquals(new Fraction(1), v9.getEntry(7));
|
||||
|
||||
}
|
||||
|
||||
public void testDataInOut() {
|
||||
|
||||
FieldVectorImpl<Fraction> v1 = new FieldVectorImpl<Fraction>(vec1);
|
||||
FieldVectorImpl<Fraction> v2 = new FieldVectorImpl<Fraction>(vec2);
|
||||
FieldVectorImpl<Fraction> v4 = new FieldVectorImpl<Fraction>(vec4);
|
||||
FieldVectorTestImpl<Fraction> v2_t = new FieldVectorTestImpl<Fraction>(vec2);
|
||||
|
||||
FieldVector<Fraction> v_append_1 = v1.append(v2);
|
||||
assertEquals(6, v_append_1.getDimension());
|
||||
assertEquals(new Fraction(4), v_append_1.getEntry(3));
|
||||
|
||||
FieldVector<Fraction> v_append_2 = v1.append(new Fraction(2));
|
||||
assertEquals(4, v_append_2.getDimension());
|
||||
assertEquals(new Fraction(2), v_append_2.getEntry(3));
|
||||
|
||||
FieldVector<Fraction> v_append_3 = v1.append(vec2);
|
||||
assertEquals(6, v_append_3.getDimension());
|
||||
assertEquals(new Fraction(4), v_append_3.getEntry(3));
|
||||
|
||||
FieldVector<Fraction> v_append_4 = v1.append(v2_t);
|
||||
assertEquals(6, v_append_4.getDimension());
|
||||
assertEquals(new Fraction(4), v_append_4.getEntry(3));
|
||||
|
||||
FieldVector<Fraction> v_copy = v1.copy();
|
||||
assertEquals(3, v_copy.getDimension());
|
||||
assertNotSame("testData not same object ", v1.data, v_copy.getData());
|
||||
|
||||
Fraction[] a_frac = v1.toArray();
|
||||
assertEquals(3, a_frac.length);
|
||||
assertNotSame("testData not same object ", v1.data, a_frac);
|
||||
|
||||
|
||||
// FieldVectorImpl<Fraction> vout4 = (FieldVectorImpl<Fraction>) v1.clone();
|
||||
// assertEquals(3, vout4.getDimension());
|
||||
// assertEquals(v1.data, vout4.data);
|
||||
|
||||
|
||||
FieldVector<Fraction> vout5 = v4.getSubVector(3, 3);
|
||||
assertEquals(3, vout5.getDimension());
|
||||
assertEquals(new Fraction(5), vout5.getEntry(1));
|
||||
try {
|
||||
v4.getSubVector(3, 7);
|
||||
fail("MatrixIndexException expected");
|
||||
} catch (MatrixIndexException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVectorImpl<Fraction> v_set1 = (FieldVectorImpl<Fraction>) v1.copy();
|
||||
v_set1.setEntry(1, new Fraction(11));
|
||||
assertEquals(new Fraction(11), v_set1.getEntry(1));
|
||||
try {
|
||||
v_set1.setEntry(3, new Fraction(11));
|
||||
fail("MatrixIndexException expected");
|
||||
} catch (MatrixIndexException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVectorImpl<Fraction> v_set2 = (FieldVectorImpl<Fraction>) v4.copy();
|
||||
v_set2.set(3, v1);
|
||||
assertEquals(new Fraction(1), v_set2.getEntry(3));
|
||||
assertEquals(new Fraction(7), v_set2.getEntry(6));
|
||||
try {
|
||||
v_set2.set(7, v1);
|
||||
fail("MatrixIndexException expected");
|
||||
} catch (MatrixIndexException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVectorImpl<Fraction> v_set3 = (FieldVectorImpl<Fraction>) v1.copy();
|
||||
v_set3.set(new Fraction(13));
|
||||
assertEquals(new Fraction(13), v_set3.getEntry(2));
|
||||
|
||||
try {
|
||||
v_set3.getEntry(23);
|
||||
fail("ArrayIndexOutOfBoundsException expected");
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
FieldVectorImpl<Fraction> v_set4 = (FieldVectorImpl<Fraction>) v4.copy();
|
||||
v_set4.setSubVector(3, v2_t);
|
||||
assertEquals(new Fraction(4), v_set4.getEntry(3));
|
||||
assertEquals(new Fraction(7), v_set4.getEntry(6));
|
||||
try {
|
||||
v_set4.setSubVector(7, v2_t);
|
||||
fail("MatrixIndexException expected");
|
||||
} catch (MatrixIndexException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
|
||||
FieldVectorImpl<Fraction> vout10 = (FieldVectorImpl<Fraction>) v1.copy();
|
||||
FieldVectorImpl<Fraction> vout10_2 = (FieldVectorImpl<Fraction>) v1.copy();
|
||||
assertEquals(vout10, vout10_2);
|
||||
vout10_2.setEntry(0, new Fraction(11, 10));
|
||||
assertNotSame(vout10, vout10_2);
|
||||
|
||||
}
|
||||
|
||||
public void testMapFunctions() {
|
||||
FieldVectorImpl<Fraction> v1 = new FieldVectorImpl<Fraction>(vec1);
|
||||
|
||||
//octave = v1 .+ 2.0
|
||||
FieldVector<Fraction> v_mapAdd = v1.mapAdd(new Fraction(2));
|
||||
Fraction[] result_mapAdd = {new Fraction(3), new Fraction(4), new Fraction(5)};
|
||||
checkArray("compare vectors" ,result_mapAdd,v_mapAdd.getData());
|
||||
|
||||
//octave = v1 .+ 2.0
|
||||
FieldVector<Fraction> v_mapAddToSelf = v1.copy();
|
||||
v_mapAddToSelf.mapAddToSelf(new Fraction(2));
|
||||
Fraction[] result_mapAddToSelf = {new Fraction(3), new Fraction(4), new Fraction(5)};
|
||||
checkArray("compare vectors" ,result_mapAddToSelf,v_mapAddToSelf.getData());
|
||||
|
||||
//octave = v1 .- 2.0
|
||||
FieldVector<Fraction> v_mapSubtract = v1.mapSubtract(new Fraction(2));
|
||||
Fraction[] result_mapSubtract = {new Fraction(-1), new Fraction(0), new Fraction(1)};
|
||||
checkArray("compare vectors" ,result_mapSubtract,v_mapSubtract.getData());
|
||||
|
||||
//octave = v1 .- 2.0
|
||||
FieldVector<Fraction> v_mapSubtractToSelf = v1.copy();
|
||||
v_mapSubtractToSelf.mapSubtractToSelf(new Fraction(2));
|
||||
Fraction[] result_mapSubtractToSelf = {new Fraction(-1), new Fraction(0), new Fraction(1)};
|
||||
checkArray("compare vectors" ,result_mapSubtractToSelf,v_mapSubtractToSelf.getData());
|
||||
|
||||
//octave = v1 .* 2.0
|
||||
FieldVector<Fraction> v_mapMultiply = v1.mapMultiply(new Fraction(2));
|
||||
Fraction[] result_mapMultiply = {new Fraction(2), new Fraction(4), new Fraction(6)};
|
||||
checkArray("compare vectors" ,result_mapMultiply,v_mapMultiply.getData());
|
||||
|
||||
//octave = v1 .* 2.0
|
||||
FieldVector<Fraction> v_mapMultiplyToSelf = v1.copy();
|
||||
v_mapMultiplyToSelf.mapMultiplyToSelf(new Fraction(2));
|
||||
Fraction[] result_mapMultiplyToSelf = {new Fraction(2), new Fraction(4), new Fraction(6)};
|
||||
checkArray("compare vectors" ,result_mapMultiplyToSelf,v_mapMultiplyToSelf.getData());
|
||||
|
||||
//octave = v1 ./ 2.0
|
||||
FieldVector<Fraction> v_mapDivide = v1.mapDivide(new Fraction(2));
|
||||
Fraction[] result_mapDivide = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)};
|
||||
checkArray("compare vectors" ,result_mapDivide,v_mapDivide.getData());
|
||||
|
||||
//octave = v1 ./ 2.0
|
||||
FieldVector<Fraction> v_mapDivideToSelf = v1.copy();
|
||||
v_mapDivideToSelf.mapDivideToSelf(new Fraction(2));
|
||||
Fraction[] result_mapDivideToSelf = {new Fraction(1, 2), new Fraction(1), new Fraction(3, 2)};
|
||||
checkArray("compare vectors" ,result_mapDivideToSelf,v_mapDivideToSelf.getData());
|
||||
|
||||
//octave = v1 .^-1
|
||||
FieldVector<Fraction> v_mapInv = v1.mapInv();
|
||||
Fraction[] result_mapInv = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)};
|
||||
checkArray("compare vectors" ,result_mapInv,v_mapInv.getData());
|
||||
|
||||
//octave = v1 .^-1
|
||||
FieldVector<Fraction> v_mapInvToSelf = v1.copy();
|
||||
v_mapInvToSelf.mapInvToSelf();
|
||||
Fraction[] result_mapInvToSelf = {new Fraction(1),new Fraction(1, 2),new Fraction(1, 3)};
|
||||
checkArray("compare vectors" ,result_mapInvToSelf,v_mapInvToSelf.getData());
|
||||
|
||||
}
|
||||
|
||||
public void testBasicFunctions() {
|
||||
FieldVectorImpl<Fraction> v1 = new FieldVectorImpl<Fraction>(vec1);
|
||||
FieldVectorImpl<Fraction> v2 = new FieldVectorImpl<Fraction>(vec2);
|
||||
new FieldVectorImpl<Fraction>(vec_null);
|
||||
|
||||
FieldVectorTestImpl<Fraction> v2_t = new FieldVectorTestImpl<Fraction>(vec2);
|
||||
|
||||
//octave = v1 + v2
|
||||
FieldVectorImpl<Fraction> v_add = v1.add(v2);
|
||||
Fraction[] result_add = {new Fraction(5), new Fraction(7), new Fraction(9)};
|
||||
checkArray("compare vect" ,v_add.getData(),result_add);
|
||||
|
||||
FieldVectorTestImpl<Fraction> vt2 = new FieldVectorTestImpl<Fraction>(vec2);
|
||||
FieldVector<Fraction> v_add_i = v1.add(vt2);
|
||||
Fraction[] result_add_i = {new Fraction(5), new Fraction(7), new Fraction(9)};
|
||||
checkArray("compare vect" ,v_add_i.getData(),result_add_i);
|
||||
|
||||
//octave = v1 - v2
|
||||
FieldVectorImpl<Fraction> v_subtract = v1.subtract(v2);
|
||||
Fraction[] result_subtract = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
|
||||
checkArray("compare vect" ,v_subtract.getData(),result_subtract);
|
||||
|
||||
FieldVector<Fraction> v_subtract_i = v1.subtract(vt2);
|
||||
Fraction[] result_subtract_i = {new Fraction(-3), new Fraction(-3), new Fraction(-3)};
|
||||
checkArray("compare vect" ,v_subtract_i.getData(),result_subtract_i);
|
||||
|
||||
// octave v1 .* v2
|
||||
FieldVectorImpl<Fraction> v_ebeMultiply = v1.ebeMultiply(v2);
|
||||
Fraction[] result_ebeMultiply = {new Fraction(4), new Fraction(10), new Fraction(18)};
|
||||
checkArray("compare vect" ,v_ebeMultiply.getData(),result_ebeMultiply);
|
||||
|
||||
FieldVector<Fraction> v_ebeMultiply_2 = v1.ebeMultiply(v2_t);
|
||||
Fraction[] result_ebeMultiply_2 = {new Fraction(4), new Fraction(10), new Fraction(18)};
|
||||
checkArray("compare vect" ,v_ebeMultiply_2.getData(),result_ebeMultiply_2);
|
||||
|
||||
// octave v1 ./ v2
|
||||
FieldVectorImpl<Fraction> v_ebeDivide = v1.ebeDivide(v2);
|
||||
Fraction[] result_ebeDivide = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)};
|
||||
checkArray("compare vect" ,v_ebeDivide.getData(),result_ebeDivide);
|
||||
|
||||
FieldVector<Fraction> v_ebeDivide_2 = v1.ebeDivide(v2_t);
|
||||
Fraction[] result_ebeDivide_2 = {new Fraction(1, 4), new Fraction(2, 5), new Fraction(1, 2)};
|
||||
checkArray("compare vect" ,v_ebeDivide_2.getData(),result_ebeDivide_2);
|
||||
|
||||
// octave dot(v1,v2)
|
||||
Fraction dot = v1.dotProduct(v2);
|
||||
assertEquals("compare val ",new Fraction(32), dot);
|
||||
|
||||
// octave dot(v1,v2_t)
|
||||
Fraction dot_2 = v1.dotProduct(v2_t);
|
||||
assertEquals("compare val ",new Fraction(32), dot_2);
|
||||
|
||||
FieldMatrix<Fraction> m_outerProduct = v1.outerProduct(v2);
|
||||
assertEquals("compare val ",new Fraction(4), m_outerProduct.getEntry(0,0));
|
||||
|
||||
FieldMatrix<Fraction> m_outerProduct_2 = v1.outerProduct(v2_t);
|
||||
assertEquals("compare val ",new Fraction(4), m_outerProduct_2.getEntry(0,0));
|
||||
|
||||
FieldVectorImpl<Fraction> v_projection = v1.projection(v2);
|
||||
Fraction[] result_projection = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)};
|
||||
checkArray("compare vect", v_projection.getData(), result_projection);
|
||||
|
||||
FieldVector<Fraction> v_projection_2 = v1.projection(v2_t);
|
||||
Fraction[] result_projection_2 = {new Fraction(128, 77), new Fraction(160, 77), new Fraction(192, 77)};
|
||||
checkArray("compare vect", v_projection_2.getData(), result_projection_2);
|
||||
|
||||
}
|
||||
|
||||
public void testMisc() {
|
||||
FieldVectorImpl<Fraction> v1 = new FieldVectorImpl<Fraction>(vec1);
|
||||
FieldVectorImpl<Fraction> v4 = new FieldVectorImpl<Fraction>(vec4);
|
||||
FieldVector<Fraction> v4_2 = new FieldVectorImpl<Fraction>(vec4);
|
||||
|
||||
String out1 = v1.toString();
|
||||
assertTrue("some output ", out1.length()!=0);
|
||||
/*
|
||||
Fraction[] dout1 = v1.copyOut();
|
||||
assertEquals(3, dout1.length);
|
||||
assertNotSame("testData not same object ", v1.data, dout1);
|
||||
*/
|
||||
try {
|
||||
v1.checkVectorDimensions(2);
|
||||
fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
try {
|
||||
v1.checkVectorDimensions(v4);
|
||||
fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
try {
|
||||
v1.checkVectorDimensions(v4_2);
|
||||
fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** verifies that two vectors are equals */
|
||||
protected void checkArray(String msg, Fraction[] m, Fraction[] n) {
|
||||
if (m.length != n.length) {
|
||||
fail("vectors have different lengths");
|
||||
}
|
||||
for (int i = 0; i < m.length; i++) {
|
||||
assertEquals(msg + " " + i + " elements differ", m[i],n[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.linear.decomposition;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.apache.commons.math.TestUtils;
|
||||
import org.apache.commons.math.fraction.Fraction;
|
||||
import org.apache.commons.math.fraction.FractionField;
|
||||
import org.apache.commons.math.linear.FieldMatrix;
|
||||
import org.apache.commons.math.linear.FieldMatrixImpl;
|
||||
import org.apache.commons.math.linear.InvalidMatrixException;
|
||||
|
||||
public class FieldLUDecompositionImplTest extends TestCase {
|
||||
private Fraction[][] testData = {
|
||||
{ new Fraction(1), new Fraction(2), new Fraction(3)},
|
||||
{ new Fraction(2), new Fraction(5), new Fraction(3)},
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(8)}
|
||||
};
|
||||
private Fraction[][] testDataMinus = {
|
||||
{ new Fraction(-1), new Fraction(-2), new Fraction(-3)},
|
||||
{ new Fraction(-2), new Fraction(-5), new Fraction(-3)},
|
||||
{ new Fraction(-1), new Fraction(0), new Fraction(-8)}
|
||||
};
|
||||
private Fraction[][] luData = {
|
||||
{ new Fraction(2), new Fraction(3), new Fraction(3) },
|
||||
{ new Fraction(2), new Fraction(3), new Fraction(7) },
|
||||
{ new Fraction(6), new Fraction(6), new Fraction(8) }
|
||||
};
|
||||
|
||||
// singular matrices
|
||||
private Fraction[][] singular = {
|
||||
{ new Fraction(2), new Fraction(3) },
|
||||
{ new Fraction(2), new Fraction(3) }
|
||||
};
|
||||
private Fraction[][] bigSingular = {
|
||||
{ new Fraction(1), new Fraction(2), new Fraction(3), new Fraction(4) },
|
||||
{ new Fraction(2), new Fraction(5), new Fraction(3), new Fraction(4) },
|
||||
{ new Fraction(7), new Fraction(3), new Fraction(256), new Fraction(1930) },
|
||||
{ new Fraction(3), new Fraction(7), new Fraction(6), new Fraction(8) }
|
||||
}; // 4th row = 1st + 2nd
|
||||
|
||||
public FieldLUDecompositionImplTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(FieldLUDecompositionImplTest.class);
|
||||
suite.setName("FieldLUDecompositionImpl Tests");
|
||||
return suite;
|
||||
}
|
||||
|
||||
/** test dimensions */
|
||||
public void testDimensions() {
|
||||
FieldMatrix<Fraction> matrix = new FieldMatrixImpl<Fraction>(testData);
|
||||
FieldLUDecomposition<Fraction> LU = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
assertEquals(testData.length, LU.getL().getRowDimension());
|
||||
assertEquals(testData.length, LU.getL().getColumnDimension());
|
||||
assertEquals(testData.length, LU.getU().getRowDimension());
|
||||
assertEquals(testData.length, LU.getU().getColumnDimension());
|
||||
assertEquals(testData.length, LU.getP().getRowDimension());
|
||||
assertEquals(testData.length, LU.getP().getColumnDimension());
|
||||
|
||||
}
|
||||
|
||||
/** test non-square matrix */
|
||||
public void testNonSquare() {
|
||||
try {
|
||||
new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ Fraction.ZERO, Fraction.ZERO },
|
||||
{ Fraction.ZERO, Fraction.ZERO },
|
||||
{ Fraction.ZERO, Fraction.ZERO }
|
||||
}));
|
||||
} catch (InvalidMatrixException ime) {
|
||||
// expected behavior
|
||||
} catch (Exception e) {
|
||||
fail("wrong exception caught");
|
||||
}
|
||||
}
|
||||
|
||||
/** test PA = LU */
|
||||
public void testPAEqualLU() {
|
||||
FieldMatrix<Fraction> matrix = new FieldMatrixImpl<Fraction>(testData);
|
||||
FieldLUDecomposition<Fraction> lu = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
FieldMatrix<Fraction> l = lu.getL();
|
||||
FieldMatrix<Fraction> u = lu.getU();
|
||||
FieldMatrix<Fraction> p = lu.getP();
|
||||
TestUtils.assertEquals(p.multiply(matrix), l.multiply(u));
|
||||
|
||||
matrix = new FieldMatrixImpl<Fraction>(testDataMinus);
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
l = lu.getL();
|
||||
u = lu.getU();
|
||||
p = lu.getP();
|
||||
TestUtils.assertEquals(p.multiply(matrix), l.multiply(u));
|
||||
|
||||
matrix = new FieldMatrixImpl<Fraction>(FractionField.getInstance(), 17, 17);
|
||||
for (int i = 0; i < matrix.getRowDimension(); ++i) {
|
||||
matrix.setEntry(i, i, Fraction.ONE);
|
||||
}
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
l = lu.getL();
|
||||
u = lu.getU();
|
||||
p = lu.getP();
|
||||
TestUtils.assertEquals(p.multiply(matrix), l.multiply(u));
|
||||
|
||||
matrix = new FieldMatrixImpl<Fraction>(singular);
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
assertFalse(lu.getSolver().isNonSingular());
|
||||
assertNull(lu.getL());
|
||||
assertNull(lu.getU());
|
||||
assertNull(lu.getP());
|
||||
|
||||
matrix = new FieldMatrixImpl<Fraction>(bigSingular);
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(matrix);
|
||||
assertFalse(lu.getSolver().isNonSingular());
|
||||
assertNull(lu.getL());
|
||||
assertNull(lu.getU());
|
||||
assertNull(lu.getP());
|
||||
|
||||
}
|
||||
|
||||
/** test that L is lower triangular with unit diagonal */
|
||||
public void testLLowerTriangular() {
|
||||
FieldMatrix<Fraction> matrix = new FieldMatrixImpl<Fraction>(testData);
|
||||
FieldMatrix<Fraction> l = new FieldLUDecompositionImpl<Fraction>(matrix).getL();
|
||||
for (int i = 0; i < l.getRowDimension(); i++) {
|
||||
assertEquals(Fraction.ONE, l.getEntry(i, i));
|
||||
for (int j = i + 1; j < l.getColumnDimension(); j++) {
|
||||
assertEquals(Fraction.ZERO, l.getEntry(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** test that U is upper triangular */
|
||||
public void testUUpperTriangular() {
|
||||
FieldMatrix<Fraction> matrix = new FieldMatrixImpl<Fraction>(testData);
|
||||
FieldMatrix<Fraction> u = new FieldLUDecompositionImpl<Fraction>(matrix).getU();
|
||||
for (int i = 0; i < u.getRowDimension(); i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
assertEquals(Fraction.ZERO, u.getEntry(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** test that P is a permutation matrix */
|
||||
public void testPPermutation() {
|
||||
FieldMatrix<Fraction> matrix = new FieldMatrixImpl<Fraction>(testData);
|
||||
FieldMatrix<Fraction> p = new FieldLUDecompositionImpl<Fraction>(matrix).getP();
|
||||
|
||||
FieldMatrix<Fraction> ppT = p.multiply(p.transpose());
|
||||
FieldMatrix<Fraction> id =
|
||||
new FieldMatrixImpl<Fraction>(FractionField.getInstance(),
|
||||
p.getRowDimension(), p.getRowDimension());
|
||||
for (int i = 0; i < id.getRowDimension(); ++i) {
|
||||
id.setEntry(i, i, Fraction.ONE);
|
||||
}
|
||||
TestUtils.assertEquals(id, ppT);
|
||||
|
||||
for (int i = 0; i < p.getRowDimension(); i++) {
|
||||
int zeroCount = 0;
|
||||
int oneCount = 0;
|
||||
int otherCount = 0;
|
||||
for (int j = 0; j < p.getColumnDimension(); j++) {
|
||||
final Fraction e = p.getEntry(i, j);
|
||||
if (e.equals(Fraction.ZERO)) {
|
||||
++zeroCount;
|
||||
} else if (e.equals(Fraction.ONE)) {
|
||||
++oneCount;
|
||||
} else {
|
||||
++otherCount;
|
||||
}
|
||||
}
|
||||
assertEquals(p.getColumnDimension() - 1, zeroCount);
|
||||
assertEquals(1, oneCount);
|
||||
assertEquals(0, otherCount);
|
||||
}
|
||||
|
||||
for (int j = 0; j < p.getColumnDimension(); j++) {
|
||||
int zeroCount = 0;
|
||||
int oneCount = 0;
|
||||
int otherCount = 0;
|
||||
for (int i = 0; i < p.getRowDimension(); i++) {
|
||||
final Fraction e = p.getEntry(i, j);
|
||||
if (e.equals(Fraction.ZERO)) {
|
||||
++zeroCount;
|
||||
} else if (e.equals(Fraction.ONE)) {
|
||||
++oneCount;
|
||||
} else {
|
||||
++otherCount;
|
||||
}
|
||||
}
|
||||
assertEquals(p.getRowDimension() - 1, zeroCount);
|
||||
assertEquals(1, oneCount);
|
||||
assertEquals(0, otherCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** test singular */
|
||||
public void testSingular() {
|
||||
FieldLUDecomposition<Fraction> lu =
|
||||
new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(testData));
|
||||
assertTrue(lu.getSolver().isNonSingular());
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(singular));
|
||||
assertFalse(lu.getSolver().isNonSingular());
|
||||
lu = new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(bigSingular));
|
||||
assertFalse(lu.getSolver().isNonSingular());
|
||||
}
|
||||
|
||||
/** test matrices values */
|
||||
public void testMatricesValues1() {
|
||||
FieldLUDecomposition<Fraction> lu =
|
||||
new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(testData));
|
||||
FieldMatrix<Fraction> lRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(0) },
|
||||
{ new Fraction(2), new Fraction(1), new Fraction(0) },
|
||||
{ new Fraction(1), new Fraction(-2), new Fraction(1) }
|
||||
});
|
||||
FieldMatrix<Fraction> uRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(1), new Fraction(2), new Fraction(3) },
|
||||
{ new Fraction(0), new Fraction(1), new Fraction(-3) },
|
||||
{ new Fraction(0), new Fraction(0), new Fraction(-1) }
|
||||
});
|
||||
FieldMatrix<Fraction> pRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(0) },
|
||||
{ new Fraction(0), new Fraction(1), new Fraction(0) },
|
||||
{ new Fraction(0), new Fraction(0), new Fraction(1) }
|
||||
});
|
||||
int[] pivotRef = { 0, 1, 2 };
|
||||
|
||||
// check values against known references
|
||||
FieldMatrix<Fraction> l = lu.getL();
|
||||
TestUtils.assertEquals(lRef, l);
|
||||
FieldMatrix<Fraction> u = lu.getU();
|
||||
TestUtils.assertEquals(uRef, u);
|
||||
FieldMatrix<Fraction> p = lu.getP();
|
||||
TestUtils.assertEquals(pRef, p);
|
||||
int[] pivot = lu.getPivot();
|
||||
for (int i = 0; i < pivotRef.length; ++i) {
|
||||
assertEquals(pivotRef[i], pivot[i]);
|
||||
}
|
||||
|
||||
// check the same cached instance is returned the second time
|
||||
assertTrue(l == lu.getL());
|
||||
assertTrue(u == lu.getU());
|
||||
assertTrue(p == lu.getP());
|
||||
|
||||
}
|
||||
|
||||
/** test matrices values */
|
||||
public void testMatricesValues2() {
|
||||
FieldLUDecomposition<Fraction> lu =
|
||||
new FieldLUDecompositionImpl<Fraction>(new FieldMatrixImpl<Fraction>(luData));
|
||||
FieldMatrix<Fraction> lRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(0) },
|
||||
{ new Fraction(3), new Fraction(1), new Fraction(0) },
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(1) }
|
||||
});
|
||||
FieldMatrix<Fraction> uRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(2), new Fraction(3), new Fraction(3) },
|
||||
{ new Fraction(0), new Fraction(-3), new Fraction(-1) },
|
||||
{ new Fraction(0), new Fraction(0), new Fraction(4) }
|
||||
});
|
||||
FieldMatrix<Fraction> pRef = new FieldMatrixImpl<Fraction>(new Fraction[][] {
|
||||
{ new Fraction(1), new Fraction(0), new Fraction(0) },
|
||||
{ new Fraction(0), new Fraction(0), new Fraction(1) },
|
||||
{ new Fraction(0), new Fraction(1), new Fraction(0) }
|
||||
});
|
||||
int[] pivotRef = { 0, 2, 1 };
|
||||
|
||||
// check values against known references
|
||||
FieldMatrix<Fraction> l = lu.getL();
|
||||
TestUtils.assertEquals(lRef, l);
|
||||
FieldMatrix<Fraction> u = lu.getU();
|
||||
TestUtils.assertEquals(uRef, u);
|
||||
FieldMatrix<Fraction> p = lu.getP();
|
||||
TestUtils.assertEquals(pRef, p);
|
||||
int[] pivot = lu.getPivot();
|
||||
for (int i = 0; i < pivotRef.length; ++i) {
|
||||
assertEquals(pivotRef[i], pivot[i]);
|
||||
}
|
||||
|
||||
// check the same cached instance is returned the second time
|
||||
assertTrue(l == lu.getL());
|
||||
assertTrue(u == lu.getU());
|
||||
assertTrue(p == lu.getP());
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue