コード例 #1
0
        /**
         * <p>
         * Checks to see if a matrix is orthogonal or isometric.
         * </p>
         *
         * @param Q The matrix being tested. Not modified.
         * @param tol Tolerance.
         * @return True if it passes the test.
         */
        public static bool isOrthogonal(DMatrixSparseCSC Q, double tol)
        {
            if (Q.numRows < Q.numCols)
            {
                throw new ArgumentException("The number of rows must be more than or equal to the number of columns");
            }

            IGrowArray gw = new IGrowArray();
            DGrowArray gx = new DGrowArray();

            for (int i = 0; i < Q.numRows; i++)
            {
                for (int j = i + 1; j < Q.numCols; j++)
                {
                    double val = CommonOps_DSCC.dotInnerColumns(Q, i, Q, j, gw, gx);

                    if (!(Math.Abs(val) <= tol))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #2
0
 private static void fillSequence(IGrowArray perm)
 {
     for (int i = 0; i < perm.Length; i++)
     {
         perm.data[i] = i;
     }
 }
コード例 #3
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);
        }
コード例 #4
0
 public static int[] adjust(IGrowArray gwork, int desired, int zeroToM)
 {
     int[] w = adjust(gwork, desired);
     //Arrays.fill(w,0,zeroToM,0);
     Array.Clear(w, 0, zeroToM);
     return(w);
 }
コード例 #5
0
        /**
         * <p>Determines which elements in 'X' will be non-zero when the system below is solved for.</p>
         * G*X = B
         *
         * <p>xi will contain a list of ordered row indexes in B which will be modified starting at xi[top] to xi[n-1].  top
         * is the value returned by this function.</p>
         *
         * <p>See cs_reach in dsparse library to understand the algorithm.  This code follow the spirit but not
         * the details because of differences in the contract.</p>
         *
         * @param G    (Input) Lower triangular system matrix.  Diagonal elements are assumed to be not zero.  Not modified.
         * @param B    (Input) Matrix B. Not modified.
         * @param colB Column in B being solved for
         * @param pinv (Input, Optional) Column pivots in G. Null if no pivots.
         * @param xi   (Output) List of row indices in B which are non-zero in graph order.  Must have length B.numRows
         * @param gwork workspace array used internally. Can be null.
         * @return Returns the index of the first element in the xi list.  Also known as top.
         */
        public static int searchNzRowsInB(DMatrixSparseCSC G, DMatrixSparseCSC B, int colB, int[] pinv,
                                          int[] xi, IGrowArray gwork)
        {
            if (xi.Length < B.numRows)
            {
                throw new ArgumentException("xi must be at least this long: " + B.numRows);
            }

            // this is a change from csparse. CSparse marks an entry by modifying G then reverting it. This can cause
            // weird unexplained behavior when people start using threads...
            int[] w = adjust(gwork, B.numRows * 2, B.numRows);

            // use 'w' as a marker to know which rows in B have been examined.  0 = unexamined and 1 = examined
            int idx0 = B.col_idx[colB];
            int idx1 = B.col_idx[colB + 1];

            int top = G.numRows;

            for (int i = idx0; i < idx1; i++)
            {
                int rowB = B.nz_rows[i];

                if (w[rowB] == 0)
                {
                    top = searchNzRowsInB_DFS(rowB, G, top, pinv, xi, w);
                }
            }

            return(top);
        }
コード例 #6
0
        /**
         * Computes the solution to the triangular system.
         *
         * @param G     (Input) Lower or upper triangular matrix.  diagonal elements must be non-zero.  Not modified.
         * @param lower true for lower triangular and false for upper
         * @param B     (Input) Matrix.  Not modified.
         * @param X     (Output) Solution
         * @param g_x   (Optional) Storage for workspace.
         * @param g_xi  (Optional) Storage for workspace.
         * @param g_w   (Optional) Storage for workspace.
         */
        public static void solve(DMatrixSparseCSC G, bool lower,
                                 DMatrixSparseCSC B, DMatrixSparseCSC X,
                                 DGrowArray g_x, IGrowArray g_xi, IGrowArray g_w)
        {
            double[] x = adjust(g_x, G.numRows);
            if (g_xi == null)
            {
                g_xi = new IGrowArray();
            }
            int[] xi = adjust(g_xi, G.numRows);

            X.nz_length     = 0;
            X.col_idx[0]    = 0;
            X.indicesSorted = false;

            for (int colB = 0; colB < B.numCols; colB++)
            {
                int top = solve(G, lower, B, colB, x, null, g_xi, g_w);

                int nz_count = X.numRows - top;
                if (X.nz_values.Length < X.nz_length + nz_count)
                {
                    X.growMaxLength(X.nz_length * 2 + nz_count, true);
                }

                for (int p = top; p < X.numRows; p++, X.nz_length++)
                {
                    X.nz_rows[X.nz_length]   = xi[p];
                    X.nz_values[X.nz_length] = x[xi[p]];
                }
                X.col_idx[colB + 1] = X.nz_length;
            }
        }
コード例 #7
0
        /**
         * Performs matrix addition:<br>
         * C = &alpha;A + &beta;B
         *
         * @param alpha scalar value multiplied against A
         * @param A Matrix
         * @param beta scalar value multiplied against B
         * @param B Matrix
         * @param C Output matrix.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         * @param gx (Optional) Storage for internal workspace.  Can be null.
         */
        public static void add(double alpha, DMatrixSparseCSC A, double beta, DMatrixSparseCSC B, DMatrixSparseCSC C,
                               IGrowArray gw, DGrowArray gx)
        {
            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);
            int[]    w = TriangularSolver_DSCC.adjust(gw, A.numRows, A.numRows);

            C.indicesSorted = false;
            C.nz_length     = 0;

            for (int col = 0; col < A.numCols; col++)
            {
                C.col_idx[col] = C.nz_length;

                ImplSparseSparseMult_DSCC.multAddColA(A, col, alpha, C, col + 1, x, w);
                ImplSparseSparseMult_DSCC.multAddColA(B, col, beta, C, col + 1, x, w);

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

                for (int i = idxC0; i < idxC1; i++)
                {
                    C.nz_values[i] = x[C.nz_rows[i]];
                }
            }
        }
