public static void multPlusTransA(int blockLength, FSubmatrixD1 A, FSubmatrixD1 B, FSubmatrixD1 C) { for (int i = A.col0; i < A.col1; i += blockLength) { int widthA = Math.Min(blockLength, A.col1 - i); for (int j = B.col0; j < B.col1; j += blockLength) { int widthB = Math.Min(blockLength, B.col1 - j); int indexC = (i - A.col0 + 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 + i * heightA; int indexB = (k - A.row0 + B.row0) * B.original.numCols + j * heightA; InnerMultiplication_FDRB.blockMultPlusTransA(A.original.data, B.original.data, C.original.data, indexA, indexB, indexC, heightA, widthA, widthB); } } } }
/** * <p> * Performs:<br> * <br> * A = A + α B <sup>T</sup>B * </p> * * @param blockLength Size of the block in the block matrix. * @param alpha scaling factor for right hand side. * @param A Block aligned submatrix. * @param B Block aligned submatrix. */ public static void rankNUpdate(int blockLength, float alpha, FSubmatrixD1 A, FSubmatrixD1 B) { int heightB = B.row1 - B.row0; if (heightB > blockLength) { throw new ArgumentException("Height of B cannot be greater than the block length"); } int N = B.col1 - B.col0; if (A.col1 - A.col0 != N) { throw new ArgumentException("A does not have the expected number of columns based on B's width"); } if (A.row1 - A.row0 != N) { throw new ArgumentException("A does not have the expected number of rows based on B's width"); } for (int i = B.col0; i < B.col1; i += blockLength) { int indexB_i = B.row0 * B.original.numCols + i * heightB; int widthB_i = Math.Min(blockLength, B.col1 - i); int rowA = i - B.col0 + A.row0; int heightA = Math.Min(blockLength, A.row1 - rowA); for (int j = B.col0; j < B.col1; j += blockLength) { int widthB_j = Math.Min(blockLength, B.col1 - j); int indexA = rowA * A.original.numCols + (j - B.col0 + A.col0) * heightA; int indexB_j = B.row0 * B.original.numCols + j * heightB; InnerMultiplication_FDRB.blockMultPlusTransA(alpha, B.original.data, B.original.data, A.original.data, indexB_i, indexB_j, indexA, heightB, widthB_i, widthB_j); } } }