/** * Special multiplication that takes in account the zeros and one in Y, which * is the matrix that stores the householder vectors. * */ public static void multAdd_zeros(int blockLength, FSubmatrixD1 Y, FSubmatrixD1 B, FSubmatrixD1 C) { int widthY = Y.col1 - Y.col0; for (int i = Y.row0; i < Y.row1; i += blockLength) { int heightY = Math.Min(blockLength, Y.row1 - i); for (int j = B.col0; j < B.col1; j += blockLength) { int widthB = Math.Min(blockLength, B.col1 - j); int indexC = (i - Y.row0 + C.row0) * C.original.numCols + (j - B.col0 + C.col0) * heightY; for (int k = Y.col0; k < Y.col1; k += blockLength) { int indexY = i * Y.original.numCols + k * heightY; int indexB = (k - Y.col0 + B.row0) * B.original.numCols + j * widthY; if (i == Y.row0) { multBlockAdd_zerosone(Y.original.data, B.original.data, C.original.data, indexY, indexB, indexC, heightY, widthY, widthB); } else { InnerMultiplication_FDRB.blockMultPlus(Y.original.data, B.original.data, C.original.data, indexY, indexB, indexC, heightY, widthY, widthB); } } } } }
/** * <p> * Performs a matrix multiplication on the block aligned submatrices. A is * assumed to be block column vector that is lower triangular with diagonal elements set to 1.<br> * <br> * C = A^T * B * </p> */ public static void multTransA_vecCol(int blockLength, FSubmatrixD1 A, FSubmatrixD1 B, FSubmatrixD1 C) { int widthA = A.col1 - A.col0; if (widthA > blockLength) { throw new ArgumentException("A is expected to be at most one block wide."); } for (int j = B.col0; j < B.col1; j += blockLength) { int widthB = Math.Min(blockLength, B.col1 - j); int indexC = C.row0 * C.original.numCols + (j - B.col0 + C.col0) * widthA; for (int k = A.row0; k < A.row1; k += blockLength) { int heightA = Math.Min(blockLength, A.row1 - k); int indexA = k * A.original.numCols + A.col0 * heightA; int indexB = (k - A.row0 + B.row0) * B.original.numCols + j * heightA; if (k == A.row0) { multTransABlockSet_lowerTriag(A.original.data, B.original.data, C.original.data, indexA, indexB, indexC, heightA, widthA, widthB); } else { InnerMultiplication_FDRB.blockMultPlusTransA(A.original.data, B.original.data, C.original.data, indexA, indexB, indexC, heightA, widthA, widthB); } } } }
/** * C = C + A^T*B * * @param blockLength * @param A row block vector * @param B row block vector * @param C */ public static void multPlusTransA(int blockLength, FSubmatrixD1 A, FSubmatrixD1 B, FSubmatrixD1 C) { int heightA = Math.Min(blockLength, A.row1 - A.row0); for (int i = C.row0 + blockLength; i < C.row1; i += blockLength) { int heightC = Math.Min(blockLength, C.row1 - i); int indexA = A.row0 * A.original.numCols + (i - C.row0 + A.col0) * heightA; for (int j = i; j < C.col1; j += blockLength) { int widthC = Math.Min(blockLength, C.col1 - j); int indexC = i * C.original.numCols + j * heightC; int indexB = B.row0 * B.original.numCols + (j - C.col0 + B.col0) * heightA; InnerMultiplication_FDRB.blockMultPlusTransA(A.original.data, B.original.data, C.original.data, indexA, indexB, indexC, heightA, heightC, widthC); } } }