Beispiel #1
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]];
                }
            }
        }
Beispiel #2
0
        /**
         * <p>
         * Solves for x in the following equation:<br>
         * <br>
         * A*x = b
         * </p>
         *
         * <p>
         * If the system could not be solved then false is returned.  If it returns true
         * that just means the algorithm finished operating, but the results could still be bad
         * because 'A' is singular or nearly singular.
         * </p>
         *
         * <p>
         * If repeat calls to solve are being made then one should consider using {@link LinearSolverFactory_DSCC}
         * instead.
         * </p>
         *
         * <p>
         * It is ok for 'b' and 'x' to be the same matrix.
         * </p>
         *
         * @param a (Input) A matrix that is m by n. Not modified.
         * @param b (Input) A matrix that is n by k. Not modified.
         * @param x (Output) A matrix that is m by k. Modified.
         *
         * @return true if it could invert the matrix false if it could not.
         */
        public static bool solve(DMatrixSparseCSC a,
                                 DMatrixRMaj b,
                                 DMatrixRMaj x)
        {
            LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver;

            if (a.numRows > a.numCols)
            {
                solver = LinearSolverFactory_DSCC.qr(FillReducing.NONE); // todo specify a filling that makes sense
            }
            else
            {
                solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE);
            }

            // Ensure that the input isn't modified
            if (solver.modifiesA())
            {
                a = (DMatrixSparseCSC)a.copy();
            }

            if (solver.modifiesB())
            {
                b = (DMatrixRMaj)b.copy();
            }

            // decompose then solve the matrix
            if (!solver.setA(a))
            {
                return(false);
            }

            solver.solve(b, x);
            return(true);
        }
        /**
         * Computes the quality of a triangular matrix, where the quality of a matrix
         * is defined in {@link LinearSolverDense#quality()}.  In
         * this situation the quality os the absolute value of the product of
         * each diagonal element divided by the magnitude of the largest diagonal element.
         * If all diagonal elements are zero then zero is returned.
         *
         * @param T A matrix.
         * @return the quality of the system.
         */
        public static double qualityTriangular(DMatrixSparseCSC T)
        {
            int N = Math.Min(T.numRows, T.numCols);

            double max = T.unsafe_get(0, 0);

            for (int i = 1; i < N; i++)
            {
                max = Math.Max(max, Math.Abs(T.unsafe_get(i, i)));
            }

            if (max == 0.0)
            {
                return(0.0);
            }

            double quality = 1.0;

            for (int i = 0; i < N; i++)
            {
                quality *= T.unsafe_get(i, i) / max;
            }

            return(Math.Abs(quality));
        }
Beispiel #4
0
        public static void removeZeros(DMatrixSparseCSC A, double tol)
        {
            int offset = 0;

            for (int i = 0; i < A.numCols; i++)
            {
                int idx0 = A.col_idx[i] + offset;
                int idx1 = A.col_idx[i + 1];

                for (int j = idx0; j < idx1; j++)
                {
                    double val = A.nz_values[j];
                    if (Math.Abs(val) > tol)
                    {
                        A.nz_rows[j - offset]   = A.nz_rows[j];
                        A.nz_values[j - offset] = val;
                    }
                    else
                    {
                        offset++;
                    }
                }
                A.col_idx[i + 1] -= offset;
            }
            A.nz_length -= offset;
        }
        /**
         * <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);
        }
        /**
         * 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;
            }
        }
Beispiel #7
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;
        }
Beispiel #8
0
        /**
         * <p>
         * Performs a matrix inversion operation that does not modify the original
         * and stores the results in another matrix.  The two matrices must have the
         * same dimension.<br>
         * <br>
         * B = A<sup>-1</sup>
         * </p>
         *
         * <p>
         * If the algorithm could not invert the matrix then false is returned.  If it returns true
         * that just means the algorithm finished.  The results could still be bad
         * because the matrix is singular or nearly singular.
         * </p>
         *
         * <p>
         * For medium to large matrices there might be a slight performance boost to using
         * {@link LinearSolverFactory_DSCC} instead.
         * </p>
         *
         * @param A (Input) The matrix that is to be inverted. Not modified.
         * @param inverse (Output) Where the inverse matrix is stored.  Modified.
         * @return true if it could invert the matrix false if it could not.
         */
        public static bool invert(DMatrixSparseCSC A, DMatrixRMaj inverse)
        {
            if (A.numRows != A.numCols)
            {
                throw new ArgumentException("A must be a square matrix");
            }
            if (A.numRows != inverse.numRows || A.numCols != inverse.numCols)
            {
                throw new ArgumentException("A and inverse must have the same shape.");
            }

            LinearSolverSparse <DMatrixSparseCSC, DMatrixRMaj> solver;

            solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE);

            // Ensure that the input isn't modified
            if (solver.modifiesA())
            {
                A = (DMatrixSparseCSC)A.copy();
            }

            DMatrixRMaj I = CommonOps_DDRM.identity(A.numRows);

            // decompose then solve the matrix
            if (!solver.setA(A))
            {
                return(false);
            }

            solver.solve(I, inverse);
            return(true);
        }
