@Override public A multiply(A v, A[] m) { final int cols1 = arrayOps.getLength(v); final int rows2 = arrayOps.getRowCount(m); final int cols2 = arrayOps.getColumnCount(m); if (cols1 != rows2) { throw new IllegalArgumentException( "incompatible dimension for matrix multiplication: " + "1x" + cols1 + " * " + rows2 + "x" + cols2); } final TernaryOperator<N, A> mulAdd = expressionComposer.addToFree(expressionComposer.mul()); final A res = numberArrayOps.newZeroVector(cols2); IntArray indices = null; final long[] rsup = numberArrayOps.getVectorSupportAsLongBits(v); for (int c = 0; c < cols2; c++) { final long[] csup = numberArrayOps.getMatrixColumnSupportAsLongBits(m, c); indices = toIndexArray(rsup, csup, indices); for (int i = 0; i < indices.length(); i++) { final int index = indices.get(i); // res[c] = res[c] + v[index]*m[index][c]* mulAdd.operate(res, c, v, index, m[index], c, res, c); } } return res; }
private static IntArray toIndexArray(long[] supportA, long[] supportB, IntArray indices) { if (indices == null) { indices = new IntArray(); } else { indices.clear(); } for (int i = 0; i < supportA.length; i++) { long commonSupport = supportA[i] & supportB[i]; while (commonSupport != 0) { final int index = Long.numberOfTrailingZeros(commonSupport); indices.add(index + i * 64); commonSupport ^= (1L << index); } } return indices; }
@Override public A[] multiply(A[] m1, A[] m2) { final int rows1 = arrayOps.getRowCount(m1); final int cols1 = arrayOps.getColumnCount(m1); final int rows2 = arrayOps.getRowCount(m2); final int cols2 = arrayOps.getColumnCount(m2); if (cols1 != rows2) { throw new IllegalArgumentException( "incompatible dimension for matrix multiplication: " + rows1 + "x" + cols1 + " * " + rows2 + "x" + cols2); } final TernaryOperator<N, A> mulAdd = expressionComposer.addToFree(expressionComposer.mul()); final A[] res = numberArrayOps.newZeroMatrix(rows1, cols2); IntArray indices = null; final long[][] rsup = numberArrayOps.getMatrixSupportAsLongBits(m1); for (int c = 0; c < cols2; c++) { final long[] csup = numberArrayOps.getMatrixColumnSupportAsLongBits(m2, c); for (int r = 0; r < rows1; r++) { indices = toIndexArray(rsup[r], csup, indices); for (int i = 0; i < indices.length(); i++) { final int index = indices.get(i); // res[r][c] = res[r][c] + m1[r][index]*m2[index][c] mulAdd.operate(res[r], c, m1[r], index, m2[index], c, res[r], c); } } } return res; }