コード例 #8
0
        /**
         * Converts DMatrixSparseTriplet into a DMatrixSparseCSC. Duplicate elements in triplet will result in an
         * illegal matrix in output having duplicate elements.
         *
         * @param src Original matrix which is to be copied.  Not modified.
         * @param dst Destination. Will be a copy.  Modified.
         * @param histStorage Workspace. Can be null.
         */
        public static DMatrixSparseCSC convert(DMatrixSparseTriplet src, DMatrixSparseCSC dst,
                                               IGrowArray histStorage)
        {
            dst = UtilEjml.reshapeOrDeclare(dst, src.numRows, src.numCols, src.nz_length);

            int[] hist = UtilEjml.adjustClear(histStorage, src.numCols);

            // compute the number of elements in each columns
            for (int i = 0; i < src.nz_length; i++)
            {
                hist[src.nz_rowcol.data[i * 2 + 1]]++;
            }

            // define col_idx
            dst.histogramToStructure(hist);
            System.Array.Copy(dst.col_idx, 0, hist, 0, dst.numCols);

            // now write the row indexes and the values
            for (int i = 0; i < src.nz_length; i++)
            {
                int    row   = src.nz_rowcol.data[i * 2];
                int    col   = src.nz_rowcol.data[i * 2 + 1];
                double value = src.nz_value.data[i];

                int index = hist[col]++;
                dst.nz_rows[index]   = row;
                dst.nz_values[index] = value;
            }
            dst.indicesSorted = false;

            return(dst);
        }
コード例 #9
0
 /**
  * Resizes the array to ensure that it is at least of length desired and returns its internal array
  */
 public static int[] adjust(IGrowArray gwork, int desired)
 {
     if (gwork == null)
     {
         gwork = new IGrowArray();
     }
     gwork.reshape(desired);
     return(gwork.data);
 }
