Esempio n. 1
0
// References : Cohen H., A course in computational algebraic number theory
// (1996), page 25.
bool multiplicative_order(const Ptr<RCP<const Integer>> &o,
                          const RCP<const Integer> &a,
                          const RCP<const Integer> &n)
{
    integer_class order, p, t;
    integer_class _a = a->as_integer_class(),
                  _n = mp_abs(n->as_integer_class());
    mp_gcd(t, _a, _n);
    if (t != 1)
        return false;

    RCP<const Integer> lambda = carmichael(n);
    map_integer_uint prime_mul;
    prime_factor_multiplicities(prime_mul, *lambda);
    _a %= _n;
    order = lambda->as_integer_class();

    for (const auto it : prime_mul) {
        p = it.first->as_integer_class();
        mp_pow_ui(t, p, it.second);
        mp_divexact(order, order, t);
        mp_powm(t, _a, order, _n);
        while (t != 1) {
            mp_powm(t, t, p, _n);
            order *= p;
        }
    }
    *o = integer(std::move(order));
    return true;
}
Esempio n. 2
0
RCP<const Integer> carmichael(const RCP<const Integer> &n)
{
    if (n->is_zero())
        return integer(1);

    map_integer_uint prime_mul;
    integer_class lambda, t, p;
    unsigned multiplicity;

    prime_factor_multiplicities(prime_mul, *n);
    lambda = 1;
    for (const auto it : prime_mul) {
        p = it.first->as_integer_class();
        multiplicity = it.second;
        if (p == 2
            and multiplicity
                    > 2) { // For powers of 2 greater than 4 divide by 2.
            multiplicity--;
        }
        t = p - 1;
        mp_lcm(lambda, lambda, t);
        mp_pow_ui(t, p, multiplicity - 1);
        // lambda and p are relatively prime.
        lambda = lambda * t;
    }
    return integer(std::move(lambda));
}
Esempio n. 3
0
integer_class UnivariateIntPolynomial::eval(const integer_class &x) const
{
    unsigned int last_deg = dict_.rbegin()->first;
    integer_class result(0), x_pow;

    for (auto it = dict_.rbegin(); it != dict_.rend(); ++it) {

        mp_pow_ui(x_pow, x, last_deg - (*it).first);
        last_deg = (*it).first;
        result = (*it).second + x_pow * result;
    }
    mp_pow_ui(x_pow, x, last_deg);
    result *= x_pow;

    return result;
}
Esempio n. 4
0
RCP<const Number> harmonic(unsigned long n, long m)
{
    rational_class res(0);
    if (m == 1) {
        for (unsigned i = 1; i <= n; ++i) {
            res += rational_class(1, i);
        }
        return Rational::from_mpq(res);
    } else {
        for (unsigned i = 1; i <= n; ++i) {
            if (m > 0) {
                rational_class t(1u, i);
                mp_pow_ui(get_den(t), get_den(t), m);
                res += t;
            } else {
                integer_class t(i);
                mp_pow_ui(t, t, -m);
                res += t;
            }
        }
        return Rational::from_mpq(res);
    }
}
Esempio n. 5
0
integer_class MIntPoly::eval(
    std::map<RCP<const Basic>, integer_class, RCPBasicKeyLess> &vals) const
{
    // TODO : handle missing values
    integer_class ans(0), temp, term;
    for (auto bucket : poly_.dict_) {
        term = bucket.second;
        unsigned int whichvar = 0;
        for (auto sym : vars_) {
            mp_pow_ui(temp, vals.find(sym)->second, bucket.first[whichvar]);
            term *= temp;
            whichvar++;
        }
        ans += term;
    }
    return ans;
}