You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Mark R. Diggory" <md...@apache.org> on 2004/10/12 15:09:56 UTC

Re: [math] cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/linear RealMatrixImplTest.java

Phil,

I think we wanted to maintain the existence of setEntry/getDataRef API 
of the RealMatrixImpl without having it in the RealMatrix Interface. At 
least until we come up with a strategy for mutability that made more 
sense then these methods. This last change removed it from both.

Michael,

We are attempting to make the Implementation immutable so that methods 
calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax) 
will be able to return submatrice objects of the existing data without 
duplicating/copying the internal datastore to do so, this will provide 
efficient means to access the stored values without performing costly 
array copies on what may be very large double[][]'s or copying objects 
which may not be in an []. So basically, what we are trying to avoid is 
that if I do the following

Matrix a = ...
Matrix b = a.getColumnMatrix(x);

that if (a) is mutable, then doing something like a.setEntry(x,y,d) will 
also cause (b) to change, something we should try to avoid, we are 
trying to work with these more as mathematical objects and not 
necessarily as "Collection objects".

If you require such mutability, could you take a moment and show an 
example of the usage you require it for?

-thanks,
Mark Diggory

Michael Heuer wrote:
> 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
> 

-- 
Mark Diggory
Open Source Software Developer
Apache Jakarta Project
http://jakarta.apache.org

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


Re: [math] RealMatrix Immutability wase: Re: [math] cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/linear RealMatrixImplTest.java

Posted by Phil Steitz <ph...@steitz.com>.
Mark R. Diggory wrote:
> 
> 
> Phil Steitz wrote:
> 
>> Mark R. Diggory wrote:
>>
>>> Phil,
>>>
>>> I think we wanted to maintain the existence of setEntry/getDataRef 
>>> API of the RealMatrixImpl without having it in the RealMatrix 
>>> Interface. At least until we come up with a strategy for mutability 
>>> that made more sense then these methods. This last change removed it 
>>> from both.
>>
>>
>>
>> getDataRef is still there in RealMatrixImpl, though I am starting to 
>> think that we can make it protected.  Either the class is immutable or 
>> it is not.  We need to decide. All of the use cases that I have can 
>> actually be accomplished with the immutable version, using the 
>> algebraic operations exposed in the RealMatrix API.  If others have 
>> use cases that require mutability, then we can change it back, but I 
>> would like to know what they are.
>>
> 
> Thats what I'm hoping to hear from Michael, I want to see solid examples 
> of the need.
> 
>>>
>>> Michael,
>>>
>>> We are attempting to make the Implementation immutable so that 
>>> methods calls such as getColumnMatrix(i) and 
>>> getSubMatrix(xmin,xmax,ymin,ymax) will be able to return submatrice 
>>> objects of the existing data without duplicating/copying the internal 
>>> datastore to do so, this will provide efficient means to access the 
>>> stored values without performing costly array copies on what may be 
>>> very large double[][]'s or copying objects which may not be in an []. 
>>> So basically, what we are trying to avoid is that if I do the following
>>>
>>> Matrix a = ...
>>> Matrix b = a.getColumnMatrix(x);
>>>
>>> that if (a) is mutable, then doing something like a.setEntry(x,y,d) 
>>> will also cause (b) to change, something we should try to avoid, we 
>>> are trying to work with these more as mathematical objects and not 
>>> necessarily as "Collection objects".
>>
>>
>>
>> Yes, but the getSubXxx and getCol, getRow currently make copies. 
>> Assuming we retain immutability, this makes no functional difference 
>> (another argument for making the class immutable).  
> 
> 
> Yes, like I said, this a feature I am working on in my checkout. I 
> havn't committed it because it is not complete yet.
> 
>> Implementation will be very tricky (and likely very inefficient) if we 
>> try to support "data sharing" as you describe. It would also make 
>> getDataRef impossible to implement.
> 
> 
> Not inefficient, a little complex, yes, but not inefficient, the only 
> real difference is "where in" the original datastore data structure (in 
> this case the data[][]) your are iterating over, the RealMatrix 
> representing the Row column or submatrix is simply maintaining extra 
> information about the xmn, xmax, ymin, ymax it represents in the 
> original data store. It accesses the original data store using the 
> getEntry(x,y) . The x and y are transposed to the appropriate location 
> int eh datstore using simple arithmetic.

