if (level > 1)
return indexed(symmetry, evalchildren(level));
+ const ex &base = seq[0];
+
// If the base object is 0, the whole object is 0
- if (seq[0].is_zero())
+ if (base.is_zero())
return _ex0();
+ // If the base object is a product, pull out the numeric factor
+ if (is_ex_exactly_of_type(base, mul) && is_ex_exactly_of_type(base.op(base.nops() - 1), numeric)) {
+ exvector v = seq;
+ ex f = ex_to_numeric(base.op(base.nops() - 1));
+ v[0] = seq[0] / f;
+ return f * thisexprseq(v);
+ }
+
// Canonicalize indices according to the symmetry properties
if (seq.size() > 2 && (symmetry != unknown && symmetry != mixed)) {
exvector v = seq;
}
// Let the class of the base object perform additional evaluations
- return seq[0].bp->eval_indexed(*this);
+ return base.bp->eval_indexed(*this);
}
ex indexed::thisexprseq(const exvector & v) const
// Simplification of sum = sum of simplifications, check consistency of
// free indices in each term
if (is_ex_exactly_of_type(e_expanded, add)) {
- ex sum = _ex0();
+ ex sum = simplify_indexed(e_expanded.op(0), free_indices, sp);
- for (unsigned i=0; i<e_expanded.nops(); i++) {
+ for (unsigned i=1; i<e_expanded.nops(); i++) {
exvector free_indices_of_term;
- sum += simplify_indexed(e_expanded.op(i), free_indices_of_term, sp);
- if (i == 0)
- free_indices = free_indices_of_term;
- else if (!indices_consistent(free_indices, free_indices_of_term))
+ ex term = simplify_indexed(e_expanded.op(i), free_indices_of_term, sp);
+ if (!indices_consistent(free_indices, free_indices_of_term))
throw (std::runtime_error("simplify_indexed: inconsistent indices in sum"));
+ if (is_ex_of_type(sum, indexed) && is_ex_of_type(term, indexed))
+ sum = sum.op(0).bp->add_indexed(sum, term);
+ else
+ sum += term;
}
return sum;