/** * Converts the transpose of a row major matrix into a row major block matrix. * * @param src Original FMatrixRMaj. Not modified. * @param dst Equivalent FMatrixRBlock. Modified. */ public static void convertTranSrc(FMatrixRMaj src, FMatrixRBlock dst) { if (src.numRows != dst.numCols || src.numCols != dst.numRows) { throw new ArgumentException("Incompatible matrix shapes."); } for (int i = 0; i < dst.numRows; i += dst.blockLength) { int blockHeight = Math.Min(dst.blockLength, dst.numRows - i); for (int j = 0; j < dst.numCols; j += dst.blockLength) { int blockWidth = Math.Min(dst.blockLength, dst.numCols - j); int indexDst = i * dst.numCols + blockHeight * j; int indexSrc = j * src.numCols + i; for (int l = 0; l < blockWidth; l++) { int rowSrc = indexSrc + l * src.numCols; int rowDst = indexDst + l; for (int k = 0; k < blockHeight; k++, rowDst += blockWidth) { dst.data[rowDst] = src.data[rowSrc++]; } } } } }
public static FMatrixRBlock convert(FMatrixRMaj A, int blockLength) { FMatrixRBlock ret = new FMatrixRBlock(A.numRows, A.numCols, blockLength); convert(A, ret); return(ret); }
/** * Converts {@link FMatrixRMaj} into {@link FMatrixRBlock} * * Can't handle null output matrix since block size needs to be specified. * * @param src Input matrix. * @param dst Output matrix. */ public static void convert(FMatrixRMaj src, FMatrixRBlock dst) { if (src.numRows != dst.numRows || src.numCols != dst.numCols) { throw new ArgumentException("Must be the same size."); } for (int i = 0; i < dst.numRows; i += dst.blockLength) { int blockHeight = Math.Min(dst.blockLength, dst.numRows - i); for (int j = 0; j < dst.numCols; j += dst.blockLength) { int blockWidth = Math.Min(dst.blockLength, dst.numCols - j); int indexDst = i * dst.numCols + blockHeight * j; int indexSrcRow = i * dst.numCols + j; for (int k = 0; k < blockHeight; k++) { Array.Copy(src.data, indexSrcRow, dst.data, indexDst, blockWidth); indexDst += blockWidth; indexSrcRow += dst.numCols; } } } }
public static FMatrixRBlock convert(FMatrixRMaj A) { FMatrixRBlock ret = new FMatrixRBlock(A.numRows, A.numCols); convert(A, ret); return(ret); }
/** * Transposes a block matrix. * * @param A Original matrix. Not modified. * @param A_tran Transposed matrix. Modified. */ public static FMatrixRBlock transpose(FMatrixRBlock A, FMatrixRBlock A_tran) { if (A_tran != null) { if (A.numRows != A_tran.numCols || A.numCols != A_tran.numRows) { throw new ArgumentException("Incompatible dimensions."); } if (A.blockLength != A_tran.blockLength) { throw new ArgumentException("Incompatible block size."); } } else { A_tran = new FMatrixRBlock(A.numCols, A.numRows, A.blockLength); } for (int i = 0; i < A.numRows; i += A.blockLength) { int blockHeight = Math.Min(A.blockLength, A.numRows - i); for (int j = 0; j < A.numCols; j += A.blockLength) { int blockWidth = Math.Min(A.blockLength, A.numCols - j); int indexA = i * A.numCols + blockHeight * j; int indexC = j * A_tran.numCols + blockWidth * i; transposeBlock(A, A_tran, indexA, indexC, blockWidth, blockHeight); } } return(A_tran); }
public static void multTransB(FMatrixRBlock A, FMatrixRBlock B, FMatrixRBlock C) { if (A.numCols != B.numCols) { throw new ArgumentException("Columns in A are incompatible with columns in B"); } if (A.numRows != C.numRows) { throw new ArgumentException("Rows in A are incompatible with rows in C"); } if (B.numRows != C.numCols) { throw new ArgumentException("Rows in B are incompatible with columns in C"); } if (A.blockLength != B.blockLength || A.blockLength != C.blockLength) { throw new ArgumentException("Block lengths are not all the same."); } int blockLength = A.blockLength; FSubmatrixD1 Asub = new FSubmatrixD1(A, 0, A.numRows, 0, A.numCols); FSubmatrixD1 Bsub = new FSubmatrixD1(B, 0, B.numRows, 0, B.numCols); FSubmatrixD1 Csub = new FSubmatrixD1(C, 0, C.numRows, 0, C.numCols); MatrixMult_FDRB.multTransB(blockLength, Asub, Bsub, Csub); }
//@Override public FMatrixRMaj getQ(FMatrixRMaj Q, bool compact) { int minLength = Math.Min(Ablock.numRows, Ablock.numCols); if (Q == null) { if (compact) { Q = new FMatrixRMaj(Ablock.numRows, minLength); CommonOps_FDRM.setIdentity(Q); } else { Q = new FMatrixRMaj(Ablock.numRows, Ablock.numRows); CommonOps_FDRM.setIdentity(Q); } } FMatrixRBlock Qblock = new FMatrixRBlock(); Qblock.numRows = Q.numRows; Qblock.numCols = Q.numCols; Qblock.blockLength = blockLength; Qblock.data = Q.data; ((QRDecompositionHouseholder_FDRB)alg).getQ(Qblock, compact); convertBlockToRow(Q.numRows, Q.numCols, Ablock.blockLength, Q.data); return(Q); }
public static bool isEquals(FMatrixRBlock A, FMatrixRBlock B, float tol) { if (A.blockLength != B.blockLength) { return(false); } return(MatrixFeatures_FDRM.isEquals(A, B, tol)); }
public static FMatrixRBlock createRandom(int numRows, int numCols, float min, float max, IMersenneTwister rand) { FMatrixRBlock ret = new FMatrixRBlock(numRows, numCols); RandomMatrices_FDRM.fillUniform(ret, min, max, rand); return(ret); }
public virtual FMatrixRMaj getT(FMatrixRMaj T) { FMatrixRBlock T_block = ((CholeskyOuterForm_FDRB)alg).getT(null); if (T == null) { T = new FMatrixRMaj(T_block.numRows, T_block.numCols); } MatrixOps_FDRB.convert(T_block, T); // todo set zeros return(T); }
/** * Transposes an individual block inside a block matrix. */ private static void transposeBlock(FMatrixRBlock A, FMatrixRBlock A_tran, int indexA, int indexC, int width, int height) { for (int i = 0; i < height; i++) { int rowIndexC = indexC + i; int rowIndexA = indexA + width * i; int end = rowIndexA + width; for (; rowIndexA < end; rowIndexC += height, rowIndexA++) { A_tran.data[rowIndexC] = A.data[rowIndexA]; } } }
/** * <p> * Checks to see if the two matrices have an identical shape an block size. * </p> * * @param A Matrix. * @param B Matrix. */ public static void checkIdenticalShape(FMatrixRBlock A, FMatrixRBlock B) { if (A.blockLength != B.blockLength) { throw new ArgumentException("Block size is different"); } if (A.numRows != B.numRows) { throw new ArgumentException("Number of rows is different"); } if (A.numCols != B.numCols) { throw new ArgumentException("NUmber of columns is different"); } }
public virtual FMatrixRMaj getQ(FMatrixRMaj Q, bool transposed) { if (Q == null) { Q = new FMatrixRMaj(Ablock.numRows, Ablock.numCols); } FMatrixRBlock Qblock = new FMatrixRBlock(); Qblock.numRows = Q.numRows; Qblock.numCols = Q.numCols; Qblock.blockLength = blockLength; Qblock.data = Q.data; ((TridiagonalDecompositionHouseholder_FDRB)alg).getQ(Qblock, transposed); convertBlockToRow(Q.numRows, Q.numCols, Ablock.blockLength, Q.data); return(Q); }
/** * <p> * Extracts a matrix from src into dst. The submatrix which is copied has its initial coordinate * at (0,0) and ends at (dst.numRows,dst.numCols). The end rows/columns must be aligned along blocks * or else it will silently screw things up. * </p> * * @param src Matrix which a submatrix is being extracted from. Not modified. * @param dst Where the submatrix is written to. Its rows and columns be less than or equal to 'src'. Modified. */ public static void extractAligned(FMatrixRBlock src, FMatrixRBlock dst) { if (src.blockLength != dst.blockLength) { throw new ArgumentException("Block size is different"); } if (src.numRows < dst.numRows) { throw new ArgumentException("The src has fewer rows than dst"); } if (src.numCols < dst.numCols) { throw new ArgumentException("The src has fewer columns than dst"); } int blockLength = src.blockLength; int numRows = Math.Min(src.numRows, dst.numRows); int numCols = Math.Min(src.numCols, dst.numCols); for (int i = 0; i < numRows; i += blockLength) { int heightSrc = Math.Min(blockLength, src.numRows - i); int heightDst = Math.Min(blockLength, dst.numRows - i); for (int j = 0; j < numCols; j += blockLength) { int widthSrc = Math.Min(blockLength, src.numCols - j); int widthDst = Math.Min(blockLength, dst.numCols - j); int indexSrc = i * src.numCols + heightSrc * j; int indexDst = i * dst.numCols + heightDst * j; for (int k = 0; k < heightDst; k++) { Array.Copy(src.data, indexSrc + widthSrc * k, dst.data, indexDst + widthDst * k, widthDst); } } } }
/** * <p> * Returns a new matrix with ones along the diagonal and zeros everywhere else. * </p> * * @param numRows Number of rows. * @param numCols NUmber of columns. * @param blockLength Block length. * @return An identify matrix. */ public static FMatrixRBlock identity(int numRows, int numCols, int blockLength) { FMatrixRBlock A = new FMatrixRBlock(numRows, numCols, blockLength); int minLength = Math.Min(numRows, numCols); for (int i = 0; i < minLength; i += blockLength) { int h = Math.Min(blockLength, A.numRows - i); int w = Math.Min(blockLength, A.numCols - i); int index = i * A.numCols + h * i; int m = Math.Min(h, w); for (int k = 0; k < m; k++) { A.data[index + k * w + k] = 1; } } return(A); }
/** * <p>Sets the value of A to all zeros except along the diagonal.</p> * * @param A Block matrix. */ public static void setIdentity(FMatrixRBlock A) { int minLength = Math.Min(A.numRows, A.numCols); CommonOps_FDRM.fill(A, 0); int blockLength = A.blockLength; for (int i = 0; i < minLength; i += blockLength) { int h = Math.Min(blockLength, A.numRows - i); int w = Math.Min(blockLength, A.numCols - i); int index = i * A.numCols + h * i; int m = Math.Min(h, w); for (int k = 0; k < m; k++) { A.data[index + k * w + k] = 1; } } }
/** * Converts {@link FMatrixRBlock} into {@link FMatrixRMaj} * * @param src Input matrix. * @param dst Output matrix. If null a new matrix will be declared. * @return Converted matrix. */ public static FMatrixRMaj convert(FMatrixRBlock src, FMatrixRMaj dst) { if (dst != null) { if (dst.numRows != src.numRows || dst.numCols != src.numCols) { throw new ArgumentException("Must be the same size."); } } else { dst = new FMatrixRMaj(src.numRows, src.numCols); } for (int i = 0; i < src.numRows; i += src.blockLength) { int blockHeight = Math.Min(src.blockLength, src.numRows - i); for (int j = 0; j < src.numCols; j += src.blockLength) { int blockWidth = Math.Min(src.blockLength, src.numCols - j); int indexSrc = i * src.numCols + blockHeight * j; int indexDstRow = i * dst.numCols + j; for (int k = 0; k < blockHeight; k++) { Array.Copy(src.data, indexSrc, dst.data, indexDstRow, blockWidth); indexSrc += blockWidth; indexDstRow += dst.numCols; } } } return(dst); }
/** * Copies either the upper or lower triangular portion of src into dst. Dst can be smaller * than src. * * @param upper If the upper or lower triangle is copied. * @param src The source matrix. Not modified. * @param dst The destination matrix. Modified. */ public static void copyTriangle(bool upper, FMatrixRBlock src, FMatrixRBlock dst) { if (src.blockLength != dst.blockLength) { throw new ArgumentException("Block size is different"); } if (src.numRows < dst.numRows) { throw new ArgumentException("The src has fewer rows than dst"); } if (src.numCols < dst.numCols) { throw new ArgumentException("The src has fewer columns than dst"); } int blockLength = src.blockLength; int numRows = Math.Min(src.numRows, dst.numRows); int numCols = Math.Min(src.numCols, dst.numCols); if (upper) { for (int i = 0; i < numRows; i += blockLength) { int heightSrc = Math.Min(blockLength, src.numRows - i); int heightDst = Math.Min(blockLength, dst.numRows - i); for (int j = i; j < numCols; j += blockLength) { int widthSrc = Math.Min(blockLength, src.numCols - j); int widthDst = Math.Min(blockLength, dst.numCols - j); int indexSrc = i * src.numCols + heightSrc * j; int indexDst = i * dst.numCols + heightDst * j; if (j == i) { for (int k = 0; k < heightDst; k++) { for (int l = k; l < widthDst; l++) { dst.data[indexDst + widthDst * k + l] = src.data[indexSrc + widthSrc * k + l]; } } } else { for (int k = 0; k < heightDst; k++) { Array.Copy(src.data, indexSrc + widthSrc * k, dst.data, indexDst + widthDst * k, widthDst); } } } } } else { for (int i = 0; i < numRows; i += blockLength) { int heightSrc = Math.Min(blockLength, src.numRows - i); int heightDst = Math.Min(blockLength, dst.numRows - i); for (int j = 0; j <= i; j += blockLength) { int widthSrc = Math.Min(blockLength, src.numCols - j); int widthDst = Math.Min(blockLength, dst.numCols - j); int indexSrc = i * src.numCols + heightSrc * j; int indexDst = i * dst.numCols + heightDst * j; if (j == i) { for (int k = 0; k < heightDst; k++) { int z = Math.Min(k + 1, widthDst); for (int l = 0; l < z; l++) { dst.data[indexDst + widthDst * k + l] = src.data[indexSrc + widthSrc * k + l]; } } } else { for (int k = 0; k < heightDst; k++) { Array.Copy(src.data, indexSrc + widthSrc * k, dst.data, indexDst + widthDst * k, widthDst); } } } } } }
/** * Converts a row major matrix into a row major block matrix. * * @param src Original FMatrixRMaj. Not modified. * @param dst Equivalent FMatrixRBlock. Modified. */ public static void convert(FMatrixRMaj src, FMatrixRBlock dst) { ConvertFMatrixStruct.convert(src, dst); }
/** * Sets either the upper or low triangle of a matrix to zero */ public static void zeroTriangle(bool upper, FMatrixRBlock A) { int blockLength = A.blockLength; if (upper) { for (int i = 0; i < A.numRows; i += blockLength) { int h = Math.Min(blockLength, A.numRows - i); for (int j = i; j < A.numCols; j += blockLength) { int w = Math.Min(blockLength, A.numCols - j); int index = i * A.numCols + h * j; if (j == i) { for (int k = 0; k < h; k++) { for (int l = k + 1; l < w; l++) { A.data[index + w * k + l] = 0; } } } else { for (int k = 0; k < h; k++) { for (int l = 0; l < w; l++) { A.data[index + w * k + l] = 0; } } } } } } else { for (int i = 0; i < A.numRows; i += blockLength) { int h = Math.Min(blockLength, A.numRows - i); for (int j = 0; j <= i; j += blockLength) { int w = Math.Min(blockLength, A.numCols - j); int index = i * A.numCols + h * j; if (j == i) { for (int k = 0; k < h; k++) { int z = Math.Min(k, w); for (int l = 0; l < z; l++) { A.data[index + w * k + l] = 0; } } } else { for (int k = 0; k < h; k++) { for (int l = 0; l < w; l++) { A.data[index + w * k + l] = 0; } } } } } } }
/** * Converts a row major block matrix into a row major matrix. * * @param src Original FMatrixRBlock.. Not modified. * @param dst Equivalent FMatrixRMaj. Modified. */ public static FMatrixRMaj convert(FMatrixRBlock src, FMatrixRMaj dst) { return(ConvertFMatrixStruct.convert(src, dst)); }
/** * <p> * Sets every element in the matrix to the specified value.<br> * <br> * a<sub>ij</sub> = value * <p> * * @param A A matrix whose elements are about to be set. Modified. * @param value The value each element will have. */ public static void set(FMatrixRBlock A, float value) { CommonOps_FDRM.fill(A, value); }