如何设计一个独立于实现的java矩阵类
我需要在应用程序中使用矩阵类进行特征值分解、LUDecomposition 等操作 以及普通的矩阵运算,如乘法、加法、转置等。 我目前决定使用 jama,因为我对它非常熟悉并且因为我目前 处理小数据集。
但可能以后,我想转向更好的矩阵库,比如 ejml 或随着数据量的增长而出现的一些未来发明。 我应该如何设计我的矩阵类,使其不绑定到特定的实现? 我想要一个类似于下面的界面。
class MyMatrix{
public MyMatrix addWithAnother(MyMatrix b){
...
}
public MyMatrix multiplyWithAnother(MyMatrix b){
...
}
public double[][] getData(){
..
}
public SomeEigenDecomposition getEigenValueDecomposition(){
...
}
我应该将实现矩阵类(jama Matrix 等)作为字段并将调用委托给它吗? 我想,这仍然会把我和贾马联系在一起。
我怎样才能使上述完全免于实现?任何设计模式,java大师请指教。
谢谢马克
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于不同的 Java 矩阵实现没有事实上或正式的标准接口,因此您可以考虑通过设计一个Facade来实现您想要的矩阵操作,从而最大限度地减少切换实现的工作量,再加上一个矩阵工厂(例如通过抽象工厂、工厂方法)来实例化您希望在幕后使用的实际矩阵。
然后,对于您希望集成的每个新实现,您只需实现调用底层矩阵实现并在外部符合您的Facade 接口的适配器代码。
并不理想,但由于实现具有不同的接口,您必须以某种方式将它们粘合到代码中。至少这种方法可以保护您的客户端/测试代码免受外观下面的更改的影响。
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.
将上面的内容(或类似的内容,根据需要)定义为接口。
创建一个实现该接口的类,该类直接使用 Jama 库或其他库。仅将接口的成员公开为公共。
通过接口调用您的类。当您想使用不同的实现时,请创建一个实现相同接口的不同类,但内部执行不同的操作;您可以将其放在使用先前实现的位置,因为接口完全相同。
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.
更多的是长评论而不是答案:
您最大的切换问题可能是使用的基本号码存储。 Jama 使用双数组,这对于性能来说非常好,但是不同的包可能会以不同的方式处理数字表示。虚数、任意精度数学、有理数或直到稍后才能解析无理数的内部表示等数据类型表示的差异可能真的很难规划。
我喜欢 Java,但 Java 在这方面很糟糕,因为它没有可用的数字基类(我想出了编写自己的矩阵库来帮助我学习数学)。 Java 处理数学的语法也令人不舒服。 (我最终用 Java 创建了所有类,但从 Groovy 中使用了它们,从而获得了更好的数学语法。)
所以我的建议是不要在外观上投入太多精力,因为它很可能不会有太大帮助反正。如果您确实想这样做,您也可以尝试抽象出底层数据类型。
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.