Author: erans Date: Sat Dec 29 13:11:51 2012 New Revision: 1426757 URL: http://svn.apache.org/viewvc?rev=1426757&view=rev Log: MATH-925 Minimal implementation of a diagonal matrix. Unit tests are lacking.
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java (with props) Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java?rev=1426757&view=auto ============================================================================== --- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java (added) +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java Sat Dec 29 13:11:51 2012 @@ -0,0 +1,376 @@ +/* + * 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.math3.linear; + +import java.io.Serializable; +import org.apache.commons.math3.exception.DimensionMismatchException; +import org.apache.commons.math3.exception.NotStrictlyPositiveException; +import org.apache.commons.math3.exception.OutOfRangeException; +import org.apache.commons.math3.exception.MathUnsupportedOperationException; + +/** + * Implementation of a diagonal matrix. + * <br/> + * Caveat: This implementation is minimal; it is currently solely aimed + * at solving issue MATH-924. In particular many methods just throw + * {@code MathUnsupportedOperationException}. + * + * @version $Id$ + */ +public class DiagonalMatrix extends AbstractRealMatrix + implements Serializable { + /** Serializable version identifier. */ + private static final long serialVersionUID = 20121229L; + /** Entries of the diagonal. */ + private double[] data; + + /** + * Creates a matrix with no data. + */ + public DiagonalMatrix() {} + + /** + * Creates a matrix with the supplied dimension. + * + * @param dimension Number of rows and columns in the new matrix. + * @param columnDimension Number of columns in the new matrix. + * @throws NotStrictlyPositiveException if the dimension is + * not positive. + */ + public DiagonalMatrix(final int dimension) + throws NotStrictlyPositiveException { + super(dimension, dimension); + data = new double[dimension]; + } + + /** + * Creates a matrix using the input array as the underlying data. + * <br/> + * The input array is copied, not referenced. + * + * @param d Data for the new matrix. + */ + public DiagonalMatrix(final double[] d) { + data = d.clone(); + } + + /** + * Creates a matrix using the input array as the underlying data. + * <br/> + * If an array is built specially in order to be embedded in a + * RealMatrix and not used directly, the {@code copyArray} may be + * set to {@code false}. This will prevent the copying and improve + * performance as no new array will be built and no data will be copied. + * + * @param d Data for new matrix. + * @param copyArray if {@code true}, the input array will be copied, + * otherwise it will be referenced. + */ + public DiagonalMatrix(final double[] d, final boolean copyArray) { + data = copyArray ? d.clone() : d; + } + + /** + * {@inheritDoc} + * + * @throws DimensionMismatchException if the requested dimensions are not equal. + */ + @Override + public RealMatrix createMatrix(final int rowDimension, + final int columnDimension) + throws NotStrictlyPositiveException, + DimensionMismatchException { + if (rowDimension != columnDimension) { + throw new DimensionMismatchException(rowDimension, columnDimension); + } + + return new DiagonalMatrix(rowDimension); + } + + /** {@inheritDoc} */ + @Override + public RealMatrix copy() { + return new DiagonalMatrix(data); + } + + /** + * Compute the sum of {@code this} and {@code m}. + * + * @param m Matrix to be added. + * @return {@code this + m}. + * @throws MatrixDimensionMismatchException if {@code m} is not the same + * size as {@code this}. + */ + public DiagonalMatrix add(final DiagonalMatrix m) + throws MatrixDimensionMismatchException { + // Safety check. + MatrixUtils.checkAdditionCompatible(this, m); + + final int dim = getRowDimension(); + final double[] outData = new double[dim]; + for (int i = 0; i < dim; i++) { + outData[i] = data[i] + m.data[i]; + } + + return new DiagonalMatrix(outData, false); + } + + /** + * Returns {@code this} minus {@code m}. + * + * @param m Matrix to be subtracted. + * @return {@code this - m} + * @throws MatrixDimensionMismatchException if {@code m} is not the same + * size as {@code this}. + */ + public DiagonalMatrix subtract(final DiagonalMatrix m) + throws MatrixDimensionMismatchException { + MatrixUtils.checkSubtractionCompatible(this, m); + + final int dim = getRowDimension(); + final double[] outData = new double[dim]; + for (int i = 0; i < dim; i++) { + outData[i] = data[i] - m.data[i]; + } + + return new DiagonalMatrix(outData, false); + } + + /** + * Returns the result of postmultiplying {@code this} by {@code m}. + * + * @param m matrix to postmultiply by + * @return {@code this * m} + * @throws DimensionMismatchException if + * {@code columnDimension(this) != rowDimension(m)} + */ + public DiagonalMatrix multiply(final DiagonalMatrix m) + throws DimensionMismatchException { + MatrixUtils.checkMultiplicationCompatible(this, m); + + final int dim = getRowDimension(); + final double[] outData = new double[dim]; + for (int i = 0; i < dim; i++) { + outData[i] = data[i] * m.data[i]; + } + + return new DiagonalMatrix(outData, false); + } + + /** + * Returns the result of postmultiplying {@code this} by {@code m}. + * + * @param m matrix to postmultiply by + * @return {@code this * m} + * @throws DimensionMismatchException if + * {@code columnDimension(this) != rowDimension(m)} + */ + public RealMatrix multiply(final RealMatrix m) + throws DimensionMismatchException { + if (m instanceof DiagonalMatrix) { + return multiply((DiagonalMatrix) m); + } else { + MatrixUtils.checkMultiplicationCompatible(this, m); + final int nRows = m.getRowDimension(); + final int nCols = m.getColumnDimension(); + final double[][] product = new double[nRows][nCols]; + for (int r = 0; r < nRows; r++) { + for (int c = 0; c < nCols; c++) { + product[r][c] = data[r] * m.getEntry(r, c); + } + } + return new Array2DRowRealMatrix(product, false); + } + } + + /** {@inheritDoc} */ + @Override + public double[][] getData() { + final int dim = getRowDimension(); + final double[][] out = new double[dim][dim]; + + for (int i = 0; i < dim; i++) { + out[i][i] = data[i]; + } + + return out; + } + + /** + * Gets a reference to the underlying data array. + * + * @return 1-dimensional array of entries. + */ + public double[] getDataRef() { + return data; + } + + /** + * @throws MathUnsupportedOperationException + */ + @Override + public void setSubMatrix(final double[][] subMatrix, + final int row, + final int column) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double getEntry(final int row, final int column) + throws OutOfRangeException { + MatrixUtils.checkMatrixIndex(this, row, column); + return row == column ? data[row] : 0; + } + + /** {@inheritDoc} + * @throws MathUnsupportedOperationException if {@code row != column}. + */ + @Override + public void setEntry(final int row, final int column, final double value) + throws OutOfRangeException, + MathUnsupportedOperationException { + if (row != column) { + throw new MathUnsupportedOperationException(); + } + MatrixUtils.checkMatrixIndex(this, row, column); + data[row] = value; + } + + /** {@inheritDoc} + * @throws MathUnsupportedOperationException if {@code row != column}. + */ + @Override + public void addToEntry(final int row, + final int column, + final double increment) + throws OutOfRangeException, + MathUnsupportedOperationException { + if (row != column) { + throw new MathUnsupportedOperationException(); + } + MatrixUtils.checkMatrixIndex(this, row, column); + data[row] += increment; + } + + /** {@inheritDoc} + * @throws MathUnsupportedOperationException if {@code row != column}. + */ + @Override + public void multiplyEntry(final int row, + final int column, + final double factor) + throws OutOfRangeException, + MathUnsupportedOperationException { + if (row != column) { + throw new MathUnsupportedOperationException(); + } + MatrixUtils.checkMatrixIndex(this, row, column); + data[row] *= factor; + } + + /** {@inheritDoc} */ + @Override + public int getRowDimension() { + return data == null ? 0 : data.length; + } + + /** {@inheritDoc} */ + @Override + public int getColumnDimension() { + return getRowDimension(); + } + + /** {@inheritDoc} */ + @Override + public double[] operate(final double[] v) + throws DimensionMismatchException { + return multiply(new DiagonalMatrix(v, false)).getDataRef(); + } + + /** {@inheritDoc} */ + @Override + public double[] preMultiply(final double[] v) + throws DimensionMismatchException { + return operate(v); + } + + /** {@inheritDoc} */ + @Override + public double walkInRowOrder(final RealMatrixChangingVisitor visitor) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInRowOrder(final RealMatrixPreservingVisitor visitor) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInRowOrder(final RealMatrixChangingVisitor visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInRowOrder(final RealMatrixPreservingVisitor visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInColumnOrder(final RealMatrixChangingVisitor visitor) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInColumnOrder(final RealMatrixChangingVisitor visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override + public double walkInColumnOrder(final RealMatrixPreservingVisitor visitor, + final int startRow, final int endRow, + final int startColumn, final int endColumn) + throws MathUnsupportedOperationException { + throw new MathUnsupportedOperationException(); + } +} Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/DiagonalMatrix.java ------------------------------------------------------------------------------ svn:eol-style = native