* Implementation of GiNaC's sums of expressions. */
/*
- * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2019 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
GINAC_ASSERT(is_canonical());
}
+add::add(epvector && vp)
+{
+ overall_coeff = _ex0;
+ construct_from_epvector(std::move(vp));
+ GINAC_ASSERT(is_canonical());
+}
+
add::add(epvector && vp, const ex & oc)
{
overall_coeff = oc;
return true;
return overall_coeff.info(inf);
}
- case info_flags::algebraic: {
- epvector::const_iterator i = seq.begin(), end = seq.end();
- while (i != end) {
- if ((recombine_pair_to_ex(*i).info(inf)))
- return true;
- ++i;
- }
- return false;
- }
}
return inherited::info(inf);
}
if (!restcoeff.is_zero()) {
if (do_clifford) {
if (clifford_max_label(restcoeff) == -1) {
- coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff));
+ coeffseq_cliff.push_back(expair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff));
} else {
- coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff));
+ coeffseq_cliff.push_back(expair(restcoeff, i.coeff));
nonscalar = true;
}
}
- coeffseq.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff));
+ coeffseq.push_back(expair(restcoeff, i.coeff));
}
}
* an expression that contain a plain number.
* - +(;c) -> c
* - +(x;0) -> x
- *
- * @param level cut-off in recursive evaluation */
-ex add::eval(int level) const
+ */
+ex add::eval() const
{
- epvector evaled = evalchildren(level);
+ if (flags & status_flags::evaluated) {
+ GINAC_ASSERT(seq.size()>0);
+ GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero());
+ return *this;
+ }
+
+ const epvector evaled = evalchildren();
if (unlikely(!evaled.empty())) {
- // do more evaluation later
+ // start over evaluating a new object
return dynallocate<add>(std::move(evaled), overall_coeff);
}
GINAC_ASSERT(!is_exactly_a<add>(i.rest));
}
#endif // def DO_GINAC_ASSERT
-
- if (flags & status_flags::evaluated) {
- GINAC_ASSERT(seq.size()>0);
- GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero());
- return *this;
- }
-
- int seq_size = seq.size();
+
+ size_t seq_size = seq.size();
if (seq_size == 0) {
// +(;c) -> c
return overall_coeff;
} else if (!overall_coeff.is_zero() && seq[0].rest.return_type() != return_types::commutative) {
throw (std::logic_error("add::eval(): sum of non-commutative objects has non-zero numeric term"));
}
-
- // if any terms in the sum still are purely numeric, then they are more
- // appropriately collected into the overall coefficient
- int terms_to_collect = 0;
- for (auto & it : seq) {
- if (unlikely(is_a<numeric>(it.rest)))
- ++terms_to_collect;
- }
- if (terms_to_collect) {
- epvector s;
- s.reserve(seq_size - terms_to_collect);
- numeric oc = *_num1_p;
- for (auto & it : seq) {
- if (unlikely(is_a<numeric>(it.rest)))
- oc = oc.mul(ex_to<numeric>(it.rest)).mul(ex_to<numeric>(it.coeff));
- else
- s.push_back(it);
- }
- return dynallocate<add>(std::move(s), ex_to<numeric>(overall_coeff).add_dyn(oc));
- }
-
+
return this->hold();
}
// than the default implementation in basic::derivative() although
// if performs the same function (differentiate each term).
for (auto & it : seq)
- s.push_back(combine_ex_with_coeff_to_pair(it.rest.diff(y), it.coeff));
+ s.push_back(expair(it.rest.diff(y), it.coeff));
- return dynallocate<add>(std::move(s), _ex0);
+ return dynallocate<add>(std::move(s));
}
int add::compare_same_type(const basic & other) const
if (is_exactly_a<mul>(e)) {
const mul &mulref(ex_to<mul>(e));
const ex &numfactor = mulref.overall_coeff;
- if (numfactor.is_equal(_ex1))
+ if (likely(numfactor.is_equal(_ex1)))
return expair(e, c);
mul & mulcopy = dynallocate<mul>(mulref);
mulcopy.overall_coeff = _ex1;