Exemple #1
0
// Mul (t^exp) to the dict "d"
void Mul::dict_add_term_new(const Ptr<RCP<const Number>> &coef, map_basic_basic &d,
    const RCP<const Basic> &exp, const RCP<const Basic> &t)
{
    auto it = d.find(t);
    if (it == d.end()) {
        // Don't check for `exp = 0` here
        // `pow` for Complex is not expanded by default
        if (is_a<Integer>(*exp) && (is_a<Integer>(*t) || is_a<Rational>(*t))) {
            imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                rcp_static_cast<const Number>(exp)));
        } else if (is_a<Integer>(*exp) && is_a<Complex>(*t)) {
            if (rcp_static_cast<const Integer>(exp)->is_one()) {
                imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else if (rcp_static_cast<const Integer>(exp)->is_minus_one()) {
                idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else {
                insert(d, t, exp);
            }
        } else {
            insert(d, t, exp);
        }
    } else {
        // Very common case, needs to be fast:
        if (is_a_Number(*exp) && is_a_Number(*it->second)) {
            RCP<const Number> tmp = rcp_static_cast<const Number>(it->second);
            iaddnum(outArg(tmp),
                rcp_static_cast<const Number>(exp));
            it->second = tmp;
        }
        else
            it->second = add(it->second, exp);

        if (is_a<Integer>(*it->second)) {
            // `pow` for Complex is not expanded by default
            if (is_a<Integer>(*t) || is_a<Rational>(*t)) {
                if (!rcp_static_cast<const Integer>(it->second)->is_zero()) {
                    imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                        rcp_static_cast<const Number>(it->second)));
                }
                d.erase(it);
            } else if (rcp_static_cast<const Integer>(it->second)->is_zero()) {
                d.erase(it);
            } else if (is_a<Complex>(*t)) {
                if (rcp_static_cast<const Integer>(it->second)->is_one()) {
                    imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                } else if (rcp_static_cast<const Integer>(it->second)->is_minus_one()) {
                    idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                }
            }
        }
    }
}
Exemple #2
0
// Mul (t**exp) to the dict "d"
void Mul::dict_add_term_new(const Ptr<RCP<const Number>> &coef, map_basic_basic &d,
    const RCP<const Basic> &exp, const RCP<const Basic> &t)
{
    auto it = d.find(t);
    if (it == d.end()) {
        // Don't check for `exp = 0` here
        // `pow` for Complex is not expanded by default
        if (is_a<Integer>(*t) || is_a<Rational>(*t)) {
            if (is_a<Integer>(*exp)) {
                imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                    rcp_static_cast<const Number>(exp)));
            } else if (is_a<Rational>(*exp)) {
                // Here we make the exponent postive and a fraction between
                // 0 and 1.
                mpz_class q, r, num, den;
                num = rcp_static_cast<const Rational>(exp)->i.get_num();
                den = rcp_static_cast<const Rational>(exp)->i.get_den();
                mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(),
                    den.get_mpz_t());

                insert(d, t, Rational::from_mpq(mpq_class(r, den)));
                imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                    rcp_static_cast<const Number>(integer(q))));
            } else {
                insert(d, t, exp);
            }
        } else if (is_a<Integer>(*exp) && is_a<Complex>(*t)) {
            if (rcp_static_cast<const Integer>(exp)->is_one()) {
                imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else if (rcp_static_cast<const Integer>(exp)->is_minus_one()) {
                idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
            } else {
                insert(d, t, exp);
            }
        } else {
            insert(d, t, exp);
        }
    } else {
        // Very common case, needs to be fast:
        if (is_a_Number(*exp) && is_a_Number(*it->second)) {
            RCP<const Number> tmp = rcp_static_cast<const Number>(it->second);
            iaddnum(outArg(tmp),
                rcp_static_cast<const Number>(exp));
            it->second = tmp;
        }
        else
            it->second = add(it->second, exp);

        if (is_a<Integer>(*it->second)) {
            // `pow` for Complex is not expanded by default
            if (is_a<Integer>(*t) || is_a<Rational>(*t)) {
                if (!rcp_static_cast<const Integer>(it->second)->is_zero()) {
                    imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                        rcp_static_cast<const Number>(it->second)));
                }
                d.erase(it);
            } else if (rcp_static_cast<const Integer>(it->second)->is_zero()) {
                d.erase(it);
            } else if (is_a<Complex>(*t)) {
                if (rcp_static_cast<const Integer>(it->second)->is_one()) {
                    imulnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                } else if (rcp_static_cast<const Integer>(it->second)->is_minus_one()) {
                    idivnum(outArg(*coef), rcp_static_cast<const Number>(t));
                    d.erase(it);
                }
            }
        } else if (is_a<Rational>(*it->second)) {
            if (is_a_Number(*t)) {
                mpz_class q, r, num, den;
                num = rcp_static_cast<const Rational>(it->second)->i.get_num();
                den = rcp_static_cast<const Rational>(it->second)->i.get_den();
                // Here we make the exponent postive and a fraction between
                // 0 and 1.
                if (num > den || num < 0) {
                    mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(),
                                den.get_mpz_t());

                    it->second = Rational::from_mpq(mpq_class(r, den));
                    imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t),
                                                  rcp_static_cast<const Number>(integer(q))));
                }
            }
        }
    }
}