コード例 #10
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        public static void multTransA(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                      IGrowArray gw, DGrowArray gx)
        {
            if (A.numCols != C.numRows || B.numCols != C.numCols)
            {
                throw new ArgumentException("Inconsistent matrix shapes");
            }

            ImplSparseSparseMult_DSCC.multTransA(A, B, C, gw, gx);
        }
コード例 #11
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        /**
         * Performs matrix addition:<br>
         * C = &alpha;A + &beta;B
         *
         * @param alpha scalar value multiplied against A
         * @param A Matrix
         * @param beta scalar value multiplied against B
         * @param B Matrix
         * @param C Output matrix.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         * @param gx (Optional) Storage for internal workspace.  Can be null.
         */
        public static void add(double alpha, DMatrixSparseCSC A, double beta, DMatrixSparseCSC B, DMatrixSparseCSC C,
                               IGrowArray gw, DGrowArray gx)
        {
            if (A.numRows != B.numRows || A.numCols != B.numCols || A.numRows != C.numRows || A.numCols != C.numCols)
            {
                throw new ArgumentException("Inconsistent matrix shapes");
            }

            ImplCommonOps_DSCC.add(alpha, A, beta, B, C, gw, gx);
        }
コード例 #12
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        /**
         * Performs an element-wise multiplication.<br>
         * C[i,j] = A[i,j]*B[i,j]<br>
         * All matrices must have the same shape.
         *
         * @param A (Input) Matrix.
         * @param B (Input) Matrix
         * @param C (Ouptut) Matrix.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         * @param gx (Optional) Storage for internal workspace.  Can be null.
         */
        public static void elementMult(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                       IGrowArray gw, DGrowArray gx)
        {
            if (A.numCols != B.numCols || A.numRows != B.numRows || A.numCols != C.numCols || A.numRows != C.numRows)
            {
                throw new ArgumentException("All inputs must have the same number of rows and columns");
            }

            ImplCommonOps_DSCC.elementMult(A, B, C, gw, gx);
        }
コード例 #13
0
        /**
         * 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]];
                }
            }
        }
コード例 #14
0
        /**
         * Performs element-wise multiplication:<br>
         * C_ij = A_ij * B_ij
         *
         * @param A (Input) Matrix
         * @param B (Input) Matrix
         * @param C (Output) matrix.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         * @param gx (Optional) Storage for internal workspace.  Can be null.
         */
        public static void elementMult(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                       IGrowArray gw, DGrowArray gx)
        {
            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);
            int[]    w = TriangularSolver_DSCC.adjust(gw, A.numRows);

            //Arrays.fill(w, 0, A.numRows, -1); // fill with -1. This will be a value less than column
            for (var i = 0; i < A.numRows; i++)
            {
                w[i] = -1;
            }

            C.indicesSorted = false; // Hmm I think if B is storted then C will be sorted...
            C.nz_length     = 0;

            for (int col = 0; col < A.numCols; col++)
            {
                int idxA0 = A.col_idx[col];
                int idxA1 = A.col_idx[col + 1];
                int idxB0 = B.col_idx[col];
                int idxB1 = B.col_idx[col + 1];

                // compute the maximum number of elements that there can be in this row
                int maxInRow = Math.Min(idxA1 - idxA0, idxB1 - idxB0);

                // make sure there are enough non-zero elements in C
                if (C.nz_length + maxInRow > C.nz_values.Length)
                {
                    C.growMaxLength(C.nz_values.Length + maxInRow, true);
                }

                // update the structure of C
                C.col_idx[col] = C.nz_length;

                // mark the rows that appear in A and save their value
                for (int i = idxA0; i < idxA1; i++)
                {
                    int row = A.nz_rows[i];
                    w[row] = col;
                    x[row] = A.nz_values[i];
                }

                // If a row appears in A and B, multiply and set as an element in C
                for (int i = idxB0; i < idxB1; i++)
                {
                    int row = B.nz_rows[i];
                    if (w[row] == col)
                    {
                        C.nz_values[C.nz_length] = x[row] * B.nz_values[i];
                        C.nz_rows[C.nz_length++] = row;
                    }
                }
            }
            C.col_idx[C.numCols] = C.nz_length;
        }
