将委托模式用于矩阵 [英] Utilizing delegate pattern for matrices
问题描述
根据,我实现了一个委托模式来隐藏要基准的线性代数库。 ,请参见:
public interface Matrix<M> {
/**
* Cols or this matrix
*
* @return columns
*/
int rows();
/**
* Rows of this matrix
*
* @return rows
*/
int cols();
/**
* Matrix multiplication, should throw if cols and rows do not match.
* Contract is This X in, i.e. this_rows*this_cols X in_cols*in_rows
*
* @param otherMatrix right operand
* @return new matrix multiplied
*/
M multiply(M otherMatrix);
/**
* Multiply each element with this scalar
*
* @param scalar to multiply with
* @return scaled with scalar
*/
M multiply(double scalar);
/**
* Add in to this matrix
*
* @param in right operand
* @return this + in
*/
M add(M in);
/**
* Add in to all elements of this.
*
* @param in scalar operand
* @return this.map(e - > e + in)
*/
M add(double in);
/**
* Subtract in from all elements of this
*
* @param in scalar operand
* @return this.map(e - > e - in);
*/
M subtract(double in);
/**
* Substract in from this matrix
*
* @param in right operand
* @return this[i][j] -= in[i][j]
*/
M subtract(M in);
/**
* Divide all elements by in
*
* @param in scalar operand
* @return in.map(e - > e / in);
*/
M divide(double in);
/**
* Map this matrix to a double, useful for reduce or trace implementations
*
* @param mapping f: This -> double
* @return a double value
*/
double map(Function<M, Double> mapping);
/**
* Map each element with this function
*
* @param mapping f: Double -> Double each element
* @return this.map(e - > mapping ( e));
*/
M mapElements(Function<Double, Double> mapping);
/**
* Sum this matrix over all entries.
*
* @return sum of this
*/
double sum();
/**
* Max of this matrix over all entries.
*
* @return max of this
*/
double max();
/**
* Index along a column of max, should only be used for vectors.
*
* @return index of max
*/
int argMax();
/**
* Transpose this matrix.
*
* @return transpose.
*/
M transpose();
enum MatrixType {
VECTOR, SQUARE
}
}
具有此类:
public class UJMPMatrix implements Matrix<UJMPMatrix> {
private org.ujmp.core.Matrix delegate;
public UJMPMatrix(UJMPMatrix in) { this.delegate = in.delegate; }
public UJMPMatrix(org.ujmp.core.Matrix in) { this.delegate = in; }
public int rows() {
return (int) this.delegate.getRowCount();
}
public int cols() {
return (int) this.delegate.getColumnCount();
}
@Override
public UJMPMatrix multiply(UJMPMatrix otherMatrix) {
return new UJMPMatrix(this.delegate.mtimes(otherMatrix.delegate));
}
@Override
public UJMPMatrix multiply(double scalar) {
return new UJMPMatrix(this.delegate.times(scalar));
}
@Override
public UJMPMatrix add(UJMPMatrix in) {
return new UJMPMatrix(this.delegate.plus(in.delegate));
}
@Override
public UJMPMatrix add(double in) {
return new UJMPMatrix(this.delegate.plus(in));
}
@Override
public UJMPMatrix subtract(double in) {
return new UJMPMatrix(this.delegate.minus(in));
}
@Override
public UJMPMatrix subtract(UJMPMatrix in) {
return new UJMPMatrix(this.delegate.minus(in.delegate));
}
@Override
public UJMPMatrix divide(double in) {
return new UJMPMatrix(this.delegate.divide(in));
}
@Override
public double map(Function<UJMPMatrix, Double> mapping) {
return mapping.apply(this);
}
@Override
public UJMPMatrix mapElements(Function<Double, Double> mapping) {
double[][] elements = this.delegate.toDoubleArray();
double[][] out = new double[elements.length][elements[0].length];
for (int i = 0; i < elements.length; i++) {
for (int j = 0; j < elements[0].length; i++) {
out[i][j] = mapping.apply(elements[i][j]);
}
}
return new UJMPMatrix(out, rows(), cols());
}
@Override
public double sum() {
return this.delegate.getValueSum();
}
@Override
public double max() {
return this.delegate.max(Calculation.Ret.NEW, 0).doubleValue();
}
@Override
public UJMPMatrix transpose() {
return new UJMPMatrix(this.delegate.transpose());
}
@Override
public int argMax() {
double[] array = this.delegate.toDoubleArray()[0];
int argMax = -1;
double best = Double.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] > best) {
best = array[i];
argMax = i;
}
}
return argMax;
}
}
但是,当我想使用这种抽象时,Java告诉我我不能使用任何这些方法,因为我需要通配符(?)来声明这些矩阵:
However, when I want to use this abstraction, Java tells me that I cannot use any of these methods, because of the wildcard I need (?) to use to declare these matrices:
private void feedForward(final Matrix<? extends Matrix<?>> starter, final List<Matrix<? extends Matrix<?>>> actives) {
Matrix<? extends Matrix<?>> toPredict = starter;
actives.add(toPredict);
for (int i = 0; i < this.totalLayers - 1; i++) {
final Matrix<? extends Matrix<?>> x = this.weights[i].multiply(toPredict).add(this.biases[i]);
// Weights and Biases are also Matrix<? extends Matrix<?>>[].
// error: cannot resolve method multiply(Matrix<capture ? extends Matrix<?>>)
toPredict = this.functions[i + 1].function(x);
actives.add(toPredict);
}
}
注意:在神经网络的构造函数中,我让调用方决定通过简单的枚举{OJ_ALGO,UJMP}获得所需的Matrix类型,然后调用我实现的Factory初始化这些矩阵。神经网络的字段如下所示:
Note: In the constructor of the Neural Network I let the caller decide what type of Matrix they want by a simple enum { OJ_ALGO, UJMP }, and call the Factory I implemented to intialise those matrices. The fields of the neural network look like this:
// Weights and biases of the network
private volatile Matrix<? extends Matrix<?>>[] weights;
private volatile Matrix<? extends Matrix<?>>[] biases;
private volatile Matrix<? extends Matrix<?>>[] dW;
private volatile Matrix<? extends Matrix<?>>[] dB;
问题:如何声明,初始化和利用在此神经网络库中实现的Matrix抽象?
Question: How do I declare, initialise and utilise the Matrix abstraction I implemented in this neural network library?
推荐答案
您的 feedForward
方法需要泛型,以表示两个参数都必须是相同类型(请注意< M>
在无效之前):
Your feedForward
method needs a generic type to signify that both arguments must be of the same type (note the <M>
before void) :
private <M> void feedForward(final Matrix<M> starter, final List<M> actives) {
同样,您的神经网络类也应声明使用的矩阵类型(假设您不想同时使用不同的实现):
And likewise your neural network class should declare the type of matrices it is using (assuming you don't want to use different implementations at the same time):
public class NeuralNetwork<M> {
private volatile Matrix<M>[] weights;
private volatile Matrix<M>[] biases;
private volatile Matrix<M>[] dW;
private volatile Matrix<M>[] dB;
作为旁注,我不确定为什么将这些声明为易失性。
As a side note, I'm not sure why these are declared as volatile.
您的界面应如下所示:
public interface Matrix<M> {
Matrix<M> multiply(Matrix<M> otherMatrix);
M delegate();
以及您的实现:
public class UJMPMatrix implements Matrix<org.ujmp.core.Matrix> {
private org.ujmp.core.Matrix delegate;
@Override
public UJMPMatrix multiply(Matrix<org.ujmp.core.Matrix> otherMatrix) {
return new UJMPMatrix(this.delegate.mtimes(otherMatrix.delegate()));
}
@Override
public org.ujmp.core.Matrix delegate() {
return delegate();
}
这篇关于将委托模式用于矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!