That will work OK for the row and column accessors and for ranges of 
contiguous cells; but not for the general case currently enabled via the 
sumMatrix API.  These methods are very flexible and allow you to permute 
rows / columns as well as select ranges.  Keeping track of all of that 
would be intractable.  So, if we do go down this path, the "advanced" 
subMatrix methods will still have to make copies.

Assuming we agree on immutablility, the semantics are no different, so I 
would prefer to focus on getting the 1.0 changes complete, including the 
changes to reduce copy operations internal to methods. Remember that all 
the changes already made still have to be ported to the BigMatrix impl. 
Changing and testing all the methods to work with offsets will be time 
consuming and error prone, so I think it is better to hold off on this 
until post 1.0.  IIUC, this would not require any change to the public 
API, so it can be postponed.

Phil


> I think were starting get this thing going in the right direction.
> 
> -Mark
> 


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


Re: [math] RealMatrix Immutability

Posted by "Mark R. Diggory" <md...@latte.harvard.edu>.

Michael Heuer wrote:

> 
> This is similar to how colt matrix views (viewRow, viewColumn,
> viewSelection, etc.) are implemented (disclaimer:  I use colt all the
> time).
> 
>    michael

Yes, a good reason why we are looking at its implementation to enhance 
the Matrix API. :-)

-Mark
-- 
Mark Diggory
Software Developer
Harvard MIT Data Center
http://www.hmdc.harvard.edu

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


Re: [math] RealMatrix Immutability

Posted by Michael Heuer <he...@acm.org>.
On Tue, 12 Oct 2004, Mark R. Diggory wrote:

> Phil Steitz wrote:
> > Mark R. Diggory wrote:
> >
> >> Phil,
> >>
> >> I think we wanted to maintain the existence of setEntry/getDataRef API
> >> of the RealMatrixImpl without having it in the RealMatrix Interface.
> >> At least until we come up with a strategy for mutability that made
> >> more sense then these methods. This last change removed it from both.
> >
> >
> > getDataRef is still there in RealMatrixImpl, though I am starting to
> > think that we can make it protected.  Either the class is immutable or
> > it is not.  We need to decide. All of the use cases that I have can
> > actually be accomplished with the immutable version, using the algebraic
> > operations exposed in the RealMatrix API.  If others have use cases that
> > require mutability, then we can change it back, but I would like to know
> > what they are.
> >
>
> Thats what I'm hoping to hear from Michael, I want to see solid examples
> of the need.
>
> >>
> >> Michael,
> >>
> >> We are attempting to make the Implementation immutable so that methods
> >> calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax)
> >> will be able to return submatrice objects of the existing data without
> >> duplicating/copying the internal datastore to do so, this will provide
> >> efficient means to access the stored values without performing costly
> >> array copies on what may be very large double[][]'s or copying objects
> >> which may not be in an []. So basically, what we are trying to avoid
> >> is that if I do the following
> >>
> >> Matrix a = ...
> >> Matrix b = a.getColumnMatrix(x);
> >>
> >> that if (a) is mutable, then doing something like a.setEntry(x,y,d)
> >> will also cause (b) to change, something we should try to avoid, we
> >> are trying to work with these more as mathematical objects and not
> >> necessarily as "Collection objects".
> >
> >
> > Yes, but the getSubXxx and getCol, getRow currently make copies.
> > Assuming we retain immutability, this makes no functional difference
> > (another argument for making the class immutable).
>
> Yes, like I said, this a feature I am working on in my checkout. I
> havn't committed it because it is not complete yet.
>
> > Implementation will
> > be very tricky (and likely very inefficient) if we try to support "data
> > sharing" as you describe. It would also make getDataRef impossible to
> > implement.
>
> Not inefficient, a little complex, yes, but not inefficient, the only
> real difference is "where in" the original datastore data structure (in
> this case the data[][]) your are iterating over, the RealMatrix
> representing the Row column or submatrix is simply maintaining extra
> information about the xmn, xmax, ymin, ymax it represents in the
> original data store. It accesses the original data store using the
> getEntry(x,y) . The x and y are transposed to the appropriate location
> int eh datstore using simple arithmetic.

This is similar to how colt matrix views (viewRow, viewColumn,
viewSelection, etc.) are implemented (disclaimer:  I use colt all the
time).

   michael


