Beispiel #1
0
        private static void checkInput(int blockLength,
                                       FSubmatrixD1 A, FSubmatrixD1 B,
                                       FSubmatrixD1 C)
        {
            int Arow = A.getRows();
            int Acol = A.getCols();
            int Brow = B.getRows();
            int Bcol = B.getCols();
            int Crow = C.getRows();
            int Ccol = C.getCols();

            if (Arow != Crow)
            {
                throw new InvalidOperationException("Mismatch A and C rows");
            }
            if (Bcol != Ccol)
            {
                throw new InvalidOperationException("Mismatch B and C columns");
            }
            if (Acol != Brow)
            {
                throw new InvalidOperationException("Mismatch A columns and B rows");
            }

            if (!MatrixOps_FDRB.blockAligned(blockLength, A))
            {
                throw new InvalidOperationException("Sub-Matrix A is not block aligned");
            }

            if (!MatrixOps_FDRB.blockAligned(blockLength, B))
            {
                throw new InvalidOperationException("Sub-Matrix B is not block aligned");
            }

            if (!MatrixOps_FDRB.blockAligned(blockLength, C))
            {
                throw new InvalidOperationException("Sub-Matrix C is not block aligned");
            }
        }
        /**
         * <p>
         * Solves upper triangular systems:<br>
         * <br>
         * B = R<sup>-1</sup> B<br>
         * <br>
         * </p>
         *
         * <p>Only the first B.numRows rows in R will be processed.  Lower triangular elements are ignored.<p>
         *
         * <p> Reverse or forward substitution is used depending upon L being transposed or not. </p>
         *
         * @param blockLength
         * @param R Upper triangular with dimensions m by m.  Not modified.
         * @param B A matrix with dimensions m by n.  Solution is written into here. Modified.
         * @param transR Is the triangular matrix transposed?
         */
        public static void solveR(int blockLength,
                                  FSubmatrixD1 R,
                                  FSubmatrixD1 B,
                                  bool transR)
        {
            int lengthR = B.row1 - B.row0;

            if (R.getCols() != lengthR)
            {
                throw new ArgumentException("Number of columns in R must be equal to the number of rows in B");
            }
            else if (R.getRows() != lengthR)
            {
                throw new ArgumentException("Number of rows in R must be equal to the number of rows in B");
            }

            FSubmatrixD1 Y = new FSubmatrixD1(B.original);

            FSubmatrixD1 Rinner = new FSubmatrixD1(R.original);
            FSubmatrixD1 Binner = new FSubmatrixD1(B.original);

            int startI, stepI;

            if (transR)
            {
                startI = 0;
                stepI  = blockLength;
            }
            else
            {
                startI = lengthR - lengthR % blockLength;
                if (startI == lengthR && lengthR >= blockLength)
                {
                    startI -= blockLength;
                }

                stepI = -blockLength;
            }

            for (int i = startI;; i += stepI)
            {
                if (transR)
                {
                    if (i >= lengthR)
                    {
                        break;
                    }
                }
                else
                {
                    if (i < 0)
                    {
                        break;
                    }
                }

                // width and height of the inner T(i,i) block
                int widthT = Math.Min(blockLength, lengthR - i);

                Rinner.col0 = R.col0 + i;
                Rinner.col1 = Rinner.col0 + widthT;
                Rinner.row0 = R.row0 + i;
                Rinner.row1 = Rinner.row0 + widthT;

                Binner.col0 = B.col0;
                Binner.col1 = B.col1;
                Binner.row0 = B.row0 + i;
                Binner.row1 = Binner.row0 + widthT;

                // solve the top row block
                // B(i,:) = T(i,i)^-1 Y(i,:)
                solveBlock(blockLength, true, Rinner, Binner, transR, false);

                bool updateY;
                if (transR)
                {
                    updateY = Rinner.row1 < R.row1;
                }
                else
                {
                    updateY = Rinner.row0 > 0;
                }
                if (updateY)
                {
                    // Y[i,:] = Y[i,:] - sum j=1:i-1 { T[i,j] B[j,i] }
                    // where i is the next block down
                    // The summation is a block inner product
                    if (transR)
                    {
                        Rinner.col0 = Rinner.col1;
                        Rinner.col1 = Math.Min(Rinner.col0 + blockLength, R.col1);
                        Rinner.row0 = R.row0;
                        //Rinner.row1 = Rinner.row1;

                        Binner.row0 = B.row0;
                        //Binner.row1 = Binner.row1;

                        Y.row0 = Binner.row1;
                        Y.row1 = Math.Min(Y.row0 + blockLength, B.row1);
                    }
                    else
                    {
                        Rinner.row1 = Rinner.row0;
                        Rinner.row0 = Rinner.row1 - blockLength;
                        Rinner.col1 = R.col1;

//                    Binner.row0 = Binner.row0;
                        Binner.row1 = B.row1;

                        Y.row0 = Binner.row0 - blockLength;
                        Y.row1 = Binner.row0;
                    }

                    // step through each block column
                    for (int k = B.col0; k < B.col1; k += blockLength)
                    {
                        Binner.col0 = k;
                        Binner.col1 = Math.Min(k + blockLength, B.col1);

                        Y.col0 = Binner.col0;
                        Y.col1 = Binner.col1;

                        if (transR)
                        {
                            // Y = Y - T^T * B
                            MatrixMult_FDRB.multMinusTransA(blockLength, Rinner, Binner, Y);
                        }
                        else
                        {
                            // Y = Y - T * B
                            MatrixMult_FDRB.multMinus(blockLength, Rinner, Binner, Y);
                        }
                    }
                }
            }
        }