}
// Partially factored cases (to avoid expanding large expressions)
- if (is_exactly_a<mul>(a) || is_exactly_a<mul>(b))
- return gcd_pf_mul(a, b, ca, cb, check_args);
+ if (!(options & gcd_options::no_part_factored)) {
+ if (is_exactly_a<mul>(a) || is_exactly_a<mul>(b))
+ return gcd_pf_mul(a, b, ca, cb, check_args);
#if FAST_COMPARE
- if (is_exactly_a<power>(a) || is_exactly_a<power>(b))
- return gcd_pf_pow(a, b, ca, cb, check_args);
+ if (is_exactly_a<power>(a) || is_exactly_a<power>(b))
+ return gcd_pf_pow(a, b, ca, cb, check_args);
#endif
+ }
// Some trivial cases
ex aex = a.expand(), bex = b.expand();
// Try heuristic algorithm first, fall back to PRS if that failed
ex g;
- bool found = heur_gcd(g, aex, bex, ca, cb, var);
- if (found) {
- // heur_gcd have already computed cofactors...
- if (g.is_equal(_ex1)) {
- // ... but we want to keep them factored if possible.
- if (ca)
- *ca = a;
- if (cb)
- *cb = b;
+ if (!(options & gcd_options::no_heur_gcd)) {
+ bool found = heur_gcd(g, aex, bex, ca, cb, var);
+ if (found) {
+ // heur_gcd have already computed cofactors...
+ if (g.is_equal(_ex1)) {
+ // ... but we want to keep them factored if possible.
+ if (ca)
+ *ca = a;
+ if (cb)
+ *cb = b;
+ }
+ return g;
}
- return g;
- }
#if STATISTICS
- else {
- heur_gcd_failed++;
- }
+ else {
+ heur_gcd_failed++;
+ }
#endif
+ }
g = sr_gcd(aex, bex, var);
if (g.is_equal(_ex1)) {
static ex gcd_pf_mul(const ex& a, const ex& b, ex* ca, ex* cb, bool check_args)
{
- if (is_exactly_a<mul>(a)) {
- if (is_exactly_a<mul>(b) && b.nops() > a.nops())
- goto factored_b;
-factored_a:
- size_t num = a.nops();
- exvector g; g.reserve(num);
- exvector acc_ca; acc_ca.reserve(num);
- ex part_b = b;
- for (size_t i=0; i<num; i++) {
- ex part_ca, part_cb;
- g.push_back(gcd(a.op(i), part_b, &part_ca, &part_cb, check_args));
- acc_ca.push_back(part_ca);
- part_b = part_cb;
- }
- if (ca)
- *ca = (new mul(acc_ca))->setflag(status_flags::dynallocated);
- if (cb)
- *cb = part_b;
- return (new mul(g))->setflag(status_flags::dynallocated);
- } else if (is_exactly_a<mul>(b)) {
- if (is_exactly_a<mul>(a) && a.nops() > b.nops())
- goto factored_a;
-factored_b:
- size_t num = b.nops();
- exvector g; g.reserve(num);
- exvector acc_cb; acc_cb.reserve(num);
- ex part_a = a;
- for (size_t i=0; i<num; i++) {
- ex part_ca, part_cb;
- g.push_back(gcd(part_a, b.op(i), &part_ca, &part_cb, check_args));
- acc_cb.push_back(part_cb);
- part_a = part_ca;
- }
- if (ca)
- *ca = part_a;
- if (cb)
- *cb = (new mul(acc_cb))->setflag(status_flags::dynallocated);
- return (new mul(g))->setflag(status_flags::dynallocated);
- }
+ if (is_exactly_a<mul>(a) && is_exactly_a<mul>(b)
+ && (b.nops() > a.nops()))
+ return gcd_pf_mul(b, a, cb, ca, check_args);
+
+ if (is_exactly_a<mul>(b) && (!is_exactly_a<mul>(a)))
+ return gcd_pf_mul(b, a, cb, ca, check_args);
+
+ GINAC_ASSERT(is_exactly_a<mul>(a));
+ size_t num = a.nops();
+ exvector g; g.reserve(num);
+ exvector acc_ca; acc_ca.reserve(num);
+ ex part_b = b;
+ for (size_t i=0; i<num; i++) {
+ ex part_ca, part_cb;
+ g.push_back(gcd(a.op(i), part_b, &part_ca, &part_cb, check_args));
+ acc_ca.push_back(part_ca);
+ part_b = part_cb;
+ }
+ if (ca)
+ *ca = (new mul(acc_ca))->setflag(status_flags::dynallocated);
+ if (cb)
+ *cb = part_b;
+ return (new mul(g))->setflag(status_flags::dynallocated);
}
/** Compute LCM (Least Common Multiple) of multivariate polynomials in Z[X].