将委托模式用于矩阵 [英] Utilizing delegate pattern for matrices

查看:70
本文介绍了将委托模式用于矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据,我实现了一个委托模式来隐藏要基准的线性代数库。 ,请参见:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