> I think were starting get this thing going in the right direction.
>
> -Mark
>
> --
> Mark Diggory
> Software Developer
> Harvard MIT Data Center
> http://www.hmdc.harvard.edu
>
> ---------------------------------------------------------------------
> 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


Re: [math] RealMatrix Immutability wase: Re: [math] cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/linear RealMatrixImplTest.java

Posted by "Mark R. Diggory" <md...@latte.harvard.edu>.

Phil Steitz wrote:
> Mark R. Diggory wrote:
> 
>> Phil,
>>
>> I think we wanted to maintain the existence of setEntry/getDataRef API 
>> of the RealMatrixImpl without having it in the RealMatrix Interface. 
>> At least until we come up with a strategy for mutability that made 
>> more sense then these methods. This last change removed it from both.
> 
> 
> getDataRef is still there in RealMatrixImpl, though I am starting to 
> think that we can make it protected.  Either the class is immutable or 
> it is not.  We need to decide. All of the use cases that I have can 
> actually be accomplished with the immutable version, using the algebraic 
> operations exposed in the RealMatrix API.  If others have use cases that 
> require mutability, then we can change it back, but I would like to know 
> what they are.
> 

Thats what I'm hoping to hear from Michael, I want to see solid examples 
of the need.

>>
>> Michael,
>>
>> We are attempting to make the Implementation immutable so that methods 
>> calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax) 
>> will be able to return submatrice objects of the existing data without 
>> duplicating/copying the internal datastore to do so, this will provide 
>> efficient means to access the stored values without performing costly 
>> array copies on what may be very large double[][]'s or copying objects 
>> which may not be in an []. So basically, what we are trying to avoid 
>> is that if I do the following
>>
>> Matrix a = ...
>> Matrix b = a.getColumnMatrix(x);
>>
>> that if (a) is mutable, then doing something like a.setEntry(x,y,d) 
>> will also cause (b) to change, something we should try to avoid, we 
>> are trying to work with these more as mathematical objects and not 
>> necessarily as "Collection objects".
> 
> 
> Yes, but the getSubXxx and getCol, getRow currently make copies. 
> Assuming we retain immutability, this makes no functional difference 
> (another argument for making the class immutable).  

Yes, like I said, this a feature I am working on in my checkout. I 
havn't committed it because it is not complete yet.

> Implementation will 
> be very tricky (and likely very inefficient) if we try to support "data 
> sharing" as you describe. It would also make getDataRef impossible to 
> implement.

Not inefficient, a little complex, yes, but not inefficient, the only 
real difference is "where in" the original datastore data structure (in 
this case the data[][]) your are iterating over, the RealMatrix 
representing the Row column or submatrix is simply maintaining extra 
information about the xmn, xmax, ymin, ymax it represents in the 
original data store. It accesses the original data store using the 
getEntry(x,y) . The x and y are transposed to the appropriate location 
int eh datstore using simple arithmetic.


I think were starting get this thing going in the right direction.

-Mark

-- 
Mark Diggory
Software Developer
Harvard MIT Data Center
http://www.hmdc.harvard.edu

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


Re: [math] RealMatrix Immutability

Posted by Phil Steitz <ph...@steitz.com>.
Michael Heuer wrote:
> On Tue, 12 Oct 2004, Phil Steitz wrote:
> 
> 
>>Mark R. Diggory wrote:
>>
>>>Phil,
>>>
>>>I think we wanted to maintain the existence of setEntry/getDataRef API
>>>of the RealMatrixImpl without having it in the RealMatrix Interface. At
>>>least until we come up with a strategy for mutability that made more
>>>sense then these methods. This last change removed it from both.
>>
>>getDataRef is still there in RealMatrixImpl, though I am starting to think
>>that we can make it protected.  Either the class is immutable or it is
>>not.  We need to decide. All of the use cases that I have can actually be
>>accomplished with the immutable version, using the algebraic operations
>>exposed in the RealMatrix API.  If others have use cases that require
>>mutability, then we can change it back, but I would like to know what they
>>are.

Another point in favor of immutability is that the cached LU decomposition 
becomes invalid on mutation, so the luDecompose method has to be exposed. 
  This method can also be made protected or even private now.