Beispiel #9
0
        /**
         * Converts the permutation matrix into a vector
         * @param P (Input) Permutation matrix
         * @param vector (Output) Permutation vector
         */
        public static void permutationVector(DMatrixSparseCSC P, int[] vector)
        {
            if (P.numCols != P.numRows)
            {
                throw new ArgumentException("Expected a square matrix");
            }
            else if (P.nz_length != P.numCols)
            {
                throw new ArgumentException("Expected N non-zero elements in permutation matrix");
            }
            else if (vector.Length < P.numCols)
            {
                throw new ArgumentException("vector is too short");
            }

            int M = P.numCols;

            for (int i = 0; i < M; i++)
            {
                if (P.col_idx[i + 1] != i + 1)
                {
                    throw new ArgumentException("Unexpected number of elements in a column");
                }

                vector[P.nz_rows[i]] = i;
            }
        }
        public static DMatrixRMaj convert(DMatrixSparseCSC src, DMatrixRMaj dst)
        {
            if (dst == null)
            {
                dst = new DMatrixRMaj(src.numRows, src.numCols);
            }
            else
            {
                dst.reshape(src.numRows, src.numCols);
                dst.zero();
            }

            int idx0 = src.col_idx[0];

            for (int j = 1; j <= src.numCols; j++)
            {
                int idx1 = src.col_idx[j];

                for (int i = idx0; i < idx1; i++)
                {
                    int    row = src.nz_rows[i];
                    double val = src.nz_values[i];

                    dst.unsafe_set(row, j - 1, val);
                }
                idx0 = idx1;
            }

            return(dst);
        }
Beispiel #11
0
        public static bool isTranspose(DMatrixSparseCSC A, DMatrixSparseCSC B, double tol)
        {
            if (A.numCols != B.numRows || A.numRows != B.numCols)
            {
                return(false);
            }
            if (A.nz_length != B.nz_length)
            {
                return(false);
            }
            if (!A.indicesSorted)
            {
                throw new ArgumentException("A must have sorted indicies");
            }

            DMatrixSparseCSC Btran = new DMatrixSparseCSC(B.numCols, B.numRows, B.nz_length);

            CommonOps_DSCC.transpose(B, Btran, null);
            Btran.sortIndices(null);

            for (int i = 0; i < B.nz_length; i++)
            {
                if (A.nz_rows[i] != Btran.nz_rows[i])
                {
                    return(false);
                }
                if (Math.Abs(A.nz_values[i] - Btran.nz_values[i]) > tol)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #12
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);
        }