コード例 #15
0
 public ComputePermutation(bool hasRow, bool hasCol)
 {
     if (hasRow)
     {
         prow = new IGrowArray();
     }
     if (hasCol)
     {
         pcol = new IGrowArray();
     }
 }
コード例 #16
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        /**
         * Perform matrix transpose
         *
         * @param a Input matrix.  Not modified
         * @param a_t Storage for transpose of 'a'.  Must be correct shape.  data length might be adjusted.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         */
        public static void transpose(DMatrixSparseCSC a, DMatrixSparseCSC a_t, IGrowArray gw)
        {
            if (a_t.numRows != a.numCols || a_t.numCols != a.numRows)
            {
                throw new ArgumentException("Unexpected shape for transpose matrix");
            }

            a_t.growMaxLength(a.nz_length, false);
            a_t.nz_length = a.nz_length;

            ImplCommonOps_DSCC.transpose(a, a_t, gw);
        }
コード例 #17
0
        /**
         * <p>Sorts an elimination tree {@link #eliminationTree} into postorder. In a postoredered tree, the d proper
         * descendants of any node k are numbered k-d through k-1.  Non-recursive implementation for better performance.</p>
         *
         * <p>post[k] = i means node 'i' of the original tree is node 'k' in the postordered tree.</p>
         *
         * <p>See page 44</p>
         *
         * @param parent (Input) The elimination tree.
         * @param N      Number of elements in parent
         * @param post   (Output) Postordering permutation.
         * @param gwork  (Optional) Internal workspace. Can be null
         */
        public static void postorder(int[] parent, int N, int[] post, IGrowArray gwork)
        {
            if (parent.Length < N)
            {
                throw new ArgumentException("parent must be at least of length N");
            }
            if (post.Length < N)
            {
                throw new ArgumentException("post must be at least of length N");
            }

            int[] w = adjust(gwork, 3 * N);

            // w[0] to w[N-1] is initialized to the youngest child of node 'j'
            // w[N] to w[2N-1] is initialized to the second youngest child of node 'j'
            // w[2N] to w[3N-1] is the stacked of nodes to be examined in the dfs
            int next = N;

            // specify the linked list as being empty initially
            for (int j = 0; j < N; j++)
            {
                w[j] = -1;
            }
            // traverse nodes in reverse order
            for (int j = N - 1; j >= 0; j--)
            {
                // skip if j has no parent, i.e. is a root node
                if (parent[j] == -1)
                {
                    continue;
                }
                // add j to the list of parents
                w[next + j]  = w[parent[j]];
                w[parent[j]] = j;
            }

            // perform the DFS on each root node
            int k = 0;

            for (int j = 0; j < N; j++)
            {
                if (parent[j] != -1)
                {
                    continue;
                }

                k = postorder_dfs(j, k, w, post, N);
            }
        }
