Esempio n. 1
0
        /**
         * Initializes class data structures and parameters
         */
        void initialize(DMatrixSparseCSC A)
        {
            m = A.numRows;
            n = A.numCols;
            int s = 4 * n + (ata ? (n + m + 1) : 0);

            gw.reshape(s);
            w = gw.data;

            // compute the transpose of A
            At.reshape(A.numCols, A.numRows, A.nz_length);
            CommonOps_DSCC.transpose(A, At, gw);

            // initialize w
            //Arrays.fill(w, 0, s, -1); // assign all values in workspace to -1
            for (var i = 0; i < s; i++)
            {
                w[i] = -1;
            }

            ancestor = 0;
            maxfirst = n;
            prevleaf = 2 * n;
            first    = 3 * n;
        }
Esempio n. 2
0
        /**
         * Computes and applies the fill reduction permutation. Either A is returned (unmodified) or the permutated
         * version of A.
         * @param A Input matrix. unmodified.
         * @return A permuted matrix. Might be A or a different matrix.
         */
        public DMatrixSparseCSC apply(DMatrixSparseCSC A)
        {
            if (fillReduce == null)
            {
                return(A);
            }
            fillReduce.process(A);

            IGrowArray gp = fillReduce.getRow();

            if (pinv.Length < gp.Length)
            {
                pinv = new int[gp.Length];
            }
            CommonOps_DSCC.permutationInverse(gp.data, pinv, gp.Length);
            if (symmetric)
            {
                CommonOps_DSCC.permuteSymmetric(A, pinv, Aperm, gw);
            }
            else
            {
                CommonOps_DSCC.permuteRowInv(pinv, A, Aperm);
            }
            return(Aperm);
        }
Esempio n. 3
0
 //@Override
 public DMatrixSparseCSC getRowPivot(DMatrixSparseCSC pivot)
 {
     if (pivot == null)
     {
         pivot = new DMatrixSparseCSC(L.numRows, L.numRows, 0);
     }
     pivot.reshape(L.numRows, L.numRows, L.numRows);
     CommonOps_DSCC.permutationMatrix(pinv, true, L.numRows, pivot);
     return(pivot);
 }
        /**
         * Performs matrix multiplication.  C = A*B<sup>T</sup></sup>
         *
         * @param A Matrix
         * @param B Matrix
         * @param C Storage for results.  Data length is increased if increased if insufficient.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         * @param gx (Optional) Storage for internal workspace.  Can be null.
         */
        public static void multTransB(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                      IGrowArray gw, DGrowArray gx)
        {
            if (!B.isIndicesSorted())
            {
                throw new ArgumentException("B must have its indices sorted.");
            }
            else if (!CommonOps_DSCC.checkIndicesSorted(B))
            {
                throw new ArgumentException("Crap. Not really sorted");
            }

            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);
            int[]    w = TriangularSolver_DSCC.adjust(gw, A.numRows + B.numCols, A.numRows);

            C.growMaxLength(A.nz_length + B.nz_length, false);
            C.indicesSorted = false;
            C.nz_length     = 0;
            C.col_idx[0]    = 0;

            // initialize w is the first index in each column of B
            int locationB = A.numRows;

            Array.Copy(B.col_idx, 0, w, locationB, B.numCols);

            for (int colC = 0; colC < B.numRows; colC++)
            {
                C.col_idx[colC + 1] = C.nz_length; // needs a value of B has nothing in the row

                // find the column in the transposed B
                int mark = colC + 1;
                for (int colB = 0; colB < B.numCols; colB++)
                {
                    int bi = w[locationB + colB];
                    if (bi < B.col_idx[colB + 1])
                    {
                        int row = B.nz_rows[bi];
                        if (row == colC)
                        {
                            multAddColA(A, colB, B.nz_values[bi], C, mark, x, w);
                            w[locationB + colB]++;
                        }
                    }
                }

                // take the values in the dense vector 'x' and put them into 'C'
                int idxC0 = C.col_idx[colC];
                int idxC1 = C.col_idx[colC + 1];

                for (int i = idxC0; i < idxC1; i++)
                {
                    C.nz_values[i] = x[C.nz_rows[i]];
                }
            }
        }
