commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Heuer <heue...@acm.org>
Subject Re: cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/linear RealMatrixImplTest.java
Date Tue, 12 Oct 2004 06:50:19 GMT

Sorry to be replying to a cvs commit message, but I think perhaps this is
taking this idea of immutability too far -- a matrix data structure isn't
very useful if you can't even modify the entries.

Wouldn't the pattern used in the Collections interfaces for modifiers be
more reasonable here?

interface RealMatrix
{
  ...

  /**
   * Sets the entry in the specified row and column to the specified
   * value (optional operation).
   *
   * ...
   * @throws UnsupportedOperationException if the <code>setEntry<code>
   *    operation is not supported by this real matrix
   */
  void setEntry(int row, int column, double value)
    ...;
}


I also wanted to mention that I feel that this interface and its
implementation seem too closely intertwined with double arrays, as if
clients of the API are going to be moving back and forth between the
two data representations regularly.

With the Collections interfaces, if I want a List, I'm going to use
one, not go back and forth between Lists and arrays.  Similarly, if I want
to use a RealMatrix, I'd like to use one, not go back and forth between it
and 1D and 2D double arrays.

   michael


On 12 Oct 2004 psteitz@apache.org wrote:

> psteitz     2004/10/11 23:19:50
>
>   Modified:    math/xdocs/userguide linear.xml
>                math/src/java/org/apache/commons/math/linear RealMatrix.java
>                         RealMatrixImpl.java
>                math/src/test/org/apache/commons/math/linear
>                         RealMatrixImplTest.java
>   Log:
>   Removed data mutators from RealMatrix interface and RealMatrixImpl.
>
>   Revision  Changes    Path
>   1.9       +4 -5      jakarta-commons/math/xdocs/userguide/linear.xml
>
>   Index: linear.xml
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/math/xdocs/userguide/linear.xml,v
>   retrieving revision 1.8
>   retrieving revision 1.9
>   diff -u -r1.8 -r1.9
>   --- linear.xml	17 May 2004 05:57:38 -0000	1.8
>   +++ linear.xml	12 Oct 2004 06:19:50 -0000	1.9
>   @@ -56,11 +56,10 @@
>
>    // One more with three rows, two columns
>    double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}};
>   -RealMatrix n = new RealMatixImpl();
>   -n.setData(matrixData2);
>   +RealMatrix n = new RealMatixImpl(matrixData2);
>
>   -// Note: both constructor and setData make
>   -// Fresh copies of input double[][] arrays
>   +// Note: constructor makes a
>   +// Fresh copy of the input double[][] array
>
>    // Now multiply m by n
>    RealMatrix p = m.multiply(n);
>
>
>
>   1.25      +1 -27     jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrix.java
>
>   Index: RealMatrix.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrix.java,v
>   retrieving revision 1.24
>   retrieving revision 1.25
>   diff -u -r1.24 -r1.25
>   --- RealMatrix.java	9 Oct 2004 22:39:22 -0000	1.24
>   +++ RealMatrix.java	12 Oct 2004 06:19:50 -0000	1.25
>   @@ -94,14 +94,6 @@
>        double[][] getData();
>
>        /**
>   -     * Overwrites the underlying data for the matrix with
>   -     * a fresh copy of <code>data</code>.
>   -     *
>   -     * @param  data  2-dimensional array of entries
>   -     */
>   -    void setData(double[][] data);
>   -
>   -    /**
>         * Returns the <a href="http://mathworld.wolfram.com/MaximumAbsoluteRowSumNorm.html">
>         * maximum absolute row sum norm</a> of the matrix.
>         *
>   @@ -197,24 +189,6 @@
>         * @throws MatrixIndexException if the row or column index is not valid
>         */
>        double getEntry(int row, int column) throws MatrixIndexException;
>   -
>   -    /**
>   -     * Sets the entry in the specified row and column to the specified value.
>   -     * <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.
>   -     *
>   -     * @param row    row location of entry to be set
>   -     * @param column    column location of entry to be set
>   -     * @param value  value to set
>   -     * @throws MatrixIndexException if the row or column index is not valid
>   -     */
>   -    void setEntry(int row, int column, double value)
>   -        throws MatrixIndexException;
>
>        /**
>         * Returns the transpose of this matrix.
>
>
>
>   1.33      +8 -57     jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrixImpl.java
>
>   Index: RealMatrixImpl.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/linear/RealMatrixImpl.java,v
>   retrieving revision 1.32
>   retrieving revision 1.33
>   diff -u -r1.32 -r1.33
>   --- RealMatrixImpl.java	10 Oct 2004 18:00:33 -0000	1.32
>   +++ RealMatrixImpl.java	12 Oct 2004 06:19:50 -0000	1.33
>   @@ -21,8 +21,8 @@
>
>
>    /**
>   - * Implementation for RealMatrix using a double[][] array to store entries
>   - * and <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
>   + * Implementation for RealMatrix using a double[][] array to store entries and
>   + * <a href="http://www.math.gatech.edu/~bourbaki/math2601/Web-notes/2num.pdf">
>     * LU decompostion</a> to support linear system
>     * solution and inverse.
>     * <p>
>   @@ -34,12 +34,11 @@
>     * <p>
>     * <strong>Usage notes</strong>:<br>
>     * <ul><li>
>   - * The LU decomposition is stored and reused on subsequent calls.  If matrix
>   - * data are modified using any of the public setXxx methods, the saved
>   - * decomposition is discarded.  If data are modified via references to the
>   - * underlying array obtained using <code>getDataRef()</code>, then the
stored
>   - * LU decomposition will not be discarded.  In this case, you need to
>   - * explicitly invoke <code>LUDecompose()</code> to recompute the decomposition
>   + * The LU decomposition is cached and reused on subsequent calls.
>   + * If data are modified via references to the underlying array obtained using
>   + * <code>getDataRef()</code>, then the stored LU decomposition will not
be
>   + * discarded.  In this case, you need to explicitly invoke
>   + * <code>LUDecompose()</code> to recompute the decomposition
>     * before using any of the methods above.</li>
>     * <li>
>     * As specified in the {@link RealMatrix} interface, matrix element indexing
>   @@ -280,17 +279,6 @@
>        }
>
>        /**
>   -     * Overwrites the underlying data for the matrix
>   -     * with a fresh copy of <code>inData</code>.
>   -     *
>   -     * @param  inData 2-dimensional array of entries
>   -     */
>   -    public void setData(double[][] inData) {
>   -        copyIn(inData);
>   -        lu = null;
>   -    }
>   -
>   -    /**
>         * Returns a reference to the underlying data array.
>         * <p>
>         * Does not make a fresh copy of the underlying data.
>   @@ -302,19 +290,6 @@
>        }
>
>        /**
>   -     * Overwrites the underlying data for the matrix
>   -     * with a reference to <code>inData</code>.
>   -     * <p>
>   -     * Does not make a fresh copy of <code>data</code>.
>   -     *
>   -     * @param  inData 2-dimensional array of entries
>   -     */
>   -    public void setDataRef(double[][] inData) {
>   -        this.data = inData;
>   -        lu = null;
>   -    }
>   -
>   -    /**
>         *
>         * @return norm
>         */
>   @@ -495,30 +470,6 @@
>                throw new MatrixIndexException("matrix entry does not exist");
>            }
>            return data[row][column];
>   -    }
>   -
>   -    /**
>   -     * Sets the entry in the specified row and column to the specified value.
>   -     * <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.
>   -     *
>   -     * @param row    row location of entry to be set
>   -     * @param column    column location of entry to be set
>   -     * @param value  value to set
>   -     * @throws MatrixIndexException if the row or column index is not valid
>   -     */
>   -    public void setEntry(int row, int column, double value)
>   -        throws MatrixIndexException {
>   -        if (!isValidCoordinate(row,column)) {
>   -            throw new MatrixIndexException("matrix entry does not exist");
>   -        }
>   -        data[row][column] = value;
>   -        lu = null;
>        }
>
>        /**
>
>
>
>   1.20      +28 -46    jakarta-commons/math/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java
>
>   Index: RealMatrixImplTest.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-commons/math/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java,v
>   retrieving revision 1.19
>   retrieving revision 1.20
>   diff -u -r1.19 -r1.20
>   --- RealMatrixImplTest.java	10 Oct 2004 18:01:16 -0000	1.19
>   +++ RealMatrixImplTest.java	12 Oct 2004 06:19:50 -0000	1.20
>   @@ -111,25 +111,13 @@
>            assertEquals("testData2 row dimension",m2.getRowDimension(),2);
>            assertEquals("testData2 column dimension",m2.getColumnDimension(),3);
>            assertTrue("testData2 is not square",!m2.isSquare());
>   -        RealMatrixImpl m3 = new RealMatrixImpl();
>   -        m3.setData(testData);
>        }
>
>        /** test copy functions */
>        public void testCopyFunctions() {
>            RealMatrixImpl m = new RealMatrixImpl(testData);
>   -        RealMatrixImpl m2 = new RealMatrixImpl(testData2);
>   -        m2.setData(m.getData());
>   -        assertClose("getData",m2,m,entryTolerance);
>   -        // no dangling reference...
>   -        m2.setEntry(1,1,2000d);
>   -        RealMatrixImpl m3 = new RealMatrixImpl(testData);
>   -        assertClose("no getData side effect",m,m3,entryTolerance);
>   -        m3 = (RealMatrixImpl) m.copy();
>   -        double[][] stompMe = {{1d,2d,3d}};
>   -        m3.setDataRef(stompMe);
>   -        assertClose("no copy side effect",m,new RealMatrixImpl(testData),
>   -            entryTolerance);
>   +        RealMatrixImpl m2 = new RealMatrixImpl(m.getData());
>   +        assertEquals(m2,m);
>        }
>
>        /** test add */
>   @@ -418,22 +406,14 @@
>            }
>        }
>
>   -    public void testEntryMutators() {
>   +    public void testGetEntry() {
>            RealMatrix m = new RealMatrixImpl(testData);
>            assertEquals("get entry",m.getEntry(0,1),2d,entryTolerance);
>   -        m.setEntry(1,2,100d);
>   -        assertEquals("get entry",m.getEntry(1,2),100d,entryTolerance);
>   -        try {
>   -            double x = m.getEntry(-1,2);
>   -            fail("expecting MatrixIndexException");
>   -        } catch (MatrixIndexException ex) {
>   -            ;
>   -        }
>            try {
>   -            m.setEntry(1,4,200d);
>   -            fail("expecting MatrixIndexException");
>   +            m.getEntry(10, 4);
>   +            fail ("Expecting MatrixIndexException");
>            } catch (MatrixIndexException ex) {
>   -            ;
>   +            // expected
>            }
>        }
>
>   @@ -475,8 +455,7 @@
>            RealMatrix m = new RealMatrixImpl(matrixData);
>            // One more with three rows, two columns
>            double[][] matrixData2 = { {1d,2d}, {2d,5d}, {1d, 7d}};
>   -        RealMatrix n = new RealMatrixImpl();
>   -        n.setData(matrixData2);
>   +        RealMatrix n = new RealMatrixImpl(matrixData2);
>            // Now multiply m by n
>            RealMatrix p = m.multiply(n);
>            assertEquals(2, p.getRowDimension());
>   @@ -652,24 +631,24 @@
>        }
>
>        /** extracts the l  and u matrices from compact lu representation */
>   -    protected void splitLU(RealMatrix lu, RealMatrix lower, RealMatrix upper) throws
InvalidMatrixException {
>   -        if (!lu.isSquare() || !lower.isSquare() || !upper.isSquare() ||
>   -                lower.getRowDimension() != upper.getRowDimension()
>   -                || lower.getRowDimension() != lu.getRowDimension()) {
>   +    protected void splitLU(RealMatrix lu, double[][] lowerData, double[][] upperData)
throws InvalidMatrixException {
>   +        if (!lu.isSquare() || lowerData.length != lowerData[0].length || upperData.length
!= upperData[0].length ||
>   +                lowerData.length != upperData.length
>   +                || lowerData.length != lu.getRowDimension()) {
>                throw new InvalidMatrixException("incorrect dimensions");
>            }
>            int n = lu.getRowDimension();
>            for (int i = 0; i < n; i++) {
>                for (int j = 0; j < n; j++) {
>                    if (j < i) {
>   -                    lower.setEntry(i, j, lu.getEntry(i, j));
>   -                    upper.setEntry(i, j, 0d);
>   +                    lowerData[i][j] = lu.getEntry(i, j);
>   +                    upperData[i][j] = 0d;
>                    } else if (i == j) {
>   -                    lower.setEntry(i, j, 1d);
>   -                    upper.setEntry(i, j, lu.getEntry(i, j));
>   +                    lowerData[i][j] = 1d;
>   +                    upperData[i][j] = lu.getEntry(i, j);
>                    } else {
>   -                    lower.setEntry(i, j, 0d);
>   -                    upper.setEntry(i, j, lu.getEntry(i, j));
>   +                    lowerData[i][j] = 0d;
>   +                    upperData[i][j] = lu.getEntry(i, j);
>                    }
>                }
>            }
>   @@ -681,21 +660,24 @@
>                throw new IllegalArgumentException("dimension mismatch");
>            }
>            int n = matrix.getRowDimension();
>   -        RealMatrix out = new RealMatrixImpl(n, n);
>   +        int m = matrix.getColumnDimension();
>   +        double out[][] = new double[m][n];
>            for (int i = 0; i < n; i++) {
>   -            for (int j = 0; j < n; j++) {
>   -                out.setEntry(i, j, matrix.getEntry(permutation[i], j));
>   +            for (int j = 0; j < m; j++) {
>   +                out[i][j] = matrix.getEntry(permutation[i], j);
>                }
>            }
>   -        return out;
>   +        return new RealMatrixImpl(out);
>        }
>
>        /** Extracts l and u matrices from lu and verifies that matrix = l times u modulo
permutation */
>        protected void verifyDecomposition(RealMatrix matrix, RealMatrix lu) throws Exception{
>            int n = matrix.getRowDimension();
>   -        RealMatrix lower = new RealMatrixImpl(n, n);
>   -        RealMatrix upper = new RealMatrixImpl(n, n);
>   -        splitLU(lu, lower, upper);
>   +        double[][] lowerData = new double[n][n];
>   +        double[][] upperData = new double[n][n];
>   +        splitLU(lu, lowerData, upperData);
>   +        RealMatrix lower =new RealMatrixImpl(lowerData);
>   +        RealMatrix upper = new RealMatrixImpl(upperData);
>            int[] permutation = ((RealMatrixImpl) matrix).getPermutation();
>            RealMatrix permuted = permuteRows(matrix, permutation);
>            assertClose("lu decomposition does not work", permuted, lower.multiply(upper),
normTolerance);
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message