Hi. > 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.
The idea of separating the algorithms from the storage layout sounds nice but why would a class implementing "MatrixOpsIface" be more performant, or simpler, than adding specialized "mutliply" methods within the RealMatrix implementations themselves? E.g. ---CUT--- public class Array2DRowRealMatrix { public Array2DRowRealMatrix multiply(Array2DRowRealMatrix m) { /* ... */ } public Array2DRowRealMatrix multiply(DiagonalRealMatrix m) { /* ... */ } /* ... */ } ---CUT--- Also, there seems to be the problem of exposing the internals (storage layout) so that the implementations of "MatrixOpsIface" can actually make use of them. This would break encapsulation: The layout would becomes part of the interface. Still, publicizing the operators might be interesting. With generics: ---CUT--- interface Multiply<M extends RealMatrix, O extends RealMatrix> { public O multiply(M m); } ---CUT--- Hence, we advertise which operations are type-optimized: ---CUT--- public class Array2DRowRealMatrix implements Multiply<Array2DRowRealMatrix, Array2DRowRealMatrix>, Multiply<Array2DRowRealMatrix, DiagonalRealMatrix> { // ... } Sorry, if this is all besides the point; without a concrete example, it's difficult to figure what must be improved. Also, you could have a look at http://www.ojalgo.org Best, Gilles --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org