how to design a java matrix class implementation independent
I need to use a matrix class in my application for operations like Eigenvalue decomposition,LUDecomposition as well as normal matrix ops like multiplication,addition ,transposition etc. I decided to use jama at present since I am quite familiar with it and because I am currently working with small datasets.
But probably later, I would want to move to a better matrix library like ejml or some future invention as the amount of data grows. How should I design my matrix class so that it is not bound to a particular implementation? I would like an interface similar to as below.
class MyMatrix{
public MyMatrix addWithAnother(MyMatrix b){
...
}
public MyMatrix multiplyWithAnother(MyMatrix b)开发者_开发百科{
...
}
public double[][] getData(){
..
}
public SomeEigenDecomposition getEigenValueDecomposition(){
...
}
Should I put the implementation matrix class(jama Matrix or such) as a field and delegate calls to it? Still that would bind me to jama ,I think.
How can I make the above totally free from the implementation?Any design pattern,java gurus please advise.
thanks
mark
Since there is no de facto or formal standard interface to different Java matrix implementations, you could consider minimizing the effort in switching implementations by designing a Facade that implements the matrix ops you want, coupled with a matrix factory (via eg. Abstract Factory, Factory Method) that instantiates the actual matrix you wish to use under the covers.
Then you would only have to implement Adapter code calling the underlying matrix implementation and externally conforming to your Facade interface, for each new implementation you wish to integrate.
Not ideal, but since the implementations have varying interfaces, you have to glue them into your code somehow. At least this approach shields your client/test code from the change underneath the Facade.
Define what you have above (or similar, as necessary) as an interface.
Create a class which implements that interface, which directly uses the Jama library or whatever. Only expose as public the members of the interface.
Invoke your class through the interface. When you want to use a different implementation, create a different class that implements the same interface, but that does things differently internally; you will be able to drop it in where you used the previous implementation, because the interface is exactly the same.
More of a long comment than an answer:
Your biggest problem switching will probably be the basic number storage used. Jama uses double arrays which is is great for performance, but different packages will probably handle number representation differently. Differences in the representation of data types like imaginary numbers, arbitrary precision math, rationals or an internal representation that doesn't resolve irrational numbers until later might be really difficult to plan for.
I love Java but Java is lousy at all this because it has no usable base class for numbers (I figured this out writing my own matrix library to help me learn the math). Java's syntax for dealing with math is uncomfortable as well. (I ended up creating all of the classes in Java but used them from Groovy allowing a MUCH better math syntax.)
So my suggestion is don't put too much effort into the façade because there is a good chance it won't help much anyway. If you really want to do this you might try to abstract-away the underlying data type as well.
精彩评论