>>
>>>Michael,
>>>
>>>We are attempting to make the Implementation immutable so that methods
>>>calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax)
>>>will be able to return submatrice objects of the existing data without
>>>duplicating/copying the internal datastore to do so, this will provide
>>>efficient means to access the stored values without performing costly
>>>array copies on what may be very large double[][]'s or copying objects
>>>which may not be in an []. So basically, what we are trying to avoid is
>>>that if I do the following
>>>
>>>Matrix a = ...
>>>Matrix b = a.getColumnMatrix(x);
>>>
>>>that if (a) is mutable, then doing something like a.setEntry(x,y,d) will
>>>also cause (b) to change, something we should try to avoid, we are
>>>trying to work with these more as mathematical objects and not
>>>necessarily as "Collection objects".
>>
>>Yes, but the getSubXxx and getCol, getRow currently make copies. Assuming
>>we retain immutability, this makes no functional difference (another
>>argument for making the class immutable).  Implementation will be very
>>tricky (and likely very inefficient) if we try to support "data sharing"
>>as you describe. It would also make getDataRef impossible to implement.
>>
>>
>>>If you require such mutability, could you take a moment and show an
>>>example of the usage you require it for?
>>
>>I thought at first that I would need mutability in my applications, and I
>>think that Kim did as well; but I found that my use of it was just because
>>I did not have the right boundary between the double[][] stuff that I was
>>doing and the algebraic operations (which is what RealMatrix is for).
> 
> 
> The double[][] constructor for RealMatrixImpl copies the input array, so
> if I want to fill a matrix with values, isn't it more efficient and more
> straightforward to simply fill the matrix?
> 
> RealMatrix rm = new RealMatrixImpl(10000, 10000);
> for (int row = 0, rows = rm.getRowDimension(); row < rows; row++)
> {
>   for (int col = 0, cols = rm.getColumnDimension(); col < cols; col++)
>   {
>     rm.setEntry(row, col, someValue);
>   }
> }
> 

That is a good point, but is not really an argument agains immutability. 
This is really just an initialization issue. The constructor makes a copy 
to be "defensive" and to provide a clean separation.  We could provide a 
factory method that does not make a copy in MatrixUtils.  That is probably 
a good idea.  Do you have other use cases where the setEntry method is 
really required?

> 
> 
>>>>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.
>>
>>Well, many clients will in fact be doing that, though hopefully with clean
>>boundaries.  Can you suggest alternatives that do not impose too much
>>overhead?
>>
>>>>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.
>>
>>That's sort of the point of the immutability argument above.  The double[]
>>and double[][] valued accessors are for convenience and speed when
>>crossing the boundary back into the client application.  Some applications
>>will start with arrays, use RealMatrix to perform algebraic operations and
>>then use "output" arrays directly.  That is why the accessors are there.
>>
>>Thanks for the feedback.
>>
>>Phil
>>
>>
>>
>>---------------------------------------------------------------------
>>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
> 


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


Re: [math] RealMatrix Immutability

Posted by Michael Heuer <he...@acm.org>.
On Tue, 12 Oct 2004, Phil Steitz wrote:

> Mark R. Diggory wrote:
> > Phil,
> >
> > I think we wanted to maintain the existence of setEntry/getDataRef API
> > of the RealMatrixImpl without having it in the RealMatrix Interface. At
> > least until we come up with a strategy for mutability that made more
> > sense then these methods. This last change removed it from both.
>
> getDataRef is still there in RealMatrixImpl, though I am starting to think
> that we can make it protected.  Either the class is immutable or it is
> not.  We need to decide. All of the use cases that I have can actually be
> accomplished with the immutable version, using the algebraic operations
> exposed in the RealMatrix API.  If others have use cases that require
> mutability, then we can change it back, but I would like to know what they
> are.
> >
> > Michael,
> >
> > We are attempting to make the Implementation immutable so that methods
> > calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax)
> > will be able to return submatrice objects of the existing data without
> > duplicating/copying the internal datastore to do so, this will provide
> > efficient means to access the stored values without performing costly
> > array copies on what may be very large double[][]'s or copying objects
> > which may not be in an []. So basically, what we are trying to avoid is
> > that if I do the following
> >
> > Matrix a = ...
> > Matrix b = a.getColumnMatrix(x);
> >
> > that if (a) is mutable, then doing something like a.setEntry(x,y,d) will
> > also cause (b) to change, something we should try to avoid, we are
> > trying to work with these more as mathematical objects and not
> > necessarily as "Collection objects".
>
> Yes, but the getSubXxx and getCol, getRow currently make copies. Assuming
> we retain immutability, this makes no functional difference (another
> argument for making the class immutable).  Implementation will be very
> tricky (and likely very inefficient) if we try to support "data sharing"
> as you describe. It would also make getDataRef impossible to implement.
>
> >
> > If you require such mutability, could you take a moment and show an
> > example of the usage you require it for?
>
> I thought at first that I would need mutability in my applications, and I
> think that Kim did as well; but I found that my use of it was just because
> I did not have the right boundary between the double[][] stuff that I was
> doing and the algebraic operations (which is what RealMatrix is for).

