如何解决将委托模式用于矩阵
根据this,我实现了一个委托模式以隐藏要基准的线性代数库,请参阅:
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告诉我我不能使用任何这些方法,因为我需要使用通配符(?)来声明这些矩阵:
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}决定他们想要的矩阵类型,然后调用我实现的Factory初始化这些矩阵。神经网络的字段如下所示:
// 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;
问题:如何声明,初始化和利用我在此神经网络库中实现的矩阵抽象?
解决方法
您的feedForward
方法需要一个通用类型来表示两个参数必须具有相同的类型(请注意<M>
在void之前):
private <M> void feedForward(final Matrix<M> starter,final List<M> actives) {
同样,您的神经网络类应声明其使用的矩阵类型(假设您不想同时使用不同的实现):
public class NeuralNetwork<M> {
private volatile Matrix<M>[] weights;
private volatile Matrix<M>[] biases;
private volatile Matrix<M>[] dW;
private volatile Matrix<M>[] dB;
作为旁注,我不确定为什么将这些声明为易失性。
您的界面应如下所示:
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();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。