Esempio n. 5
0
        //@Override
        public void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            double[] b  = TriangularSolver_DSCC.adjust(gb, B.numRows);
            double[] bp = TriangularSolver_DSCC.adjust(gbp, B.numRows);
            double[] x  = TriangularSolver_DSCC.adjust(gx, X.numRows);

            int[] pinv = qr.getStructure().getPinv();

            // process each column in X and B individually
            for (int colX = 0; colX < X.numCols; colX++)
            {
                int index = colX;
                for (int i = 0; i < B.numRows; i++, index += X.numCols)
                {
                    b[i] = B.data[index];
                }

                // apply row pivots
                CommonOps_DSCC.permuteInv(pinv, b, bp, m);

                // apply Householder reflectors
                for (int j = 0; j < n; j++)
                {
                    QrHelperFunctions_DSCC.applyHouseholder(qr.getV(), j, qr.getBeta(j), bp);
                }
                // Solve for R*x = b
                TriangularSolver_DSCC.solveU(qr.getR(), bp);

                // undo the permutation
                double[] output;
                if (qr.isFillPermutated())
                {
                    CommonOps_DSCC.permute(qr.getFillPermutation(), bp, x, X.numRows);
                    output = x;
                }
                else
                {
                    output = bp;
                }

                index = colX;
                for (int i = 0; i < X.numRows; i++, index += X.numCols)
                {
                    X.data[index] = output[i];
                }
            }
        }
Esempio n. 6
0
        //@Override
        public void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
//        if( B.numCols != X.numCols || B.numRows != numRows || X.numRows != numCols) {
//            throw new ArgumentException("Unexpected matrix size");
//        }

            int[]    pinv = decomposition.getPinv();
            int[]    q    = decomposition.getReducePermutation();
            double[] x    = TriangularSolver_DSCC.adjust(gx, X.numRows);
            double[] b    = TriangularSolver_DSCC.adjust(gb, B.numRows);

            DMatrixSparseCSC L = decomposition.getL();
            DMatrixSparseCSC U = decomposition.getU();

            bool reduceFill = decomposition.getReduceFill() != null;

            // process each column in X and B individually
            for (int colX = 0; colX < X.numCols; colX++)
            {
                int index = colX;
                for (int i = 0; i < B.numRows; i++, index += X.numCols)
                {
                    b[i] = B.data[index];
                }

                CommonOps_DSCC.permuteInv(pinv, b, x, X.numRows);
                TriangularSolver_DSCC.solveL(L, x);
                TriangularSolver_DSCC.solveU(U, x);
                double[] d;
                if (reduceFill)
                {
                    CommonOps_DSCC.permute(q, x, b, X.numRows);
                    d = b;
                }
                else
                {
                    d = x;
                }
                index = colX;
                for (int i = 0; i < X.numRows; i++, index += X.numCols)
                {
                    X.data[index] = d[i];
                }
            }
        }
Esempio n. 7
0
        /**
         * <p>
         * Performs a rank-1 update operation on the submatrix specified by V with the multiply on the right.<br>
         * <br>
         * C = (I - &gamma;*v*v<sup>T</sup>)*A<br>
         * </p>
         * <p>
         * The order that matrix multiplies are performed has been carefully selected
         * to minimize the number of operations.
         * </p>
         *
         * <p>
         * Before this can become a truly generic operation the submatrix specification needs
         * to be made more generic.
         * </p>
         */
        public static void rank1UpdateMultR(DMatrixSparseCSC V, int colV, double gamma,
                                            DMatrixSparseCSC A, DMatrixSparseCSC C,
                                            IGrowArray gw, DGrowArray gx)
        {
            if (V.numRows != A.numRows)
            {
                throw new ArgumentException("Number of rows in V and A must match");
            }

            C.nz_length = 0;
            C.numRows   = V.numRows;
            C.numCols   = 0;

            for (int i = 0; i < A.numCols; i++)
            {
                double tau = CommonOps_DSCC.dotInnerColumns(V, colV, A, i, gw, gx);
                ImplCommonOps_DSCC.addColAppend(1.0, A, i, -gamma * tau, V, colV, C, gw);
            }
        }