The double[][] constructor for RealMatrixImpl copies the input array, so
if I want to fill a matrix with values, isn't it more efficient and more
straightforward to simply fill the matrix?

RealMatrix rm = new RealMatrixImpl(10000, 10000);
for (int row = 0, rows = rm.getRowDimension(); row < rows; row++)
{
  for (int col = 0, cols = rm.getColumnDimension(); col < cols; col++)
  {
    rm.setEntry(row, col, someValue);
  }
}


> >> 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.
>
> Well, many clients will in fact be doing that, though hopefully with clean
> boundaries.  Can you suggest alternatives that do not impose too much
> overhead?
> >>
> >> 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.
>
> That's sort of the point of the immutability argument above.  The double[]
> and double[][] valued accessors are for convenience and speed when
> crossing the boundary back into the client application.  Some applications
> will start with arrays, use RealMatrix to perform algebraic operations and
> then use "output" arrays directly.  That is why the accessors are there.
>
> Thanks for the feedback.
>
> Phil
>
>
>
> ---------------------------------------------------------------------
> 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


[math] RealMatrix Immutability wase: Re: [math] cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/linear RealMatrixImplTest.java

Posted by Phil Steitz <ph...@steitz.com>.
Mark R. Diggory wrote:
> Phil,
> 
> I think we wanted to maintain the existence of setEntry/getDataRef API 
> of the RealMatrixImpl without having it in the RealMatrix Interface. At 
> least until we come up with a strategy for mutability that made more 
> sense then these methods. This last change removed it from both.

getDataRef is still there in RealMatrixImpl, though I am starting to think 
that we can make it protected.  Either the class is immutable or it is 
not.  We need to decide. All of the use cases that I have can actually be 
accomplished with the immutable version, using the algebraic operations 
exposed in the RealMatrix API.  If others have use cases that require 
mutability, then we can change it back, but I would like to know what they 
are.
> 
> Michael,
> 
> We are attempting to make the Implementation immutable so that methods 
> calls such as getColumnMatrix(i) and getSubMatrix(xmin,xmax,ymin,ymax) 
> will be able to return submatrice objects of the existing data without 
> duplicating/copying the internal datastore to do so, this will provide 
> efficient means to access the stored values without performing costly 
> array copies on what may be very large double[][]'s or copying objects 
> which may not be in an []. So basically, what we are trying to avoid is 
> that if I do the following
> 
> Matrix a = ...
> Matrix b = a.getColumnMatrix(x);
> 
> that if (a) is mutable, then doing something like a.setEntry(x,y,d) will 
> also cause (b) to change, something we should try to avoid, we are 
> trying to work with these more as mathematical objects and not 
> necessarily as "Collection objects".

Yes, but the getSubXxx and getCol, getRow currently make copies. Assuming 
we retain immutability, this makes no functional difference (another 
argument for making the class immutable).  Implementation will be very 
tricky (and likely very inefficient) if we try to support "data sharing" 
as you describe. It would also make getDataRef impossible to implement.

> 
> If you require such mutability, could you take a moment and show an 
> example of the usage you require it for?

I thought at first that I would need mutability in my applications, and I 
think that Kim did as well; but I found that my use of it was just because 
I did not have the right boundary between the double[][] stuff that I was 
doing and the algebraic operations (which is what RealMatrix is for).


>> 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.

Well, many clients will in fact be doing that, though hopefully with clean 
boundaries.  Can you suggest alternatives that do not impose too much 
overhead?
>>
>> 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.

That's sort of the point of the immutability argument above.  The double[] 
and double[][] valued accessors are for convenience and speed when 
crossing the boundary back into the client application.  Some applications 
will start with arrays, use RealMatrix to perform algebraic operations and 
then use "output" arrays directly.  That is why the accessors are there.

Thanks for the feedback.

Phil



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