示例#1
0
文件: mul.cpp 项目: MridulS/csympy
RCP<const Basic> mul_expand(const RCP<const Mul> &self)
{
    RCP<const Basic> a, b;
    self->as_two_terms(outArg(a), outArg(b));
    a = expand(a);
    b = expand(b);
    return mul_expand_two(a, b);
}
示例#2
0
文件: mul.cpp 项目: MridulS/csympy
RCP<const Basic> mul_expand_two(const RCP<const Basic> &a, const RCP<const Basic> &b)
{
    // Both a and b are assumed to be expanded
    if (is_a<Add>(*a) && is_a<Add>(*b)) {
        RCP<const Number> coef = mulnum(rcp_static_cast<const Add>(a)->coef_,
            rcp_static_cast<const Add>(b)->coef_);
        umap_basic_num d;
        // Improves (x+1)^3(x+2)^3...(x+350)^3 expansion from 0.97s to 0.93s:
        d.reserve((rcp_static_cast<const Add>(a))->dict_.size()*
            (rcp_static_cast<const Add>(b))->dict_.size());
        // Expand dicts first:
        for (auto &p: (rcp_static_cast<const Add>(a))->dict_) {
            for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
                // The main bottleneck here is the mul(p.first, q.first) command
                RCP<const Basic> term = mul(p.first, q.first);
                if (is_a_Number(*term)) {
                    iaddnum(outArg(coef), rcp_static_cast<const Number>(term));
                } else {
                    Add::dict_add_term(d, mulnum(p.second, q.second), term);
                }
            }
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(b)->coef_, p.second),
                    p.first);
        }
        // Handle the coefficient of "a":
        for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(a)->coef_, q.second),
                    q.first);
        }
        return Add::from_dict(coef, std::move(d));
    } else if (is_a<Add>(*a)) {
        return mul_expand_two(b, a);
    } else if (is_a<Add>(*b)) {
        RCP<const Number> a_coef;
        RCP<const Basic> a_term;
        Add::as_coef_term(a, outArg(a_coef), outArg(a_term));

        RCP<const Number> coef = zero;
        umap_basic_num d;
        d.reserve((rcp_static_cast<const Add>(b))->dict_.size());
        for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
            RCP<const Basic> term = mul(a_term, q.first);
            if (is_a_Number(*term)) {
                iaddnum(outArg(coef), rcp_static_cast<const Number>(term));
            } else {
                Add::dict_add_term(d, mulnum(a_coef, q.second), term);
            }
        }
        if (eq(a_term, one)) {
            iaddnum(outArg(coef),
                mulnum(rcp_static_cast<const Add>(b)->coef_, a_coef));
        } else {
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(b)->coef_, a_coef),
                    a_term);
        }
        return Add::from_dict(coef, std::move(d));
    }
    return mul(a, b);
}
示例#3
0
文件: mul.cpp 项目: v0dro/symengine
RCP<const Basic> mul_expand_two(const RCP<const Basic> &a, const RCP<const Basic> &b)
{
    // Both a and b are assumed to be expanded
    if (is_a<Add>(*a) && is_a<Add>(*b)) {
        RCP<const Number> coef = mulnum(rcp_static_cast<const Add>(a)->coef_,
            rcp_static_cast<const Add>(b)->coef_);
        umap_basic_num d;
        // Improves (x+1)**3*(x+2)**3*...(x+350)**3 expansion from 0.97s to 0.93s:
        d.reserve((rcp_static_cast<const Add>(a))->dict_.size()*
            (rcp_static_cast<const Add>(b))->dict_.size());
        // Expand dicts first:
        for (auto &p: (rcp_static_cast<const Add>(a))->dict_) {
            for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
                // The main bottleneck here is the mul(p.first, q.first) command
                RCP<const Basic> term = mul(p.first, q.first);
                if (is_a_Number(*term)) {
                    iaddnum(outArg(coef),
                        mulnum(mulnum(p.second, q.second), rcp_static_cast<const Number>(term)));
                } else {
                    if (is_a<Mul>(*term) &&
                        !(rcp_static_cast<const Mul>(term)->coef_->is_one())) {
                        // Tidy up things like {2x: 3} -> {x: 6}
                        RCP<const Number> coef2 =
                                rcp_static_cast<const Mul>(term)->coef_;
                        // We make a copy of the dict_:
                        map_basic_basic d2 = rcp_static_cast<const Mul>(term)->dict_;
                        term = Mul::from_dict(one, std::move(d2));
                        Add::dict_add_term(d, mulnum(mulnum(p.second, q.second), coef2), term);
                    } else {
                        Add::dict_add_term(d, mulnum(p.second, q.second), term);
                    }
                }
            }
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(b)->coef_, p.second),
                    p.first);
        }
        // Handle the coefficient of "a":
        for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(a)->coef_, q.second),
                    q.first);
        }
        return Add::from_dict(coef, std::move(d));
    } else if (is_a<Add>(*a)) {
        return mul_expand_two(b, a);
    } else if (is_a<Add>(*b)) {
        RCP<const Number> a_coef;
        RCP<const Basic> a_term;
        Add::as_coef_term(a, outArg(a_coef), outArg(a_term));

        RCP<const Number> coef = zero;
        umap_basic_num d;
        d.reserve((rcp_static_cast<const Add>(b))->dict_.size());
        for (auto &q: (rcp_static_cast<const Add>(b))->dict_) {
            RCP<const Basic> term = mul(a_term, q.first);
            if (is_a_Number(*term)) {
                iaddnum(outArg(coef), mulnum(mulnum(q.second, a_coef),
                        rcp_static_cast<const Number>(term)));
            } else {
                if (is_a<Mul>(*term) &&
                    !(rcp_static_cast<const Mul>(term)->coef_->is_one())) {
                    // Tidy up things like {2x: 3} -> {x: 6}
                    RCP<const Number> coef2 =
                            rcp_static_cast<const Mul>(term)->coef_;
                    // We make a copy of the dict_:
                    map_basic_basic d2 = rcp_static_cast<const Mul>(term)->dict_;
                    term = Mul::from_dict(one, std::move(d2));
                    Add::dict_add_term(d, mulnum(mulnum(q.second, a_coef), coef2), term);
                } else {
                    Add::dict_add_term(d, mulnum(a_coef, q.second), term);
                }
            }
        }
        if (eq(*a_term, *one)) {
            iaddnum(outArg(coef),
                mulnum(rcp_static_cast<const Add>(b)->coef_, a_coef));
        } else {
            Add::dict_add_term(d,
                    mulnum(rcp_static_cast<const Add>(b)->coef_, a_coef),
                    a_term);
        }
        return Add::from_dict(coef, std::move(d));
    }
    return mul(a, b);
}