Beispiel #13
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);
        }
        /**
         * Performs the performing operation x = x + A(:,i)*alpha
         *
         * <p>NOTE: This is the same as cs_scatter() in csparse.</p>
         */
        public static void multAddColA(DMatrixSparseCSC A, int colA,
                                       double alpha,
                                       DMatrixSparseCSC C, int mark,
                                       double[] x, int[] w)
        {
            int idxA0 = A.col_idx[colA];
            int idxA1 = A.col_idx[colA + 1];

            for (int j = idxA0; j < idxA1; j++)
            {
                int row = A.nz_rows[j];

                if (w[row] < mark)
                {
                    if (C.nz_length >= C.nz_rows.Length)
                    {
                        C.growMaxLength(C.nz_length * 2 + 1, true);
                    }

                    w[row] = mark;
                    C.nz_rows[C.nz_length] = row;
                    C.col_idx[mark]        = ++C.nz_length;
                    x[row] = A.nz_values[j] * alpha;
                }
                else
                {
                    x[row] += A.nz_values[j] * alpha;
                }
            }
        }
        public static void mult(DMatrixSparseCSC A, DMatrixRMaj B, DMatrixRMaj C)
        {
            C.zero();

            // C(i,j) = sum_k A(i,k) * B(k,j)
            for (int k = 0; k < A.numCols; k++)
            {
                int idx0 = A.col_idx[k];
                int idx1 = A.col_idx[k + 1];

                for (int indexA = idx0; indexA < idx1; indexA++)
                {
                    int    i      = A.nz_rows[indexA];
                    double valueA = A.nz_values[indexA];

                    int indexB = k * B.numCols;
                    int indexC = i * C.numCols;
                    int end    = indexB + B.numCols;

//                for (int j = 0; j < B.numCols; j++) {
                    while (indexB < end)
                    {
                        C.data[indexC++] += valueA * B.data[indexB++];
                    }
                }
            }
        }
        public static DMatrixSparseTriplet convert(DMatrixSparseCSC src, DMatrixSparseTriplet dst)
        {
            if (dst == null)
            {
                dst = new DMatrixSparseTriplet(src.numRows, src.numCols, src.nz_length);
            }
            else
            {
                dst.reshape(src.numRows, src.numCols);
            }

            int i0 = src.col_idx[0];

            for (int col = 0; col < src.numCols; col++)
            {
                int i1 = src.col_idx[col + 1];

                for (int i = i0; i < i1; i++)
                {
                    int row = src.nz_rows[i];
                    dst.addItem(row, col, src.nz_values[i]);
                }
                i0 = i1;
            }

            return(dst);
        }
Beispiel #17
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);
        }
