예제 #1
0
        /**
         * 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++];
                        }
                    }
                }
            }
        }
예제 #2
0
        public static FMatrixRBlock convert(FMatrixRMaj A, int blockLength)
        {
            FMatrixRBlock ret = new FMatrixRBlock(A.numRows, A.numCols, blockLength);

            convert(A, ret);
            return(ret);
        }
예제 #3
0
        /**
         * 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;
                    }
                }
            }
        }
예제 #4
0
        public static FMatrixRBlock convert(FMatrixRMaj A)
        {
            FMatrixRBlock ret = new FMatrixRBlock(A.numRows, A.numCols);

            convert(A, ret);
            return(ret);
        }
예제 #5
0
        /**
         * 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);
        }
예제 #6
0
        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);
        }
예제 #8
0
        public static bool isEquals(FMatrixRBlock A, FMatrixRBlock B, float tol)
        {
            if (A.blockLength != B.blockLength)
            {
                return(false);
            }

            return(MatrixFeatures_FDRM.isEquals(A, B, tol));
        }
예제 #9
0
        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);
        }
예제 #11
0
 /**
  * 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];
         }
     }
 }
예제 #12
0
 /**
  * <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);
        }
예제 #14
0
        /**
         * <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);
                    }
                }
            }
        }
예제 #15
0
        /**
         * <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);
        }
예제 #16
0
        /**
         * <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;
                }
            }
        }
예제 #17
0
        /**
         * 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);
        }
예제 #18
0
        /**
         * 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);
                            }
                        }
                    }
                }
            }
        }
예제 #19
0
 /**
  * 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);
 }
예제 #20
0
        /**
         * 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;
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #21
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));
 }
예제 #22
0
 /**
  * <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);
 }