コード例 #18
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        /**
         * Performs matrix multiplication.  C = A*B<sup>T</sup>. B needs to be sorted and will be sorted if it
         * has not already been sorted.
         *
         * @param A (Input) Matrix. Not modified.
         * @param B (Input) Matrix. Value not modified but indicies will be sorted if not sorted already.
         * @param C (Output) 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 (A.numRows != C.numRows || B.numRows != C.numCols)
            {
                throw new ArgumentException("Inconsistent matrix shapes");
            }

            if (!B.isIndicesSorted())
            {
                B.sortIndices(null);
            }

            ImplSparseSparseMult_DSCC.multTransB(A, B, C, gw, gx);
        }
コード例 #19
0
        /**
         * Adds the results of adding a column in A and B as a new column in C.<br>
         * C(:,end+1) = &alpha;*A(:,colA) + &beta;*B(:,colB)
         *
         * @param alpha scalar
         * @param A matrix
         * @param colA column in A
         * @param beta scalar
         * @param B matrix
         * @param colB column in B
         * @param C Column in C
         * @param gw workspace
         */
        public static void addColAppend(double alpha, DMatrixSparseCSC A, int colA, double beta, DMatrixSparseCSC B,
                                        int colB,
                                        DMatrixSparseCSC C, IGrowArray gw)
        {
            if (A.numRows != B.numRows || A.numRows != C.numRows)
            {
                throw new ArgumentException("Number of rows in A, B, and C do not match");
            }

            int idxA0 = A.col_idx[colA];
            int idxA1 = A.col_idx[colA + 1];
            int idxB0 = B.col_idx[colB];
            int idxB1 = B.col_idx[colB + 1];

            C.growMaxColumns(++C.numCols, true);
            C.growMaxLength(C.nz_length + idxA1 - idxA0 + idxB1 - idxB0, true);

            int[] w = TriangularSolver_DSCC.adjust(gw, A.numRows);
            //Arrays.fill(w, 0, A.numRows, -1);
            for (var i = 0; i < A.numRows; i++)
            {
                w[i] = -1;
            }

            for (int i = idxA0; i < idxA1; i++)
            {
                int row = A.nz_rows[i];
                C.nz_rows[C.nz_length]   = row;
                C.nz_values[C.nz_length] = alpha * A.nz_values[i];
                w[row] = C.nz_length++;
            }

            for (int i = idxB0; i < idxB1; i++)
            {
                int row = B.nz_rows[i];
                if (w[row] != -1)
                {
                    C.nz_values[w[row]] += beta * B.nz_values[i];
                }
                else
                {
                    C.nz_values[C.nz_length] = beta * B.nz_values[i];
                    C.nz_rows[C.nz_length++] = row;
                }
            }
            C.col_idx[C.numCols] = C.nz_length;
        }
コード例 #20
0
        /**
         * Performs matrix multiplication.  C = A*B
         *
         * @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 mult(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                IGrowArray gw, DGrowArray gx)
        {
            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);
            int[]    w = TriangularSolver_DSCC.adjust(gw, A.numRows, A.numRows);

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

            // C(i,j) = sum_k A(i,k) * B(k,j)
            int idx0 = B.col_idx[0];

            for (int bj = 1; bj <= B.numCols; bj++)
            {
                int colB = bj - 1;
                int idx1 = B.col_idx[bj];
                C.col_idx[bj] = C.nz_length;

                if (idx0 == idx1)
                {
                    continue;
                }

                // C(:,j) = sum_k A(:,k)*B(k,j)
                for (int bi = idx0; bi < idx1; bi++)
                {
                    int    rowB = B.nz_rows[bi];
                    double valB = B.nz_values[bi]; // B(k,j)  k=rowB j=colB

                    multAddColA(A, rowB, valB, C, colB + 1, x, w);
                }

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

                for (int i = idxC0; i < idxC1; i++)
                {
                    C.nz_values[i] = x[C.nz_rows[i]];
                }

                idx0 = idx1;
            }
        }
コード例 #21
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);
            }
        }
コード例 #22
0
        /**
         * Computes the inner product of two column vectors taken from the input matrices.
         *
         * <p>dot = A(:,colA)'*B(:,colB)</p>
         *
         * @param A Matrix
         * @param colA Column in A
         * @param B Matrix
         * @param colB Column in B
         * @return Dot product
         */
        public static double dotInnerColumns(DMatrixSparseCSC A, int colA, DMatrixSparseCSC B, int colB,
                                             IGrowArray gw, DGrowArray gx)
        {
            if (A.numRows != B.numRows)
            {
                throw new ArgumentException("Number of rows must match.");
            }

            int[] w = TriangularSolver_DSCC.adjust(gw, A.numRows);
            //Arrays.fill(w,0,A.numRows,-1);
            for (var i = 0; i < A.numRows; i++)
            {
                w[i] = -1;
            }
            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);

            int length = 0;

            int idx0 = A.col_idx[colA];
            int idx1 = A.col_idx[colA + 1];

            for (int i = idx0; i < idx1; i++)
            {
                int row = A.nz_rows[i];
                x[length] = A.nz_values[i];
                w[row]    = length++;
            }

            double dot = 0;

            idx0 = B.col_idx[colB];
            idx1 = B.col_idx[colB + 1];
            for (int i = idx0; i < idx1; i++)
            {
                int row = B.nz_rows[i];
                if (w[row] != -1)
                {
                    dot += x[w[row]] * B.nz_values[i];
                }
            }

            return(dot);
        }
