commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Sterijevski <>
Subject Re: (MATH-608) Remove methods from RealMatrix Interface
Date Fri, 01 Jul 2011 21:35:49 GMT

I am not sure why you think there will be double dispatch. If we remove the
multiplication method from the interface then there can only be one call to
multiply. If we want to keep the interface as is and also have a MatrixOps
class, then perhaps that is where we might have such a case. I am either for
the status quo, or the elimination of the operations I noted in my feature
request. Supporting both would be a disaster...

My request stems from attempting to build a SymmetricRealMatrix which stores
its contents in a packed format. I began implementing multiply and so forth
and did not relish having a bunch of case statements. This lead me to the
idea of removing all operations involving other matrices to a separate

I am not clear about why using java's type system is such a bad thing. A
diagonal is different from a symmetric. Both fall under the "is a"
condition. Each is an example of a matrix-but different enough to merit its
own class.

As for the second "MatrixOps" class. The utility of such a class is that the
multiply routine is added when there is a need for it. I may have
GregsZigZagMatrix, whose only user is Greg. If I only multiply
GregsZigZagMatrix matrix with a diagonal, then that's the only method we
would implement. In the current schema, I would need to either support all
existing matrix patterns, support a few and throw exceptions on others, or
have a default case which is unoptimized and uses the element getter method.

I will look at Mahout's solution for this. I guess a better question to the
list would have been: "What is the best way to implement a symmetric matrix
where only the lower (or upper) triangular portion is kept?"

Thank you,


On Fri, Jul 1, 2011 at 12:45 PM, Ted Dunning <> wrote:

> Getting double dispatch this way leads to a pretty ugly API interface.
> There is no reason why Matrix.times can't delegate to MatrixOp.times(this,
> other), though.  That gives you your double dispatch.
> The real problem with this design is that adding a new matrix type is no
> longer something that a user can do and all of your dispatch almost has to
> be done based on Java type structure.  That isn't really what you want.  In
> Mahout, for instance, we have a fair bit of special purpose code that uses
> special indicator methods like isSparse().  In retrospect, I think we might
> have missed a bet and should have used indicator interfaces instead, but
> the
> differences aren't huge.
> The cost is that most of our cleverness lives in AbstractMatrix in the form
> of cascaded if statements rather than nice stylish polymorphism.  This
> design does, however, allow user written classes to add a layer of their
> own
> special casing before delegating to the super class.
> The question of whether users ever really need to write their own matrix
> class is difficult to answer.  In Mahout, the answer was thought to be no,
> because users hadn't.  On the other hand, now that users can, they do.
>  This
> is partly because Mahout lives on the edge of new parallel paradigms and
> users need to experiment a lot to get things right before contributing
> back.
>  I suspect that they same is true of Commons Math, just on a longer time
> scale.  The needs for experimentation are less dire than with Mahout, but
> the pace of change is also glacial.  In my mind, this leads to a similar
> ratio of need / change-rate and may indicate that a similar solution would
> be a good idea.
> On Fri, Jul 1, 2011 at 7:36 AM, Greg Sterijevski <
> >wrote:
> > Hello All,
> >
> > Luc suggested that I move this discussion to the list. Luc posed the
> > question:
> >
> > "I don't understand how you intend to separate the API.
> > Would that mean users would always have to know beforehand the shape of
> the
> > matrix they use and manage both the matrix, the data store and the
> > operators
> > in sync ?"
> >
> > I think my longwinded report was not as clear as it should have been. I
> > want
> > to simplify the RealMatrix interface and implementing classes. In my
> mind's
> > eye, I see the real matrix interface as describing the shape of the data,
> > holding that data and giving the user an indexing scheme to get at an
> > element.
> >
> > My concern with the current interface is that if different shapes of
> > matrices are allowed (Diagonal, Symmetric, Triangular, Banded) the matrix
> > manipulation routines (add, subtract, mult, ...) become very complicated.
> >
> > In my proposal, I argue that we might have another class, say
> > MatrixOperations.
> >
> > It would have routines for Mutlitplication that depend on type. A small
> > subset of the interface might look like:
> >
> > public interface MatrixOpsIface{
> >    public SymmetricMatrix selfTimesTranspose( SymmetricMatrix sm );
> >    public SymmetricMatrix selfTimesTranspose( GeneralMatrix sm );
> >    public SymmetricMatrix sandwichProduct( SymmetricMatrix sm,
> > GeneralMatrix gm);
> >    public SymmetricMatrix sandwichProduct( SymmetricMatrix sm,
> > SymmericMatrix sm2);
> >    public SymmetricMatrix sandwichProduct( SymmetricMatrix sm,
> > SymmetricMatrix gm);
> >    public GeneralMatrix multipy( DiagonalMatrix dm, GeneralMatrix gm);
> >    public GeneralMatrix multiply( SymmetricMatrix sm, GeneralMatrix gm);
> >    public DiagonalMatrix multiply( DiagonalMatrix dm, DiagonalMatrix dm);
> > }
> >
> > The benefit of doing this would be that you could write highly optimized
> > multiplication routines dependent on the shape of the matrices. All of
> the
> > complexity would be handled by the compiler. The user would simply
> > instantiate the operations object (maybe these could be static methods),
> > and
> > call multiply. Adding a new matrix shape would be require an two check
> ins,
> > the code for the new matrix as well as a new set of methods for handling
> > multiplication, etc, with the other types.
> >
> > -Greg
> >

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message