Exemple #1
0
std::vector<std::pair<GaloisFieldDict, integer_class>>
GaloisFieldDict::gf_ddf_zassenhaus() const
{
    unsigned i = 1;
    GaloisFieldDict f(*this);
    GaloisFieldDict g = GaloisFieldDict::from_vec({0_z, 1_z}, modulo_);
    GaloisFieldDict to_sub(g);
    std::vector<std::pair<GaloisFieldDict, integer_class>> factors;

    auto b = f.gf_frobenius_monomial_base();
    while (2 * i <= f.degree()) {
        g = g.gf_frobenius_map(f, b);

        GaloisFieldDict h = f.gf_gcd(g - to_sub);

        if (not h.is_one()) {
            factors.push_back({h, integer_class(i)});
            f /= h;
            g %= f;
            b = f.gf_frobenius_monomial_base();
        }
        i += 1;
    }
    if (not(f.is_one() || f.empty())) {
        factors.push_back({f, integer_class(f.degree())});
    }
    return factors;
}
Exemple #2
0
std::vector<std::pair<GaloisFieldDict, integer_class>>
GaloisFieldDict::gf_sqf_list() const
{
    std::vector<std::pair<GaloisFieldDict, integer_class>> vec_out;
    if (degree() < 1)
        return vec_out;
    integer_class n = integer_class(1);
    unsigned r = mp_get_si(modulo_);
    bool sqf = false;
    integer_class LC;
    GaloisFieldDict f;
    gf_monic(LC, outArg(f));
    while (true) {
        GaloisFieldDict F = f.gf_diff();
        if (not F.dict_.empty()) {
            GaloisFieldDict g = f.gf_gcd(F);
            GaloisFieldDict h = f / g;

            integer_class i = integer_class(1);

            while (not h.is_one()) {
                GaloisFieldDict G = h.gf_gcd(g);
                GaloisFieldDict H = h / G;

                if (H.degree() > 0)
                    vec_out.push_back({H, i * n});

                i += integer_class(1);
                g /= G;
                h = G;
            }
            if (g.is_one())
                sqf = true;
            else
                f = g;
        }
        if (not sqf) {
            unsigned int deg = f.degree();
            unsigned int d = deg / r;
            GaloisFieldDict temp = f;
            for (unsigned int i = 0; i <= d; i++) {
                f.dict_[d - i] = temp.dict_[deg - i * r];
            }
            n *= r;
            f.dict_.resize(d + 1);
            f.gf_istrip();
        } else
            break;
    }
    return vec_out;
}
Exemple #3
0
GaloisFieldDict GaloisFieldDict::gf_diff() const
{
    auto df = degree();
    GaloisFieldDict out = GaloisFieldDict({}, modulo_);
    out.dict_.resize(df, integer_class(0));
    for (unsigned i = 1; i <= df; i++) {
        if (dict_[i] != integer_class(0)) {
            out.dict_[i - 1] = i * dict_[i];
            mp_fdiv_r(out.dict_[i - 1], out.dict_[i - 1], modulo_);
        }
    }
    out.gf_istrip();
    return out;
}
Exemple #4
0
vec_basic GaloisField::get_args() const
{
    vec_basic args;
    if (poly_.dict_.empty())
        args.push_back(zero);
    else {
        for (unsigned i = 0; i < poly_.dict_.size(); i++) {
            if (poly_.dict_[i] == integer_class(0))
                continue;
            if (i == 0) {
                args.push_back(integer(poly_.dict_[i]));
            } else if (i == 1) {
                if (poly_.dict_[i] == 1) {
                    args.push_back(var_);
                } else {
                    args.push_back(
                        Mul::from_dict(integer(poly_.dict_[i]), {{var_, one}}));
                }
            } else {
                if (poly_.dict_[i] == 1) {
                    args.push_back(pow(var_, integer(i)));
                } else {
                    args.push_back(Mul::from_dict(integer(poly_.dict_[i]),
                                                  {{var_, integer(i)}}));
                }
            }
        }
    }
    return args;
}
RCP<const UIntPolyFlint> UIntPolyFlint::from_vec(const RCP<const Symbol> &var,
                                                 const vec_integer_class &v)
{
    // benchmark this against vec->str->fmpz_polyxx
    unsigned int deg = v.size() - 1;
    while (v[deg] == integer_class(0))
        deg--;

    fp_t f(deg + 1);
    for (unsigned int i = 0; i <= deg; i++) {
        if (v[i] != integer_class(0)) {
            fz_t r(get_mpz_t(v[i]));
            f.set_coeff(i, r);
        }
    }
    return make_rcp<const UIntPolyFlint>(var, std::move(f));
}
Exemple #6
0
void GaloisFieldDict::gf_monic(integer_class &res,
                               const Ptr<GaloisFieldDict> &monic) const
{
    *monic = static_cast<GaloisFieldDict>(*this);
    if (dict_.empty()) {
        res = integer_class(0);
    } else {
        res = *dict_.rbegin();
        if (res != integer_class(1)) {
            integer_class inv, temp;
            mp_invert(inv, res, modulo_);
            for (auto &iter : monic->dict_) {
                temp = inv;
                temp *= iter;
                mp_fdiv_r(iter, temp, modulo_);
            }
        }
    }
}
Exemple #7
0
GaloisFieldDict GaloisFieldDict::gf_lshift(const integer_class n) const
{
    std::vector<integer_class> dict_out;
    auto to_ret = GaloisFieldDict::from_vec(dict_out, modulo_);
    if (!dict_.empty()) {
        unsigned n_val = mp_get_si(n);
        to_ret.dict_.resize(n_val, integer_class(0));
        to_ret.dict_.insert(to_ret.dict_.end(), dict_.begin(), dict_.end());
    }
    return to_ret;
}
Exemple #8
0
GaloisFieldDict GaloisFieldDict::gf_pow(const integer_class n) const
{
    if (n == 0) {
        return GaloisFieldDict({integer_class(1)}, modulo_);
    }
    if (n == 1)
        return static_cast<GaloisFieldDict>(*this);
    if (n == 2)
        return gf_sqr();
    long num = mp_get_si(n);
    GaloisFieldDict to_sq = static_cast<GaloisFieldDict>(*this);
    GaloisFieldDict to_ret = GaloisFieldDict({integer_class(1)}, modulo_);
    while (1) {
        if (num & 1) {
            to_ret *= to_sq;
        }
        num >>= 1;
        if (num == 0)
            return to_ret;
        to_sq = to_sq.gf_sqr();
    }
}
Exemple #9
0
RCP<const Number> Integer::pow_negint(const Integer &other) const
{
    RCP<const Number> tmp = powint(*other.neg());
    if (is_a<Integer>(*tmp)) {
        const integer_class &j = down_cast<const Integer &>(*tmp).i;
#if SYMENGINE_INTEGER_CLASS == SYMENGINE_BOOSTMP
        // boost::multiprecision::cpp_rational lacks an (int, cpp_int)
        // constructor. must use cpp_rational(cpp_int,cpp_int)
        rational_class q(integer_class(mp_sign(j)), mp_abs(j));
#else
        rational_class q(mp_sign(j), mp_abs(j));
#endif
        return Rational::from_mpq(std::move(q));
    } else {
        throw SymEngineException("powint returned non-integer");
    }
}
Exemple #10
0
RCP<const UnivariateIntPolynomial>
UnivariateIntPolynomial::from_dict(const RCP<const Symbol> &var,
                                   map_uint_mpz &&d)
{
    auto itter = d.begin();
    while (itter != d.end()) {
        if (integer_class(0) == itter->second) {
            auto toErase = itter;
            itter++;
            d.erase(toErase);
        } else {
            itter++;
        }
    }
    unsigned int degree = 0;
    if (!d.empty())
        degree = (--(d.end()))->first;
    return make_rcp<const UnivariateIntPolynomial>(var, degree, std::move(d));
}