Beispiel #1
0
// Scale the rows of a CSR matrix *in place*
// A[i, :] *= X[i]
void csr_scale_rows(CSRMatrix &A, const DenseMatrix &X)
{
    SYMENGINE_ASSERT(A.row_ == X.nrows() and X.ncols() == 1);

    for (unsigned i = 0; i < A.row_; i++) {
        if (eq(*(X.get(i, 0)), *zero))
            throw SymEngineException("Scaling factor can't be zero");
        for (unsigned jj = A.p_[i]; jj < A.p_[i + 1]; jj++)
            A.x_[jj] = mul(A.x_[jj], X.get(i, 0));
    }
}
Beispiel #2
0
RCP<const Basic> det_berkowitz(const DenseMatrix &A)
{
    std::vector<DenseMatrix> polys;

    berkowitz(A, polys);
    DenseMatrix poly = polys[polys.size() - 1];

    if (polys.size() % 2 == 1)
        return mul(minus_one, poly.get(poly.nrows() - 1, 0));

    return poly.get(poly.nrows() - 1, 0);
}
Beispiel #3
0
// Scale the columns of a CSR matrix *in place*
// A[:, i] *= X[i]
void csr_scale_columns(CSRMatrix &A, const DenseMatrix &X)
{
    SYMENGINE_ASSERT(A.col_ == X.nrows() and X.ncols() == 1);

    const unsigned nnz = A.p_[A.row_];
    unsigned i;

    for (i = 0; i < A.col_; i++) {
        if (eq(*(X.get(i, 0)), *zero))
            throw SymEngineException("Scaling factor can't be zero");
    }

    for (i = 0; i < nnz; i++)
        A.x_[i] = mul(A.x_[i], X.get(A.j_[i], 0));
}
Beispiel #4
0
bool order(const DenseMatrix &t, const std::vector<DenseMatrix> &basis,
           unsigned k)
{
    bool eq = true;

    for (unsigned j = 0; j < t.ncols(); j++) {
        SYMENGINE_ASSERT(is_a<Integer>(*t.get(0, j)));
        integer_class t_
            = rcp_static_cast<const Integer>(t.get(0, j))->as_integer_class();

        SYMENGINE_ASSERT(is_a<Integer>(*basis[k].get(0, j)));
        integer_class b_ = rcp_static_cast<const Integer>(basis[k].get(0, j))
                               ->as_integer_class();

        if (t_ < b_) {
            return false;
        }
        if (t_ > b_) {
            eq = false;
        }
    }

    return not eq;
}
Beispiel #5
0
// Solve the diophantine system Ax = 0 and return a basis set for solutions
// Reference:
// Evelyne Contejean, Herve Devie. An Efficient Incremental Algorithm for
// Solving
// Systems of Linear Diophantine Equations. Information and computation,
// 113(1):143-172,
// August 1994.
void homogeneous_lde(std::vector<DenseMatrix> &basis, const DenseMatrix &A)
{
    unsigned p = A.nrows();
    unsigned q = A.ncols();
    unsigned n;

    SYMENGINE_ASSERT(p > 0 and q > 1);

    DenseMatrix row_zero(1, q);
    zeros(row_zero);

    DenseMatrix col_zero(p, 1);
    zeros(col_zero);

    std::vector<DenseMatrix> P;
    P.push_back(row_zero);

    std::vector<std::vector<bool>> Frozen(q, std::vector<bool>(q, true));
    for (unsigned j = 0; j < q; j++) {
        Frozen[0][j] = false;
    }

    std::vector<bool> F(q, false);

    DenseMatrix t, transpose, product, T;
    RCP<const Integer> dot;

    product = DenseMatrix(p, 1);
    transpose = DenseMatrix(q, 1);

    while (P.size() > 0) {
        n = P.size() - 1;
        t = P[n];
        P.pop_back();

        t.transpose(transpose);
        A.mul_matrix(transpose, product);

        if (product.eq(col_zero) and not t.eq(row_zero)) {
            basis.push_back(t);
        } else {
            for (unsigned i = 0; i < q; i++) {
                F[i] = Frozen[n][i];
            }

            T = t;
            for (unsigned i = 0; i < q; i++) {
                SYMENGINE_ASSERT(is_a<Integer>(*T.get(0, i)));
                T.set(0, i, rcp_static_cast<const Integer>(T.get(0, i))
                                ->addint(*one));

                if (i > 0) {
                    SYMENGINE_ASSERT(is_a<Integer>(*T.get(0, i - 1)));
                    T.set(0, i - 1,
                          rcp_static_cast<const Integer>(T.get(0, i - 1))
                              ->subint(*one));
                }

                dot = zero;
                for (unsigned j = 0; j < p; j++) {
                    SYMENGINE_ASSERT(is_a<Integer>(*product.get(j, 0)));
                    RCP<const Integer> p_j0
                        = rcp_static_cast<const Integer>(product.get(j, 0));

                    SYMENGINE_ASSERT(is_a<Integer>(*A.get(j, i)));
                    RCP<const Integer> A_ji
                        = rcp_static_cast<const Integer>(A.get(j, i));

                    dot = dot->addint(*p_j0->mulint(*A_ji));
                }

                if (F[i] == false and ((dot->is_negative()
                                        and is_minimum(T, basis, basis.size()))
                                       or t.eq(row_zero))) {
                    P.push_back(T);
                    n = n + 1;

                    for (unsigned j = 0; j < q; j++) {
                        Frozen[n - 1][j] = F[j];
                    }

                    F[i] = true;
                }
            }
        }
    }
}