Ejemplo n.º 1
0
        /**
         * <p>
         * Performs a matrix multiplication on {@link DMatrixRBlock} submatrices.<br>
         * <br>
         * c = c - a * b <br>
         * <br>
         * </p>
         *
         * <p>
         * It is assumed that all submatrices start at the beginning of a block and end at the end of a block.
         * </p>
         *
         * @param blockLength Size of the blocks in the submatrix.
         * @param A A submatrix.  Not modified.
         * @param B A submatrix.  Not modified.
         * @param C Result of the operation.  Modified,
         */
        public static void multMinus(int blockLength,
                                     DSubmatrixD1 A, DSubmatrixD1 B,
                                     DSubmatrixD1 C)
        {
            //        checkShapeMult( blockLength,A,B,C);

            //CONCURRENT_BELOW EjmlConcurrency.loopFor(A.row0,A.row1,blockLength,i->{
            for (int i = A.row0; i < A.row1; i += blockLength)
            {
                int heightA = Math.Min(blockLength, A.row1 - i);

                for (int j = B.col0; j < B.col1; j += blockLength)
                {
                    int widthB = Math.Min(blockLength, B.col1 - j);

                    int indexC = (i - A.row0 + C.row0) * C.original.numCols + (j - B.col0 + C.col0) * heightA;

                    for (int k = A.col0; k < A.col1; k += blockLength)
                    {
                        int widthA = Math.Min(blockLength, A.col1 - k);

                        int indexA = i * A.original.numCols + k * heightA;
                        int indexB = (k - A.col0 + B.row0) * B.original.numCols + j * widthA;

                        InnerMultiplication_DDRB.blockMultMinus(A.original.data, B.original.data, C.original.data,
                                                                indexA, indexB, indexC, heightA, widthA, widthB);
                    }
                }
            }
            //CONCURRENT_ABOVE });
        }
Ejemplo n.º 2
0
        /**
         * Inverts an upper or lower triangular block submatrix. Uses a row-oriented approach.
         *
         * @param upper Is it upper or lower triangular.
         * @param T Triangular matrix that is to be inverted. Must be block aligned. Not Modified.
         * @param T_inv Where the inverse is stored. This can be the same as T. Modified.
         * @param workspace Work space variable that is size blockLength*blockLength.
         */
        public static void invert(int blockLength,
                                  bool upper,
                                  DSubmatrixD1 T,
                                  DSubmatrixD1 T_inv,
                                  GrowArray <DGrowArray> workspace)
        {
            if (upper)
            {
                throw new ArgumentException("Upper triangular matrices not supported yet");
            }

            //CONCURRENT_INLINE if (T.original == T_inv.original)
            //CONCURRENT_INLINE    throw new ArgumentException("Same instance not allowed for concurrent");

            //if (workspace == null)
            //    workspace = new GrowArray<DGrowArray>(new DGrowArray());
            //else
            //    workspace.reset();

            if (T.row0 != T_inv.row0 || T.row1 != T_inv.row1 || T.col0 != T_inv.col0 || T.col1 != T_inv.col1)
            {
                throw new ArgumentException("T and T_inv must be at the same elements in the matrix");
            }

            int blockSize = blockLength * blockLength;

            //CONCURRENT_REMOVE_BELOW
            double[] temp = workspace.grow().reshape(blockSize).data;

            int M = T.row1 - T.row0;

            double[] dataT = T.original.data;
            double[] dataX = T_inv.original.data;

            int offsetT = T.row0 * T.original.numCols + M * T.col0;

            for (int rowT = 0; rowT < M; rowT += blockLength)
            {
                int _rowT   = rowT; // Needed for concurrent lambdas
                int heightT = Math.Min(T.row1 - (rowT + T.row0), blockLength);

                int indexII = offsetT + T.original.numCols * (rowT + T.row0) + heightT * (rowT + T.col0);

                //CONCURRENT_BELOW EjmlConcurrency.loopFor(0, rowT, blockLength, workspace, ( work, colT ) -> {
                for (int colT = 0; colT < rowT; colT += blockLength)
                {
                    //CONCURRENT_INLINE double[] temp = work.reshape(blockSize).data;
                    int widthX = Math.Min(T.col1 - (colT + T.col0), blockLength);

                    Array.Fill(temp, 0);

                    for (int k = colT; k < _rowT; k += blockLength)
                    {
                        int widthT = Math.Min(T.col1 - (k + T.col0), blockLength);

                        int indexL2 = offsetT + T.original.numCols * (_rowT + T.row0) + heightT * (k + T.col0);
                        int indexX2 = offsetT + T.original.numCols * (k + T.row0) + widthT * (colT + T.col0);

                        InnerMultiplication_DDRB.blockMultMinus(dataT, dataX, temp, indexL2, indexX2, 0, heightT, widthT, widthX);
                    }

                    int indexX = offsetT + T.original.numCols * (_rowT + T.row0) + heightT * (colT + T.col0);

                    InnerTriangularSolver_DDRB.solveL(dataT, temp, heightT, widthX, heightT, indexII, 0);
                    System.Array.Copy(temp, 0, dataX, indexX, widthX * heightT);
                }
                //CONCURRENT_ABOVE });
                InnerTriangularSolver_DDRB.invertLower(dataT, dataX, heightT, indexII, indexII);
            }
        }