Esempio n. 8
0
        public static void main(string[] args)
        {
            // create a random matrix that can be solved
            int N = 5;
            IMersenneTwister rand = new MersenneTwisterFast(234);

            DMatrixSparseCSC A = RandomMatrices_DSCC.rectangle(N, N, N * N / 4, rand);

            RandomMatrices_DSCC.ensureNotSingular(A, rand);

            // Create the LU decomposition
            LUSparseDecomposition_F64 <DMatrixSparseCSC> decompose =
                DecompositionFactory_DSCC.lu(FillReducing.NONE);

            // Decompose the matrix.
            // If you care about the A matrix being modified call decompose.inputModified()
            if (!decompose.decompose(A))
            {
                throw new InvalidOperationException("The matrix is singular");
            }

            // Extract new copies of the L and U matrices
            DMatrixSparseCSC L = decompose.getLower(null);
            DMatrixSparseCSC U = decompose.getUpper(null);
            DMatrixSparseCSC P = decompose.getRowPivot(null);

            // Storage for an intermediate step
            DMatrixSparseCSC tmp = (DMatrixSparseCSC)A.createLike();

            // Storage for the inverse matrix
            DMatrixSparseCSC Ainv = (DMatrixSparseCSC)A.createLike();

            // Solve for the inverse: P*I = L*U*inv(A)
            TriangularSolver_DSCC.solve(L, true, P, tmp, null, null, null);
            TriangularSolver_DSCC.solve(U, false, tmp, Ainv, null, null, null);

            // Make sure the inverse has been found. A*inv(A) = identity should be an identity matrix
            DMatrixSparseCSC found = (DMatrixSparseCSC)A.createLike();

            CommonOps_DSCC.mult(A, Ainv, found);
            found.print();
        }
        //@Override
        public DMatrixSparseCSC getR(DMatrixSparseCSC R, bool compact)
        {
            if (R == null)
            {
                R = new DMatrixSparseCSC(0, 0, 0);
            }

            R.set(this.R);
            if (m > n)
            {
                // there should only be only zeros past row n
                R.numRows = compact ? n : m;
            }
            else if (n > m && V.numRows != m)
            {
                DMatrixSparseCSC tmp = new DMatrixSparseCSC(m, n, 0);
                CommonOps_DSCC.extractRows(R, 0, m, tmp);
                R.set(tmp);
            }
            return(R);
        }
        //@Override
        public DMatrixSparseCSC getQ(DMatrixSparseCSC Q, bool compact)
        {
            if (Q == null)
            {
                Q = new DMatrixSparseCSC(1, 1, 0);
            }

            if (compact)
            {
                Q.reshape(V.numRows, n, 0);
            }
            else
            {
                Q.reshape(V.numRows, m, 0);
            }
            DMatrixSparseCSC I = CommonOps_DSCC.identity(V.numRows, Q.numCols);

            for (int i = V.numCols - 1; i >= 0; i--)
            {
                QrHelperFunctions_DSCC.rank1UpdateMultR(V, i, beta[i], I, Q, gwork, gx);
                I.set(Q);
            }

            // Apply P transpose to Q
            CommonOps_DSCC.permutationInverse(structure.pinv, structureP, V.numRows);
            CommonOps_DSCC.permuteRowInv(structureP, Q, I);

            // Remove fictitious rows
            if (V.numRows > m)
            {
                CommonOps_DSCC.extractRows(I, 0, m, Q);
            }
            else
            {
                Q.set(I);
            }

            return(Q);
        }
Esempio n. 11
0
        //@Override
        public void solve(DMatrixRMaj B, DMatrixRMaj X)
        {
            DMatrixSparseCSC L = cholesky.getL();

            int N = L.numRows;

            double[] b = TriangularSolver_DSCC.adjust(gb, N);
            double[] x = TriangularSolver_DSCC.adjust(gx, N);

            int[] Pinv = reduce.getArrayPinv();

            for (int col = 0; col < B.numCols; col++)
            {
                int index = col;
                for (int i = 0; i < N; i++, index += B.numCols)
                {
                    b[i] = B.data[index];
                }

                if (Pinv != null)
                {
                    CommonOps_DSCC.permuteInv(Pinv, b, x, N);
                    TriangularSolver_DSCC.solveL(L, x);
                    TriangularSolver_DSCC.solveTranL(L, x);
                    CommonOps_DSCC.permute(Pinv, x, b, N);
                }
                else
                {
                    TriangularSolver_DSCC.solveL(L, b);
                    TriangularSolver_DSCC.solveTranL(L, b);
                }

                index = col;
                for (int i = 0; i < N; i++, index += X.numCols)
                {
                    X.data[index] = b[i];
                }
            }
        }
