Author: luc Date: Sun Apr 19 16:39:40 2009 New Revision: 766485 URL: http://svn.apache.org/viewvc?rev=766485&view=rev Log: 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
Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldMatrix.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldMatrixChangingVisitor.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldMatrixImpl.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldMatrixPreservingVisitor.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVector.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/FieldVectorImpl.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldDecompositionSolver.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecomposition.java (with props) commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImpl.java (with props) commons/proper/math/trunk/src/test/org/apache/commons/math/linear/FieldMatrixImplTest.java (with props) commons/proper/math/trunk/src/test/org/apache/commons/math/linear/FieldVectorImplTest.java (with props) commons/proper/math/trunk/src/test/org/apache/commons/math/linear/decomposition/FieldLUDecompositionImplTest.java (with props) Modified: commons/proper/math/trunk/findbugs-exclude-filter.xml commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrix.java commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrixImpl.java commons/proper/math/trunk/src/java/org/apache/commons/math/linear/decomposition/LUDecompositionImpl.java commons/proper/math/trunk/src/site/xdoc/changes.xml commons/proper/math/trunk/src/site/xdoc/userguide/index.xml commons/proper/math/trunk/src/site/xdoc/userguide/linear.xml commons/proper/math/trunk/src/test/org/apache/commons/math/TestUtils.java commons/proper/math/trunk/src/test/org/apache/commons/math/linear/BigMatrixImplTest.java Modified: commons/proper/math/trunk/findbugs-exclude-filter.xml URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/findbugs-exclude-filter.xml?rev=766485&r1=766484&r2=766485&view=diff ============================================================================== --- commons/proper/math/trunk/findbugs-exclude-filter.xml (original) +++ commons/proper/math/trunk/findbugs-exclude-filter.xml Sun Apr 19 16:39:40 2009 @@ -110,6 +110,16 @@ <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" /> <Bug pattern="EI_EXPOSE_REP2" /> @@ -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> Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=766485&r1=766484&r2=766485&view=diff ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java (original) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java Sun Apr 19 16:39:40 2009 @@ -230,6 +230,12 @@ { "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 @@ "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 @@ "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)", Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java?rev=766485&view=auto ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java (added) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java Sun Apr 19 16:39:40 2009 @@ -0,0 +1,1088 @@ +/* + * 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 org.apache.commons.math.Field; +import org.apache.commons.math.FieldElement; +import org.apache.commons.math.MathRuntimeException; +import org.apache.commons.math.linear.decomposition.NonSquareMatrixException; + +/** + * Basic implementation of {...@link FieldMatrix} methods regardless of the underlying storage. + * <p>All the methods implemented here use {...@link #getEntry(int, int)} to access + * matrix elements. Derived class can provide faster implementations. </p> + * + * @param <T> the type of the field elements + * @version $Revision$ $Date$ + * @since 2.0 + */ +public abstract class AbstractFieldMatrix<T extends FieldElement<T>> implements FieldMatrix<T>, Serializable { + + /** Serializable version identifier. */ + private static final long serialVersionUID = -3665653040524315561L; + + /** Field to which the elements belong. */ + private final Field<T> field; + + /** Build an array of elements. + * @param rows number of rows + * @param columns number of columns + * @return a new array + */ + @SuppressWarnings("unchecked") + protected T[][] buildArray(final int rows, final int columns) { + return (T[][]) Array.newInstance(field.getZero().getClass(), new int[] { rows, columns }); + } + + /** Build an array of elements. + * @param length of the array + * @return a new array + */ + @SuppressWarnings("unchecked") + protected T[] buildArray(final int length) { + return (T[]) Array.newInstance(field.getZero().getClass(), length); + } + + /** + * Creates a matrix with no data + * @param field field to which the elements belong + */ + protected AbstractFieldMatrix(final Field<T> field) { + this.field = 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 + */ + protected AbstractFieldMatrix(final Field<T> field, + final int rowDimension, final int columnDimension) + throws IllegalArgumentException { + if (rowDimension <= 0 ) { + throw MathRuntimeException.createIllegalArgumentException( + "invalid row dimension {0} (must be positive)", + rowDimension); + } + if (columnDimension <= 0) { + throw MathRuntimeException.createIllegalArgumentException( + "invalid column dimension {0} (must be positive)", + columnDimension); + } + this.field = field; + } + + /** {...@inheritdoc} */ + public Field<T> getField() { + return field; + } + + /** {...@inheritdoc} */ + public abstract FieldMatrix<T> createMatrix(final int rowDimension, final int columnDimension) + throws IllegalArgumentException; + + /** {...@inheritdoc} */ + public abstract FieldMatrix<T> copy(); + + /** {...@inheritdoc} */ + public FieldMatrix<T> add(FieldMatrix<T> m) throws IllegalArgumentException { + + // safety check + checkAdditionCompatible(m); + + final int rowCount = getRowDimension(); + final int columnCount = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(rowCount, columnCount); + for (int row = 0; row < rowCount; ++row) { + for (int col = 0; col < columnCount; ++col) { + out.setEntry(row, col, getEntry(row, col).add(m.getEntry(row, col))); + } + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> subtract(final FieldMatrix<T> m) throws IllegalArgumentException { + + // safety check + checkSubtractionCompatible(m); + + final int rowCount = getRowDimension(); + final int columnCount = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(rowCount, columnCount); + for (int row = 0; row < rowCount; ++row) { + for (int col = 0; col < columnCount; ++col) { + out.setEntry(row, col, getEntry(row, col).subtract(m.getEntry(row, col))); + } + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> scalarAdd(final T d) { + + final int rowCount = getRowDimension(); + final int columnCount = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(rowCount, columnCount); + for (int row = 0; row < rowCount; ++row) { + for (int col = 0; col < columnCount; ++col) { + out.setEntry(row, col, getEntry(row, col).add(d)); + } + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> scalarMultiply(final T d) { + + final int rowCount = getRowDimension(); + final int columnCount = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(rowCount, columnCount); + for (int row = 0; row < rowCount; ++row) { + for (int col = 0; col < columnCount; ++col) { + out.setEntry(row, col, getEntry(row, col).multiply(d)); + } + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> multiply(final FieldMatrix<T> m) + throws IllegalArgumentException { + + // safety check + checkMultiplicationCompatible(m); + + final int nRows = getRowDimension(); + final int nCols = m.getColumnDimension(); + final int nSum = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(nRows, nCols); + for (int row = 0; row < nRows; ++row) { + for (int col = 0; col < nCols; ++col) { + T sum = field.getZero(); + for (int i = 0; i < nSum; ++i) { + sum = sum.add(getEntry(row, i).multiply(m.getEntry(i, col))); + } + out.setEntry(row, col, sum); + } + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> preMultiply(final FieldMatrix<T> m) + throws IllegalArgumentException { + return m.multiply(this); + } + + /** {...@inheritdoc} */ + public T[][] getData() { + + final T[][] data = buildArray(getRowDimension(), getColumnDimension()); + + for (int i = 0; i < data.length; ++i) { + final T[] dataI = data[i]; + for (int j = 0; j < dataI.length; ++j) { + dataI[j] = getEntry(i, j); + } + } + + return data; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MatrixIndexException { + + checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); + + final FieldMatrix<T> subMatrix = + createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); + for (int i = startRow; i <= endRow; ++i) { + for (int j = startColumn; j <= endColumn; ++j) { + subMatrix.setEntry(i - startRow, j - startColumn, getEntry(i, j)); + } + } + + return subMatrix; + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> getSubMatrix(final int[] selectedRows, final int[] selectedColumns) + throws MatrixIndexException { + + // safety checks + checkSubMatrixIndex(selectedRows, selectedColumns); + + // copy entries + final FieldMatrix<T> subMatrix = + createMatrix(selectedRows.length, selectedColumns.length); + subMatrix.walkInOptimizedOrder(new DefaultFieldMatrixChangingVisitor<T>(field.getZero()) { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 5079316658710707181L; + + /** {...@inheritdoc} */ + @Override + public T visit(final int row, final int column, final T value) { + return getEntry(selectedRows[row], selectedColumns[column]); + } + + }); + + return subMatrix; + + } + + /** {...@inheritdoc} */ + public void copySubMatrix(final int startRow, final int endRow, + final int startColumn, final int endColumn, + final T[][] destination) + throws MatrixIndexException, IllegalArgumentException { + + // safety checks + checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); + final int rowsCount = endRow + 1 - startRow; + final int columnsCount = endColumn + 1 - startColumn; + if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) { + throw MathRuntimeException.createIllegalArgumentException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + destination.length, destination[0].length, + rowsCount, columnsCount); + } + + // copy entries + walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 1894428776156078725L; + + /** Initial row index. */ + private int startRow; + + /** Initial column index. */ + private int startColumn; + + /** {...@inheritdoc} */ + @Override + public void start(final int rows, final int columns, + final int startRow, final int endRow, + final int startColumn, final int endColumn) { + this.startRow = startRow; + this.startColumn = startColumn; + } + + /** {...@inheritdoc} */ + @Override + public void visit(final int row, final int column, final T value) { + destination[row - startRow][column - startColumn] = value; + } + + }, startRow, endRow, startColumn, endColumn); + + } + + /** {...@inheritdoc} */ + public void copySubMatrix(int[] selectedRows, int[] selectedColumns, T[][] destination) + throws MatrixIndexException, IllegalArgumentException { + + // safety checks + checkSubMatrixIndex(selectedRows, selectedColumns); + if ((destination.length < selectedRows.length) || + (destination[0].length < selectedColumns.length)) { + throw MathRuntimeException.createIllegalArgumentException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + destination.length, destination[0].length, + selectedRows.length, selectedColumns.length); + } + + // copy entries + for (int i = 0; i < selectedRows.length; i++) { + final T[] destinationI = destination[i]; + for (int j = 0; j < selectedColumns.length; j++) { + destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]); + } + } + + } + + /** {...@inheritdoc} */ + public void setSubMatrix(final T[][] subMatrix, final int row, final int column) + throws MatrixIndexException { + + 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"); + } + + for (int r = 1; r < nRows; ++r) { + if (subMatrix[r].length != nCols) { + throw MathRuntimeException.createIllegalArgumentException( + "some rows have length {0} while others have length {1}", + nCols, subMatrix[r].length); + } + } + + checkRowIndex(row); + checkColumnIndex(column); + checkRowIndex(nRows + row - 1); + checkColumnIndex(nCols + column - 1); + + for (int i = 0; i < nRows; ++i) { + for (int j = 0; j < nCols; ++j) { + setEntry(row + i, column + j, subMatrix[i][j]); + } + } + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> getRowMatrix(final int row) + throws MatrixIndexException { + + checkRowIndex(row); + final int nCols = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(1, nCols); + for (int i = 0; i < nCols; ++i) { + out.setEntry(0, i, getEntry(row, i)); + } + + return out; + + } + + /** {...@inheritdoc} */ + public void setRowMatrix(final int row, final FieldMatrix<T> matrix) + throws MatrixIndexException, InvalidMatrixException { + + checkRowIndex(row); + final int nCols = getColumnDimension(); + if ((matrix.getRowDimension() != 1) || + (matrix.getColumnDimension() != nCols)) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + matrix.getRowDimension(), matrix.getColumnDimension(), 1, nCols); + } + for (int i = 0; i < nCols; ++i) { + setEntry(row, i, matrix.getEntry(0, i)); + } + + } + + /** {...@inheritdoc} */ + public FieldMatrix<T> getColumnMatrix(final int column) + throws MatrixIndexException { + + checkColumnIndex(column); + final int nRows = getRowDimension(); + final FieldMatrix<T> out = createMatrix(nRows, 1); + for (int i = 0; i < nRows; ++i) { + out.setEntry(i, 0, getEntry(i, column)); + } + + return out; + + } + + /** {...@inheritdoc} */ + public void setColumnMatrix(final int column, final FieldMatrix<T> matrix) + throws MatrixIndexException, InvalidMatrixException { + + checkColumnIndex(column); + final int nRows = getRowDimension(); + if ((matrix.getRowDimension() != nRows) || + (matrix.getColumnDimension() != 1)) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + matrix.getRowDimension(), matrix.getColumnDimension(), nRows, 1); + } + for (int i = 0; i < nRows; ++i) { + setEntry(i, column, matrix.getEntry(i, 0)); + } + + } + + /** {...@inheritdoc} */ + public FieldVector<T> getRowVector(final int row) + throws MatrixIndexException { + return new FieldVectorImpl<T>(getRow(row), false); + } + + /** {...@inheritdoc} */ + public void setRowVector(final int row, final FieldVector<T> vector) + throws MatrixIndexException, InvalidMatrixException { + + checkRowIndex(row); + final int nCols = getColumnDimension(); + if (vector.getDimension() != nCols) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + 1, vector.getDimension(), 1, nCols); + } + for (int i = 0; i < nCols; ++i) { + setEntry(row, i, vector.getEntry(i)); + } + + } + + /** {...@inheritdoc} */ + public FieldVector<T> getColumnVector(final int column) + throws MatrixIndexException { + return new FieldVectorImpl<T>(getColumn(column), false); + } + + /** {...@inheritdoc} */ + public void setColumnVector(final int column, final FieldVector<T> vector) + throws MatrixIndexException, InvalidMatrixException { + + checkColumnIndex(column); + final int nRows = getRowDimension(); + if (vector.getDimension() != nRows) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + vector.getDimension(), 1, nRows, 1); + } + for (int i = 0; i < nRows; ++i) { + setEntry(i, column, vector.getEntry(i)); + } + + } + + /** {...@inheritdoc} */ + public T[] getRow(final int row) + throws MatrixIndexException { + + checkRowIndex(row); + final int nCols = getColumnDimension(); + final T[] out = buildArray(nCols); + for (int i = 0; i < nCols; ++i) { + out[i] = getEntry(row, i); + } + + return out; + + } + + /** {...@inheritdoc} */ + public void setRow(final int row, final T[] array) + throws MatrixIndexException, InvalidMatrixException { + + checkRowIndex(row); + final int nCols = getColumnDimension(); + if (array.length != nCols) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + 1, array.length, 1, nCols); + } + for (int i = 0; i < nCols; ++i) { + setEntry(row, i, array[i]); + } + + } + + /** {...@inheritdoc} */ + public T[] getColumn(final int column) + throws MatrixIndexException { + + checkColumnIndex(column); + final int nRows = getRowDimension(); + final T[] out = buildArray(nRows); + for (int i = 0; i < nRows; ++i) { + out[i] = getEntry(i, column); + } + + return out; + + } + + /** {...@inheritdoc} */ + public void setColumn(final int column, final T[] array) + throws MatrixIndexException, InvalidMatrixException { + + checkColumnIndex(column); + final int nRows = getRowDimension(); + if (array.length != nRows) { + throw new InvalidMatrixException( + "dimensions mismatch: got {0}x{1} but expected {2}x{3}", + array.length, 1, nRows, 1); + } + for (int i = 0; i < nRows; ++i) { + setEntry(i, column, array[i]); + } + + } + + /** {...@inheritdoc} */ + public abstract T getEntry(int row, int column) + throws MatrixIndexException; + + /** {...@inheritdoc} */ + public abstract void setEntry(int row, int column, T value) + throws MatrixIndexException; + + /** {...@inheritdoc} */ + public abstract void addToEntry(int row, int column, T increment) + throws MatrixIndexException; + + /** {...@inheritdoc} */ + public abstract void multiplyEntry(int row, int column, T factor) + throws MatrixIndexException; + + /** {...@inheritdoc} */ + public FieldMatrix<T> transpose() { + + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + final FieldMatrix<T> out = createMatrix(nCols, nRows); + walkInOptimizedOrder(new DefaultFieldMatrixPreservingVisitor<T>(field.getZero()) { + + /** Serializable version identifier. */ + private static final long serialVersionUID = 6281961451465720534L; + + /** {...@inheritdoc} */ + @Override + public void visit(final int row, final int column, final T value) { + out.setEntry(column, row, value); + } + + }); + + return out; + + } + + /** {...@inheritdoc} */ + public boolean isSquare() { + return (getColumnDimension() == getRowDimension()); + } + + /** {...@inheritdoc} */ + public abstract int getRowDimension(); + + /** {...@inheritdoc} */ + public abstract int getColumnDimension(); + + /** {...@inheritdoc} */ + public T getTrace() + throws NonSquareMatrixException { + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + if (nRows != nCols) { + throw new NonSquareMatrixException(nRows, nCols); + } + T trace = field.getZero(); + for (int i = 0; i < nRows; ++i) { + trace = trace.add(getEntry(i, i)); + } + return trace; + } + + /** {...@inheritdoc} */ + public T[] operate(final T[] v) + throws IllegalArgumentException { + + final int nRows = getRowDimension(); + final int nCols = 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) { + T sum = field.getZero(); + for (int i = 0; i < nCols; ++i) { + sum = sum.add(getEntry(row, i).multiply(v[i])); + } + out[row] = sum; + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldVector<T> operate(final FieldVector<T> v) + throws IllegalArgumentException { + try { + return new FieldVectorImpl<T>(operate(((FieldVectorImpl<T>) v).getDataRef()), false); + } catch (ClassCastException cce) { + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + if (v.getDimension() != nCols) { + throw MathRuntimeException.createIllegalArgumentException( + "vector length mismatch: got {0} but expected {1}", + v.getDimension(), nCols); + } + + final T[] out = buildArray(nRows); + for (int row = 0; row < nRows; ++row) { + T sum = field.getZero(); + for (int i = 0; i < nCols; ++i) { + sum = sum.add(getEntry(row, i).multiply(v.getEntry(i))); + } + out[row] = sum; + } + + return new FieldVectorImpl<T>(out, false); + } + } + + /** {...@inheritdoc} */ + 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 = field.getZero(); + for (int i = 0; i < nRows; ++i) { + sum = sum.add(getEntry(i, col).multiply(v[i])); + } + out[col] = sum; + } + + return out; + + } + + /** {...@inheritdoc} */ + public FieldVector<T> preMultiply(final FieldVector<T> v) + throws IllegalArgumentException { + try { + return new FieldVectorImpl<T>(preMultiply(((FieldVectorImpl<T>) v).getDataRef()), false); + } catch (ClassCastException cce) { + + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + if (v.getDimension() != nRows) { + throw MathRuntimeException.createIllegalArgumentException( + "vector length mismatch: got {0} but expected {1}", + v.getDimension(), nRows); + } + + final T[] out = buildArray(nCols); + for (int col = 0; col < nCols; ++col) { + T sum = field.getZero(); + for (int i = 0; i < nRows; ++i) { + sum = sum.add(getEntry(i, col).multiply(v.getEntry(i))); + } + out[col] = sum; + } + + return new FieldVectorImpl<T>(out); + + } + } + + /** {...@inheritdoc} */ + 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 row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + final T oldValue = getEntry(row, column); + final T newValue = visitor.visit(row, column, oldValue); + setEntry(row, column, newValue); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + visitor.visit(row, column, getEntry(row, column)); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 row = startRow; row <= endRow; ++row) { + for (int column = startColumn; column <= endColumn; ++column) { + final T oldValue = getEntry(row, column); + final T newValue = visitor.visit(row, column, oldValue); + setEntry(row, column, newValue); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 row = startRow; row <= endRow; ++row) { + for (int column = startColumn; column <= endColumn; ++column) { + visitor.visit(row, column, getEntry(row, column)); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 column = 0; column < columns; ++column) { + for (int row = 0; row < rows; ++row) { + final T oldValue = getEntry(row, column); + final T newValue = visitor.visit(row, column, oldValue); + setEntry(row, column, newValue); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 column = 0; column < columns; ++column) { + for (int row = 0; row < rows; ++row) { + visitor.visit(row, column, getEntry(row, column)); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 column = startColumn; column <= endColumn; ++column) { + for (int row = startRow; row <= endRow; ++row) { + final T oldValue = getEntry(row, column); + final T newValue = visitor.visit(row, column, oldValue); + setEntry(row, column, newValue); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + 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 column = startColumn; column <= endColumn; ++column) { + for (int row = startRow; row <= endRow; ++row) { + visitor.visit(row, column, getEntry(row, column)); + } + } + return visitor.end(); + } + + /** {...@inheritdoc} */ + public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor) + throws MatrixVisitorException { + return walkInRowOrder(visitor); + } + + /** {...@inheritdoc} */ + public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor) + throws MatrixVisitorException { + return walkInRowOrder(visitor); + } + + /** {...@inheritdoc} */ + public T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MatrixIndexException, MatrixVisitorException { + return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); + } + + /** {...@inheritdoc} */ + public T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MatrixIndexException, MatrixVisitorException { + return walkInRowOrder(visitor, startRow, endRow, startColumn, endColumn); + } + + /** + * Get a string representation for this matrix. + * @return a string representation for this matrix + */ + @Override + public String toString() { + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + final StringBuffer res = new StringBuffer(); + String fullClassName = getClass().getName(); + String shortClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1); + res.append(shortClassName).append("{"); + + for (int i = 0; i < nRows; ++i) { + if (i > 0) { + res.append(","); + } + res.append("{"); + for (int j = 0; j < nCols; ++j) { + if (j > 0) { + res.append(","); + } + res.append(getEntry(i, j)); + } + res.append("}"); + } + + res.append("}"); + return res.toString(); + + } + + /** + * Returns true iff <code>object</code> is a + * <code>FieldMatrix</code> instance with the same dimensions as this + * and all corresponding matrix entries are equal. + * + * @param object the object to test equality against. + * @return true if object equals this + */ + @SuppressWarnings("unchecked") + @Override + public boolean equals(final Object object) { + if (object == this ) { + return true; + } + if (object instanceof FieldMatrix == false) { + return false; + } + FieldMatrix<T> m = (FieldMatrix<T>) object; + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + if (m.getColumnDimension() != nCols || m.getRowDimension() != nRows) { + return false; + } + for (int row = 0; row < nRows; ++row) { + for (int col = 0; col < nCols; ++col) { + if (!getEntry(row, col).equals(m.getEntry(row, col))) { + return false; + } + } + } + return true; + } + + /** + * Computes a hashcode for the matrix. + * + * @return hashcode for matrix + */ + @Override + public int hashCode() { + int ret = 322562; + final int nRows = getRowDimension(); + final int nCols = getColumnDimension(); + ret = ret * 31 + nRows; + ret = ret * 31 + nCols; + for (int row = 0; row < nRows; ++row) { + for (int col = 0; col < nCols; ++col) { + ret = ret * 31 + (11 * (row+1) + 17 * (col+1)) * getEntry(row, col).hashCode(); + } + } + return ret; + } + + /** + * Check if a row index is valid. + * @param row row index to check + * @exception MatrixIndexException if index is not valid + */ + protected void checkRowIndex(final int row) { + if (row < 0 || row >= getRowDimension()) { + throw new MatrixIndexException("row index {0} out of allowed range [{1}, {2}]", + row, 0, getRowDimension() - 1); + } + } + + /** + * Check if a column index is valid. + * @param column column index to check + * @exception MatrixIndexException if index is not valid + */ + protected void checkColumnIndex(final int column) + throws MatrixIndexException { + if (column < 0 || column >= getColumnDimension()) { + throw new MatrixIndexException("column index {0} out of allowed range [{1}, {2}]", + column, 0, getColumnDimension() - 1); + } + } + + /** + * Check if submatrix ranges indices are valid. + * Rows and columns are indicated counting from 0 to n-1. + * + * @param startRow Initial row index + * @param endRow Final row index + * @param startColumn Initial column index + * @param endColumn Final column index + * @exception MatrixIndexException if the indices are not valid + */ + protected void checkSubMatrixIndex(final int startRow, final int endRow, + final int startColumn, final int endColumn) { + checkRowIndex(startRow); + checkRowIndex(endRow); + if (startRow > endRow) { + throw new MatrixIndexException("initial row {0} after final row {1}", + startRow, endRow); + } + + checkColumnIndex(startColumn); + checkColumnIndex(endColumn); + if (startColumn > endColumn) { + throw new MatrixIndexException("initial column {0} after final column {1}", + startColumn, endColumn); + } + + + } + + /** + * Check if submatrix ranges indices are valid. + * Rows and columns are indicated counting from 0 to n-1. + * + * @param selectedRows Array of row indices. + * @param selectedColumns Array of column indices. + * @exception MatrixIndexException if row or column selections are not valid + */ + protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) { + if (selectedRows.length * selectedColumns.length == 0) { + if (selectedRows.length == 0) { + throw new MatrixIndexException("empty selected row index array"); + } + throw new MatrixIndexException("empty selected column index array"); + } + + for (final int row : selectedRows) { + checkRowIndex(row); + } + for (final int column : selectedColumns) { + checkColumnIndex(column); + } + } + + /** + * Check if a matrix is addition compatible with the instance + * @param m matrix to check + * @exception IllegalArgumentException if matrix is not addition compatible with instance + */ + protected void checkAdditionCompatible(final FieldMatrix<T> m) { + if ((getRowDimension() != m.getRowDimension()) || + (getColumnDimension() != m.getColumnDimension())) { + throw MathRuntimeException.createIllegalArgumentException( + "{0}x{1} and {2}x{3} matrices are not addition compatible", + getRowDimension(), getColumnDimension(), + m.getRowDimension(), m.getColumnDimension()); + } + } + + /** + * Check if a matrix is subtraction compatible with the instance + * @param m matrix to check + * @exception IllegalArgumentException if matrix is not subtraction compatible with instance + */ + protected void checkSubtractionCompatible(final FieldMatrix<T> m) { + if ((getRowDimension() != m.getRowDimension()) || + (getColumnDimension() != m.getColumnDimension())) { + throw MathRuntimeException.createIllegalArgumentException( + "{0}x{1} and {2}x{3} matrices are not subtraction compatible", + getRowDimension(), getColumnDimension(), + m.getRowDimension(), m.getColumnDimension()); + } + } + + /** + * Check if a matrix is multiplication compatible with the instance + * @param m matrix to check + * @exception IllegalArgumentException if matrix is not multiplication compatible with instance + */ + protected void checkMultiplicationCompatible(final FieldMatrix<T> m) { + if (getColumnDimension() != m.getRowDimension()) { + throw MathRuntimeException.createIllegalArgumentException( + "{0}x{1} and {2}x{3} matrices are not multiplication compatible", + getRowDimension(), getColumnDimension(), + m.getRowDimension(), m.getColumnDimension()); + } + } + +} Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/AbstractFieldMatrix.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrix.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrix.java?rev=766485&r1=766484&r2=766485&view=diff ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrix.java (original) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrix.java Sun Apr 19 16:39:40 2009 @@ -27,7 +27,10 @@ * 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 { /** Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrixImpl.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrixImpl.java?rev=766485&r1=766484&r2=766485&view=diff ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrixImpl.java (original) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/BigMatrixImpl.java Sun Apr 19 16:39:40 2009 @@ -49,8 +49,11 @@ * 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 */ Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java?rev=766485&view=auto ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java (added) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java Sun Apr 19 16:39:40 2009 @@ -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; + } + +} Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixChangingVisitor.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Added: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java?rev=766485&view=auto ============================================================================== --- commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java (added) +++ commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java Sun Apr 19 16:39:40 2009 @@ -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; + } + +} Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/math/trunk/src/java/org/apache/commons/math/linear/DefaultFieldMatrixPreservingVisitor.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision