英文:
Abstracting away Matrix library dependency
问题
我正在编写一个用于学习和在一个玩具神经网络库中使用的线性代数库。我想要使用不同的Java线性代数库来测试效率,但我在抽象化方面遇到了困难。
假设我希望我的矩阵抽象支持加法、减法、乘法、Hadamard乘法、映射和映射元素,如下所示:
// 我希望这将强制实现类是不可变的...
// M是实现矩阵的类型
public interface Matrix<M, T extends Number> {
M add(M in); // 返回 this 矩阵 + in
// 重载 add(T)
// 默认 subtract = add(-1 * T)
M multiply(M in); // 返回 this 矩阵 X in
// 重载 multiply(T)
// 默认 divide = multiply(T^-1)
M hadamardMultiply(M in); // 返回 this 矩阵 hadamard in
T map(Function<M, T> map); // f: M -> T
M mapElements(UnaryOperator<T> map); // f: T -> T
}
我的意思是不可变的,我的API应该看起来像这样:
Matrix<vendor.matrix.VendorMatrix, Double> multiple = myMatrix.multiply(someOtherMatrix);
// 或者
Matrix<vendor.matrix.VendorMatrix, Double> add = myMatrix.add(5);
// 以及
Matrix<vendor.matrix.VendorMatrix, Double> mapped = myMatrix.map(e -> e / Math.PI);
这不应该改变myMatrix。
现在,我之前使用过UJMP,所以我需要在该库周围实现这个包装器,这就是我遇到的问题,这些方法不能返回我的Matrix,它们必须返回实现类中矩阵的类型。然而,这破坏了抽象。
因此,我认为下一步是创建一个UJMPMatrix类,它扩展了任何库(在本例中是UJMP)所需的矩阵类,并实现了我的Matrix接口,如下所示:
public class UJMPMatrix extends org.ujmp.core.DefaultDenseDoubleMatrix2D
implements my.library.Matrix<org.ujmp.core.Matrix, Double> {
// 实现接口方法...
}
有了这个,我现在失去了抽象,因为DefaultDenseDoubleMatrix2D 已经包含了所有这些方法,而我只想要接口中提供的方法。我该如何继续?
英文:
I'm writing a toy linear algebra library for learning and to be used in a toy neural network library. I would like to use different Java linear algebra libraries to test efficiency, but I'm stuck at the abstraction.
Suppose I would like my own Matrix abstraction to be add, subtract, multiply, hadamardMultiply, map, and mapElements like so:
// I would prefer for this to force the implementing classes to be immutable...
// M is the type of implementing matrix
public interface Matrix<M,T extends Number> {
M add(M in); // return this matrix + in
// overload add(T)
// default subtract = add (-1 * T)
M multiply(M in); // return this matrix X in
// overload multiply(T)
// default divide = multiply(T^-1)
M hadamardMultiply(M in); // return this matrix hadamard in
T map(Function<M,T> map); // f: M -> T
M mapElements(UnaryOperator<T> map); // f: T -> T
}
What I mean by immutable is that my API should look like
Matrix<vendor.matrix.VendorMatrix, Double> multiple = myMatrix.multiply(someOtherMatrix);
// or
Matrix<vendor.matrix.VendorMatrix, Double> add = myMatrix.add(5);
// and
Matrix<vendor.matrix.VendorMatrix, Double> mapped = myMatrix.map(e -> e / Math.PI);
which should not alter the myMatrix.
Now I've previously used UJMP, and so I need to implement this wrapper around that library, and here is where I stumbled upon the issue that these methods cannot return my Matrix, they have to return the type of the matrices in implementing classes. However, this breaks the abstraction.
So I thought that the next step would be to make a UJMPMatrix class, which extends whichever library's (in this case UJMP) desired matrix class and implements my Matrix interface like so:
public class UJMPMatrix extends org.ujmp.core.DefaultDenseDoubleMatrix2D
implements my.library.Matrix<org.ujmp.core.Matrix, Double> {
....
}
With this, I have now lost the abstraction, as the defaultdensedoublematrix2d already has all of these methods in them, when I only want the ones provided in my interface. How do I proceed?
答案1
得分: 2
如果 UJMPMatrix 扩展 DefaultDenseDoubleMatrix2D,则所有公共的 UJMP 方法都会被暴露出来。您需要使用委托模式。
关于泛型类型,您还需要对其进行更改,以便可以接受其他 UJMPMatrix 作为方法参数。
public class UJMPMatrix implements my.library.Matrix<UJMPMatrix, Double> {
private org.ujmp.core.DefaultDenseDoubleMatrix2D delegate;
// 通过使用委托来实现接口的方法
}
英文:
If UJMPMatrix extends DefaultDenseDoubleMatrix2D then all the public UJMP methods are exposed. You need to use the delegate pattern.
Regarding the generics typing you will also need change it so it can accept other UJMPMatrix as method arguments.
public class UJMPMatrix implements my.library.Matrix<UJMPMatrix, Double> {
private org.ujmp.core.DefaultDenseDoubleMatrix2D delegate;
// Implement the methods of your interface by using the delegate
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论