コード例 #23
0
        /**
         * Performs a matrix transpose.
         *
         * @param A Original matrix.  Not modified.
         * @param C Storage for transposed 'a'.  Reshaped.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         */
        public static void transpose(DMatrixSparseCSC A, DMatrixSparseCSC C, IGrowArray gw)
        {
            int[] work = TriangularSolver_DSCC.adjust(gw, A.numRows, A.numRows);
            C.reshape(A.numCols, A.numRows, A.nz_length);

            // compute the histogram for each row in 'a'
            int idx0 = A.col_idx[0];

            for (int j = 1; j <= A.numCols; j++)
            {
                int idx1 = A.col_idx[j];
                for (int i = idx0; i < idx1; i++)
                {
                    if (A.nz_rows.Length <= i)
                    {
                        throw new InvalidOperationException("Egads");
                    }
                    work[A.nz_rows[i]]++;
                }
                idx0 = idx1;
            }

            // construct col_idx in the transposed matrix
            C.colsum(work);

            // fill in the row indexes
            idx0 = A.col_idx[0];
            for (int j = 1; j <= A.numCols; j++)
            {
                int col  = j - 1;
                int idx1 = A.col_idx[j];
                for (int i = idx0; i < idx1; i++)
                {
                    int row   = A.nz_rows[i];
                    int index = work[row]++;
                    C.nz_rows[index]   = col;
                    C.nz_values[index] = A.nz_values[i];
                }
                idx0 = idx1;
            }
        }
コード例 #24
0
 public virtual int[] getRowPivotV(IGrowArray pivot)
 {
     return(UtilEjml.pivotVector(this.pivot, LU.numRows, pivot));
 }
コード例 #25
0
 public void setGwork(IGrowArray gwork)
 {
     this.gwork = gwork;
 }
コード例 #26
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
 /**
  * Computes the inner product of two column vectors taken from the input matrices.
  *
  * <p>dot = A(:,colA)'*B(:,colB)</p>
  *
  * @param A Matrix
  * @param colA Column in A
  * @param B Matrix
  * @param colB Column in B
  * @return Dot product
  */
 public static double dotInnerColumns(DMatrixSparseCSC A, int colA, DMatrixSparseCSC B, int colB,
                                      IGrowArray gw, DGrowArray gx)
 {
     return(ImplSparseSparseMult_DSCC.dotInnerColumns(A, colA, B, colB, gw, gx));
 }
