/** Maximum number of terms of leading coefficient of symbol in both polynomials */
size_t max_lcnops;
- /** Commparison operator for sorting */
+ /** Comparison operator for sorting */
bool operator<(const sym_desc &x) const
{
if (max_deg == x.max_deg)
* @param lcm LCM to multiply in */
static ex multiply_lcm(const ex &e, const numeric &lcm)
{
+ if (lcm.is_equal(*_num1_p))
+ // e * 1 -> e;
+ return e;
+
if (is_exactly_a<mul>(e)) {
+ // (a*b*...)*lcm -> (a*lcma)*(b*lcmb)*...*(lcm/(lcma*lcmb*...))
size_t num = e.nops();
- exvector v; v.reserve(num + 1);
+ exvector v;
+ v.reserve(num + 1);
numeric lcm_accum = *_num1_p;
for (size_t i=0; i<num; i++) {
numeric op_lcm = lcmcoeff(e.op(i), *_num1_p);
v.push_back(lcm / lcm_accum);
return dynallocate<mul>(v);
} else if (is_exactly_a<add>(e)) {
+ // (a+b+...)*lcm -> a*lcm+b*lcm+...
size_t num = e.nops();
- exvector v; v.reserve(num);
+ exvector v;
+ v.reserve(num);
for (size_t i=0; i<num; i++)
v.push_back(multiply_lcm(e.op(i), lcm));
return dynallocate<add>(v);
} else if (is_exactly_a<power>(e)) {
- if (is_a<symbol>(e.op(0)))
- return e * lcm;
- else {
+ if (!is_a<symbol>(e.op(0))) {
+ // (b^e)*lcm -> (b*lcm^(1/e))^e if lcm^(1/e) ∈ ℚ (i.e. not a float)
+ // but not for symbolic b, as evaluation would undo this again
numeric root_of_lcm = lcm.power(ex_to<numeric>(e.op(1)).inverse());
if (root_of_lcm.is_rational())
return pow(multiply_lcm(e.op(0), root_of_lcm), e.op(1));
- else
- return e * lcm;
}
- } else
- return e * lcm;
+ }
+ // can't recurse down into e
+ return dynallocate<mul>(e, lcm);
}
// The symbol with least degree which is contained in both polynomials
// is our main variable
- sym_desc_vec::iterator vari = sym_stats.begin();
+ auto vari = sym_stats.begin();
while ((vari != sym_stats.end()) &&
(((vari->ldeg_b == 0) && (vari->deg_b == 0)) ||
((vari->ldeg_a == 0) && (vari->deg_a == 0))))
return bp->to_rational(repl);
}
-// GiNaC 1.1 compatibility function
-ex ex::to_rational(lst & repl_lst) const
-{
- // Convert lst to exmap
- exmap m;
- for (auto & it : repl_lst)
- m.insert(std::make_pair(it.op(0), it.op(1)));
-
- ex ret = bp->to_rational(m);
-
- // Convert exmap back to lst
- repl_lst.remove_all();
- for (auto & it : m)
- repl_lst.append(it.first == it.second);
-
- return ret;
-}
-
ex ex::to_polynomial(exmap & repl) const
{
return bp->to_polynomial(repl);
}
-// GiNaC 1.1 compatibility function
-ex ex::to_polynomial(lst & repl_lst) const
-{
- // Convert lst to exmap
- exmap m;
- for (auto & it : repl_lst)
- m.insert(std::make_pair(it.op(0), it.op(1)));
-
- ex ret = bp->to_polynomial(m);
-
- // Convert exmap back to lst
- repl_lst.remove_all();
- for (auto & it : m)
- repl_lst.append(it.first == it.second);
-
- return ret;
-}
-
/** Default implementation of ex::to_rational(). This replaces the object with
* a temporary symbol. */
ex basic::to_rational(exmap & repl) const