抽象掉 Matrix 库依赖

Abstracting away Matrix library dependency

我正在编写一个玩具线性代数库,用于学习和在玩具神经网络库中使用。我想使用不同的 Java 线性代数库来测试效率,但我停留在抽象上。

假设我希望我自己的 Matrix 抽象是加法、减法、乘法、hadamardMultiply、map 和 mapElements,如下所示:

// 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
}

我所说的不可变的意思是我的 API 应该看起来像

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);

这不应该改变 myMatrix。

现在我以前使用过 UJMP,所以我需要围绕那个库实现这个包装器,在这里我偶然发现了这些方法不能 return 我的矩阵的问题,在实施 classes 时,他们必须 return 矩阵的类型。然而,这打破了抽象。

所以我认为下一步是制作一个 UJMPMatrix class,它扩展了任何库(在本例中为 UJMP)所需的矩阵 class 并像这样实现我的 Matrix 接口:

public class UJMPMatrix extends org.ujmp.core.DefaultDenseDoubleMatrix2D 
    implements my.library.Matrix<org.ujmp.core.Matrix, Double> {
....
}

有了这个,我现在已经失去了抽象,因为 defaultdensedoublematrix2d 已经有了所有这些方法,而我只想要我的界面中提供的方法。我该如何进行?

如果 UJMPMatrix 扩展了 DefaultDenseDoubleMatrix2D,那么所有 public UJMP 方法都会被公开。您需要使用委托模式。

关于泛型类型,您还需要对其进行更改,以便它可以接受其他 UJMPMatrix 作为方法参数。

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
}