Ejemplo n.º 3
0
        //CONCURRENT_OMIT_BEGIN

        /**
         * Inverts an upper or lower triangular block submatrix. Uses a row oriented approach.
         *
         * @param upper Is it upper or lower triangular.
         * @param T Triangular matrix that is to be inverted. Overwritten with solution. Modified.
         * @param workspace Work space variable that is size blockLength*blockLength.
         */
        public static void invert(int blockLength,
                                  bool upper,
                                  DSubmatrixD1 T,
                                  GrowArray <DGrowArray> workspace)
        {
            if (upper)
            {
                throw new ArgumentException("Upper triangular matrices not supported yet");
            }

            // FORCE to disable
            workspace = null;

            if (workspace == null)
            {
                //workspace = new GrowArray<>(DGrowArray::new);
            }
            else
            {
                workspace.reset();
            }

            int blockSize = blockLength * blockLength;

            double[] temp = workspace.grow().reshape(blockSize).data;

            int M = T.row1 - T.row0;

            double[] dataT   = T.original.data;
            int      offsetT = T.row0 * T.original.numCols + M * T.col0;

            for (int i = 0; i < M; i += blockLength)
            {
                int heightT = Math.Min(T.row1 - (i + T.row0), blockLength);

                int indexII = offsetT + T.original.numCols * (i + T.row0) + heightT * (i + T.col0);

                for (int j = 0; j < i; j += blockLength)
                {
                    int widthX = Math.Min(T.col1 - (j + T.col0), blockLength);

                    Array.Fill(temp, 0);

                    for (int k = j; k < i; k += blockLength)
                    {
                        int widthT = Math.Min(T.col1 - (k + T.col0), blockLength);

                        int indexL2 = offsetT + T.original.numCols * (i + T.row0) + heightT * (k + T.col0);
                        int indexX2 = offsetT + T.original.numCols * (k + T.row0) + widthT * (j + T.col0);

                        InnerMultiplication_DDRB.blockMultMinus(dataT, dataT, temp, indexL2, indexX2, 0, heightT, widthT, widthX);
                    }

                    int indexX = offsetT + T.original.numCols * (i + T.row0) + heightT * (j + T.col0);

                    InnerTriangularSolver_DDRB.solveL(dataT, temp, heightT, widthX, heightT, indexII, 0);
                    System.Array.Copy(temp, 0, dataT, indexX, widthX * heightT);
                }
                InnerTriangularSolver_DDRB.invertLower(dataT, heightT, indexII);
            }
        }