Esempio n. 12
0
 //@Override
 public void minus(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC output)
 {
     CommonOps_DSCC.add(1, A, -1, B, output, null, null);
 }
Esempio n. 13
0
 //@Override
 public void mult(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC output)
 {
     CommonOps_DSCC.mult(A, B, output);
 }
Esempio n. 14
0
 //@Override
 public void transpose(DMatrixSparseCSC input, DMatrixSparseCSC output)
 {
     CommonOps_DSCC.transpose(input, output, null);
 }
Esempio n. 15
0
        public static void main(String[] args)
        {
            IMersenneTwister rand = new MersenneTwisterFast(234);

            // easy to work with sparse format, but hard to do computations with
            DMatrixSparseTriplet work = new DMatrixSparseTriplet(5, 4, 5);

            work.addItem(0, 1, 1.2);
            work.addItem(3, 0, 3);
            work.addItem(1, 1, 22.21234);
            work.addItem(2, 3, 6);

            // convert into a format that's easier to perform math with
            DMatrixSparseCSC Z = ConvertDMatrixStruct.convert(work, (DMatrixSparseCSC)null);

            // print the matrix to standard out in two different formats
            Z.print();
            Console.WriteLine();
            Z.printNonZero();
            Console.WriteLine();

            // Create a large matrix that is 5% filled
            DMatrixSparseCSC A = RandomMatrices_DSCC.rectangle(ROWS, COLS, (int)(ROWS * COLS * 0.05), rand);
            //          large vector that is 70% filled
            DMatrixSparseCSC x = RandomMatrices_DSCC.rectangle(COLS, XCOLS, (int)(XCOLS * COLS * 0.7), rand);

            Console.WriteLine("Done generating random matrices");
            // storage for the initial solution
            DMatrixSparseCSC y = new DMatrixSparseCSC(ROWS, XCOLS, 0);
            DMatrixSparseCSC z = new DMatrixSparseCSC(ROWS, XCOLS, 0);

            // To demonstration how to perform sparse math let's multiply:
            //                  y=A*x
            // Optional storage is set to null so that it will declare it internally
            long       before = DateTimeHelper.CurrentTimeMilliseconds;
            IGrowArray workA  = new IGrowArray(A.numRows);
            DGrowArray workB  = new DGrowArray(A.numRows);

            for (int i = 0; i < 100; i++)
            {
                CommonOps_DSCC.mult(A, x, y, workA, workB);
                CommonOps_DSCC.add(1.5, y, 0.75, y, z, workA, workB);
            }
            long after = DateTimeHelper.CurrentTimeMilliseconds;

            Console.WriteLine("norm = " + NormOps_DSCC.fastNormF(y) + "  sparse time = " + (after - before) + " ms");

            DMatrixRMaj Ad = ConvertDMatrixStruct.convert(A, (DMatrixRMaj)null);
            DMatrixRMaj xd = ConvertDMatrixStruct.convert(x, (DMatrixRMaj)null);
            DMatrixRMaj yd = new DMatrixRMaj(y.numRows, y.numCols);
            DMatrixRMaj zd = new DMatrixRMaj(y.numRows, y.numCols);

            before = DateTimeHelper.CurrentTimeMilliseconds;
            for (int i = 0; i < 100; i++)
            {
                CommonOps_DDRM.mult(Ad, xd, yd);
                CommonOps_DDRM.add(1.5, yd, 0.75, yd, zd);
            }
            after = DateTimeHelper.CurrentTimeMilliseconds;
            Console.WriteLine("norm = " + NormOps_DDRM.fastNormF(yd) + "  dense time  = " + (after - before) + " ms");
        }