RealMatrix在没有重新分配的情况下成倍增加

时间:2014-10-30 20:55:10

标签: java optimization blas apache-commons-math

在我的Java源代码中,我必须经常执行以下行:

vecX = EigenMat.multiply(vecX);
vecY = EigenMat.multiply(vecY);

EigenMat是N×N矩阵,N~40 vecX / vecY是一个N x 1向量(实际上是一个RealMatrix)

我使用VisualFM中的“Sampler”在我的代码中找到一些热点,

org.apache.commons.math3.linear.Array2DRowRealMatrix.<init>()
org.apache.commons.math3.linear.Array2DRowRealMatrix.multiply()

运行时非常高。 我不是一个java专业人士,但我认为每个乘法都会创建一个新的向量。我可以重新分配旧的吗?

也许我应该转而使用JBLAS来加速它?

Matyro

编辑: 仅限单核

Hotspot2 Hotspot1

1 个答案:

答案 0 :(得分:0)

  

我认为每个乘法都会创建一个新的矢量

是的,确实如此。 multiply()的{​​{3}}:

public Array2DRowRealMatrix multiply(final Array2DRowRealMatrix m) {
        // Safety check.
        MatrixUtils.checkMultiplicationCompatible(this, m);

        final int nRows = this.getRowDimension();
        final int nCols = m.getColumnDimension();
        final int nSum = this.getColumnDimension();

        final double[][] outData = new double[nRows][nCols];
        // Will hold a column of "m".
        final double[] mCol = new double[nSum];
        final double[][] mData = m.data;

        // Multiply.
        for (int col = 0; col < nCols; col++) {
            // Copy all elements of column "col" of "m" so that
            // will be in contiguous memory.
            for (int mRow = 0; mRow < nSum; mRow++) {
                mCol[mRow] = mData[mRow][col];
            }

            for (int row = 0; row < nRows; row++) {
                final double[] dataRow = data[row];
                double sum = 0;
                for (int i = 0; i < nSum; i++) {
                    sum += dataRow[i] * mCol[i];
                }
                outData[row][col] = sum;
            }
        }

        return new Array2DRowRealMatrix(outData, false);
    }

复制输入向量m,如评论Copy all elements of column "col" of "m" so that will be in contiguous memory中所述。

  

我可以重新分配旧的吗?

是的,您可以自己执行乘法,编写两个循环。使用getData()获取对基础double[][] data

的引用