コード例 #27
0
        /**
         * Performs matrix multiplication.  C = A<sup>T</sup></sup>*B
         *
         * @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 multTransA(DMatrixSparseCSC A, DMatrixSparseCSC B, DMatrixSparseCSC C,
                                      IGrowArray gw, DGrowArray gx)
        {
            double[] x = TriangularSolver_DSCC.adjust(gx, A.numRows);
            int[]    w = TriangularSolver_DSCC.adjust(gw, A.numRows, A.numRows);

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

            int idxB0 = B.col_idx[0];

            for (int bj = 1; bj <= B.numCols; bj++)
            {
                int idxB1 = B.col_idx[bj];
                C.col_idx[bj] = C.nz_length;

                if (idxB0 == idxB1)
                {
                    continue;
                }

                // convert the column of B into a dense format and mark which rows are used
                for (int bi = idxB0; bi < idxB1; bi++)
                {
                    int rowB = B.nz_rows[bi];
                    x[rowB] = B.nz_values[bi];
                    w[rowB] = bj;
                }

                // C(colA,colB) = A(:,colA)*B(:,colB)
                for (int colA = 0; colA < A.numCols; colA++)
                {
                    int idxA0 = A.col_idx[colA];
                    int idxA1 = A.col_idx[colA + 1];

                    double sum = 0;
                    for (int ai = idxA0; ai < idxA1; ai++)
                    {
                        int rowA = A.nz_rows[ai];
                        if (w[rowA] == bj)
                        {
                            sum += x[rowA] * A.nz_values[ai];
                        }
                    }

                    if (sum != 0)
                    {
                        if (C.nz_length == C.nz_values.Length)
                        {
                            C.growMaxLength(C.nz_length * 2 + 1, true);
                        }
                        C.nz_values[C.nz_length] = sum;
                        C.nz_rows[C.nz_length++] = colA;
                    }
                }
                C.col_idx[bj] = C.nz_length;
                idxB0         = idxB1;
            }
        }
コード例 #28
0
ファイル: CommonOps_DSCC.cs プロジェクト: lulzzz/BraneCloud
        /**
         * Applies the permutation to upper triangular symmetric matrices. Typically a symmetric matrix only stores the
         * upper triangular part, so normal permutation will have undesirable results, e.g. the zeros will get mixed
         * in and will no longer be symmetric. This algorithm will handle the implicit lower triangular and construct
         * new upper triangular matrix.
         *
         * <p>See page cs_symperm() on Page 22 of "Direct Methods for Sparse Linear Systems"</p>
         *
         * @param input (Input) Upper triangular symmetric matrix which is to be permuted.
         *              Entries below the diagonal are ignored.
         * @param permInv (Input) Inverse permutation vector.  Specifies new order of the rows and columns.
         * @param output (Output) Upper triangular symmetric matrix which has the permutation stored in it.  Reshaped.
         * @param gw (Optional) Storage for internal workspace.  Can be null.
         */
        public static void permuteSymmetric(DMatrixSparseCSC input, int[] permInv, DMatrixSparseCSC output,
                                            IGrowArray gw)
        {
            if (input.numRows != input.numCols)
            {
                throw new ArgumentException("Input must be a square matrix");
            }
            if (input.numRows != permInv.Length)
            {
                throw new ArgumentException("Number of column in input must match length of permInv");
            }
            if (input.numCols != permInv.Length)
            {
                throw new ArgumentException("Number of rows in input must match length of permInv");
            }

            int N = input.numCols;

            int[] w = TriangularSolver_DSCC.adjustClear(gw, N); // histogram with column counts

            output.reshape(N, N, 0);
            output.indicesSorted = false;
            output.col_idx[0]    = 0;

            // determine column counts for output
            for (int j = 0; j < N; j++)
            {
                int j2   = permInv[j];
                int idx0 = input.col_idx[j];
                int idx1 = input.col_idx[j + 1];

                for (int p = idx0; p < idx1; p++)
                {
                    int i = input.nz_rows[p];
                    if (i > j) // ignore the lower triangular portion
                    {
                        continue;
                    }
                    int i2 = permInv[i];

                    w[i2 > j2 ? i2 : j2]++;
                }
            }

            // update structure of output
            output.colsum(w);

            for (int j = 0; j < N; j++)
            {
                // column j of Input is row j2 of Output
                int j2   = permInv[j];
                int idx0 = input.col_idx[j];
                int idx1 = input.col_idx[j + 1];

                for (int p = idx0; p < idx1; p++)
                {
                    int i = input.nz_rows[p];
                    if (i > j) // ignore the lower triangular portion
                    {
                        continue;
                    }

                    int i2 = permInv[i];
                    // row i of Input is row i2 of Output
                    int q = w[i2 > j2 ? i2 : j2]++;
                    output.nz_rows[q]   = i2 < j2 ? i2 : j2;
                    output.nz_values[q] = input.nz_values[p];
                }
            }
        }
コード例 #29
0
 public void setGw(IGrowArray gw)
 {
     this.gw = gw;
 }
コード例 #30
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");
        }