Beispiel #18
0
        public static bool isIdentity(DMatrixSparseCSC A, double tol)
        {
            if (A.numCols != A.numRows)
            {
                return(false);
            }

            if (A.nz_length != A.numCols)
            {
                return(false);
            }

            for (int i = 1; i <= A.numCols; i++)
            {
                if (A.col_idx[i] != i)
                {
                    return(false);
                }
                if (Math.Abs(A.nz_values[i - 1] - 1) > tol)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #19
0
        /**
         * Checks to see if row indicies are sorted into ascending order.  O(N)
         * @return true if sorted and false if not
         */
        public static bool checkIndicesSorted(DMatrixSparseCSC A)
        {
            for (int j = 0; j < A.numCols; j++)
            {
                int idx0 = A.col_idx[j];
                int idx1 = A.col_idx[j + 1];

                if (idx0 != idx1 && A.nz_rows[idx0] >= A.numRows)
                {
                    return(false);
                }

                for (int i = idx0 + 1; i < idx1; i++)
                {
                    int row = A.nz_rows[i];
                    if (A.nz_rows[i - 1] >= row)
                    {
                        return(false);
                    }
                    if (row >= A.numRows)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #20
0
        /**
         * Applies the row permutation specified by the vector to the input matrix and save the results
         * in the output matrix.  output[perm[j],:] = input[j,:]
         *
         * @param permInv (Input) Inverse permutation vector.  Specifies new order of the rows.
         * @param input (Input) Matrix which is to be permuted
         * @param output (Output) Matrix which has the permutation stored in it.  Is reshaped.
         */
        public static void permuteRowInv(int[] permInv, DMatrixSparseCSC input, DMatrixSparseCSC output)
        {
            if (input.numRows > permInv.Length)
            {
                throw new ArgumentException("permutation vector must have at least as many elements as input has rows");
            }

            output.reshape(input.numRows, input.numCols, input.nz_length);
            output.nz_length     = input.nz_length;
            output.indicesSorted = false;

            Array.Copy(input.nz_values, 0, output.nz_values, 0, input.nz_length);
            Array.Copy(input.col_idx, 0, output.col_idx, 0, input.numCols + 1);

            int idx0 = 0;

            for (int i = 0; i < input.numCols; i++)
            {
                int idx1 = output.col_idx[i + 1];

                for (int j = idx0; j < idx1; j++)
                {
                    output.nz_rows[j] = permInv[input.nz_rows[j]];
                }
                idx0 = idx1;
            }
        }
Beispiel #21
0
        /**
         * Creates a submatrix by extracting the specified rows from A. rows = {row0 %le; i %le; row1}.
         * @param A (Input) matrix
         * @param row0 First row. Inclusive
         * @param row1 Last row+1.
         * @param out (Output, Option) Storage for output matrix
         * @return The submatrix
         */
        public static DMatrixSparseCSC extractRows(DMatrixSparseCSC A, int row0, int row1, DMatrixSparseCSC output)
        {
            if (output == null)
            {
                output = new DMatrixSparseCSC(1, 1, 1);
            }

            output.reshape(row1 - row0, A.numCols, A.nz_length);
//        output.col_idx[0] = 0;
//        output.nz_length = 0;

            for (int col = 0; col < A.numCols; col++)
            {
                int idx0 = A.col_idx[col];
                int idx1 = A.col_idx[col + 1];

                for (int i = idx0; i < idx1; i++)
                {
                    int row = A.nz_rows[i];
                    if (row >= row0 && row < row1)
                    {
                        output.nz_values[output.nz_length] = A.nz_values[i];
                        output.nz_rows[output.nz_length++] = row - row0;
                    }
                }
                output.col_idx[col + 1] = output.nz_length;
            }

            return(output);
        }
Beispiel #22
0
        /// <summary>
        /// Create a simple matrix of the specified type
        /// </summary>
        /// <param name="numRows"> The number of rows in the matrix. </param>
        /// <param name="numCols"> The number of columns in the matrix. </param>
        /// <param name="type"> The matrix type </param>
        public SimpleMatrix(int numRows, int numCols, MatrixType type)
        {
            switch (type.tipo)
            {
            case Types.DDRM:
                mat = new DMatrixRMaj(numRows, numCols);
                break;

            case Types.FDRM:
                //mat = new FMatrixRMaj(numRows, numCols);
                break;

            case Types.ZDRM:
                mat = new ZMatrixRMaj(numRows, numCols);
                break;

            case Types.CDRM:
                //mat = new CMatrixRMaj(numRows, numCols);
                break;

            case Types.DSCC:
                mat = new DMatrixSparseCSC(numRows, numCols);
                break;

            case Types.FSCC:
                //mat = new FMatrixSparseCSC(numRows, numCols);
                break;

            default:
                throw new Exception("Unknown matrix type");
            }
        }
Beispiel #23
0
        /**
         * Converts the permutation vector into a matrix. B = P*A.  B[p[i],:] = A[i,:]
         * @param p (Input) Permutation vector
         * @param inverse (Input) If it is the inverse. B[i,:] = A[p[i],:)
         * @param P (Output) Permutation matrix
         */
        public static DMatrixSparseCSC permutationMatrix(int[] p, bool inverse, int N, DMatrixSparseCSC P)
        {
            if (P == null)
            {
                P = new DMatrixSparseCSC(N, N, N);
            }
            else
            {
                P.reshape(N, N, N);
            }
            P.indicesSorted = true;
            P.nz_length     = N;

            // each column should have one element inside of it
            if (!inverse)
            {
                for (int i = 0; i < N; i++)
                {
                    P.col_idx[i + 1] = i + 1;
                    P.nz_rows[p[i]]  = i;
                    P.nz_values[i]   = 1;
                }
            }
            else
            {
                for (int i = 0; i < N; i++)
                {
                    P.col_idx[i + 1] = i + 1;
                    P.nz_rows[i]     = p[i];
                    P.nz_values[i]   = 1;
                }
            }

            return(P);
        }
Beispiel #24
0
        /**
         * Randomly generates matrix with the specified number of non-zero elements filled with values from min to max.
         *
         * @param numRows Number of rows
         * @param numCols Number of columns
         * @param nz_total Total number of non-zero elements in the matrix
         * @param min Minimum element value, inclusive
         * @param max Maximum element value, inclusive
         * @param rand Random number generator
         * @return Randomly generated matrix
         */
        public static DMatrixSparseCSC rectangle(int numRows, int numCols, int nz_total,
                                                 double min, double max, IMersenneTwister rand)
        {
            nz_total = Math.Min(numCols * numRows, nz_total);
            int[] selected = UtilEjml.shuffled(numRows * numCols, nz_total, rand);
            Array.Sort(selected, 0, nz_total);

            DMatrixSparseCSC ret = new DMatrixSparseCSC(numRows, numCols, nz_total);

            ret.indicesSorted = true;

            // compute the number of elements in each column
            int[] hist = new int[numCols];
            for (int i = 0; i < nz_total; i++)
            {
                hist[selected[i] / numRows]++;
            }

            // define col_idx
            ret.colsum(hist);

            for (int i = 0; i < nz_total; i++)
            {
                int row = selected[i] % numRows;

                ret.nz_rows[i]   = row;
                ret.nz_values[i] = rand.NextDouble() * (max - min) + min;
            }

            return(ret);
        }
Beispiel #25
0
        /**
         * Checks to see if the matrix is symmetric to within tolerance.
         *
         * @param A Matrix being tested.  Not modified.
         * @param tol Tolerance that defines how similar two values must be to be considered identical
         * @return true if symmetric or false if not
         */
        public static bool isSymmetric(DMatrixSparseCSC A, double tol)
        {
            if (A.numRows != A.numCols)
            {
                return(false);
            }

            int N = A.numCols;

            for (int i = 0; i < N; i++)
            {
                int idx0 = A.col_idx[i];
                int idx1 = A.col_idx[i + 1];

                for (int index = idx0; index < idx1; index++)
                {
                    int    j        = A.nz_rows[index];
                    double value_ji = A.nz_values[index];
                    double value_ij = A.get(i, j);

                    if (Math.Abs(value_ij - value_ji) > tol)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Beispiel #26
0
 public static bool checkSortedFlag(DMatrixSparseCSC A)
 {
     if (A.indicesSorted)
     {
         return(checkIndicesSorted(A));
     }
     return(true);
 }
Beispiel #27
0
        public static DMatrixSparseCSC identity(int numRows, int numCols)
        {
            int min            = Math.Min(numRows, numCols);
            DMatrixSparseCSC A = new DMatrixSparseCSC(numRows, numCols, min);

            setToIdentity(A);
            return(A);
        }
Beispiel #28
0
        /**
         * Performs matrix multiplication.  C = A*B
         *
         * @param A Matrix
         * @param B Dense Matrix
         * @param C Dense Matrix
         */
        public static void mult(DMatrixSparseCSC A, DMatrixRMaj B, DMatrixRMaj C)
        {
            if (A.numRows != C.numRows || B.numCols != C.numCols)
            {
                throw new ArgumentException("Inconsistent matrix shapes");
            }

            ImplSparseSparseMult_DSCC.mult(A, B, C);
        }
Beispiel #29
0
        public static DMatrixSparseCSC triangleUpper(int dimen, int hessenberg, int nz_total,
                                                     double min, double max, IMersenneTwister rand)
        {
            DMatrixSparseCSC L = triangleLower(dimen, hessenberg, nz_total, min, max, rand);
            DMatrixSparseCSC U = (DMatrixSparseCSC)L.createLike();

            CommonOps_DSCC.transpose(L, U, null);
            return(U);
        }
Beispiel #30
0
        /**
         * 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);
        }