提取Matrix库依赖项

问题描述

我正在编写一个玩具线性代数库,用于学习并在玩具神经网络库中使用。我想使用不同的Java线性代数库来测试效率,但是我仍然局限于抽象。

假设我希望自己的矩阵抽象像这样添加,减去,相乘,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,因此我需要在该库周围实现该包装器,在这里我偶然发现了这些方法无法返回我的Matrix,它们必须返回类型的问题实现类的矩阵。但是,这破坏了抽象。

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

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

有了这个,我现在已经失去了抽象性,因为当我只想要接口中提供的方法时,defaultdensedoublematrix2d已经在其中包含了所有这些方法。我该如何进行?

解决方法

如果UJMPMatrix扩展了DefaultDenseDoubleMatrix2D,则所有公共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
}