* Implementation of GiNaC's non-commutative products of expressions. */
/*
- * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2018 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
// If there are no sums, we are done
if (number_of_adds == 0) {
if (!v.empty())
- return (new ncmul(std::move(v)))->
- setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+ return dynallocate<ncmul>(std::move(v)).setflag(options == 0 ? status_flags::expanded : 0);
else
return *this;
}
term[positions_of_adds[i]] = rename_dummy_indices_uniquely(va, expanded_seq[positions_of_adds[i]].op(k[i]), true);
}
- distrseq.push_back((new ncmul(std::move(term)))->
- setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
+ distrseq.push_back(dynallocate<ncmul>(std::move(term)).setflag(options == 0 ? status_flags::expanded : 0));
// increment k[]
int l = number_of_adds-1;
break;
}
- return (new add(distrseq))->
- setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+ return dynallocate<add>(distrseq).setflag(options == 0 ? status_flags::expanded : 0);
}
int ncmul::degree(const ex & s) const
// if a non-zero power of s is found, the resulting product will be 0
for (auto & it : seq)
coeffseq.push_back(it.coeff(s,n));
- return (new ncmul(std::move(coeffseq)))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(std::move(coeffseq));
}
bool coeff_found = false;
}
if (coeff_found)
- return (new ncmul(std::move(coeffseq)))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(std::move(coeffseq));
return _ex0;
}
* - ncmul(...,c1,...,c2,...) -> *(c1,c2,ncmul(...)) (pull out commutative elements)
* - ncmul(x1,y1,x2,y2) -> *(ncmul(x1,x2),ncmul(y1,y2)) (collect elements of same type)
* - ncmul(x1,x2,x3,...) -> x::eval_ncmul(x1,x2,x3,...)
- *
- * @param level cut-off in recursive evaluation */
-ex ncmul::eval(int level) const
+ */
+ex ncmul::eval() const
{
// The following additional rule would be nice, but produces a recursion,
// which must be trapped by introducing a flag that the sub-ncmuls()
// ncmul(ncmul(x1,x2,...),X,ncmul(y1,y2,...)
// (X noncommutative_composite)
- if ((level==1) && (flags & status_flags::evaluated)) {
+ if (flags & status_flags::evaluated) {
return *this;
}
- exvector evaledseq=evalchildren(level);
-
// ncmul(...,*(x1,x2),...,ncmul(x3,x4),...) ->
// ncmul(...,x1,x2,...,x3,x4,...) (associativity)
size_t factors = 0;
- for (auto & it : evaledseq)
+ for (auto & it : seq)
factors += count_factors(it);
exvector assocseq;
assocseq.reserve(factors);
- make_flat_inserter mf(evaledseq, true);
- for (auto & it : evaledseq) {
+ make_flat_inserter mf(seq, true);
+ for (auto & it : seq) {
ex factor = mf.handle_factor(it, 1);
append_factors(assocseq, factor);
}
else
noncommutativeseq.push_back(assocseq[i]);
}
- commutativeseq.push_back((new ncmul(std::move(noncommutativeseq)))->setflag(status_flags::dynallocated));
- return (new mul(std::move(commutativeseq)))->setflag(status_flags::dynallocated);
+ commutativeseq.push_back(dynallocate<ncmul>(std::move(noncommutativeseq)));
+ return dynallocate<mul>(std::move(commutativeseq));
}
// ncmul(x1,y1,x2,y2) -> *(ncmul(x1,x2),ncmul(y1,y2))
exvector splitseq;
splitseq.reserve(evv_num);
for (i=0; i<evv_num; ++i)
- splitseq.push_back((new ncmul(evv[i]))->setflag(status_flags::dynallocated));
+ splitseq.push_back(dynallocate<ncmul>(evv[i]));
- return (new mul(splitseq))->setflag(status_flags::dynallocated);
+ return dynallocate<mul>(splitseq);
}
- return (new ncmul(assocseq))->setflag(status_flags::dynallocated |
- status_flags::evaluated);
+ return dynallocate<ncmul>(assocseq).setflag(status_flags::evaluated);
}
ex ncmul::evalm() const
}
no_matrix:
- return (new ncmul(std::move(s)))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(std::move(s));
}
ex ncmul::thiscontainer(const exvector & v) const
{
- return (new ncmul(v))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(v);
}
ex ncmul::thiscontainer(exvector && v) const
{
- return (new ncmul(std::move(v)))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(std::move(v));
}
ex ncmul::conjugate() const
--i;
ev.push_back(i->conjugate());
}
- return (new ncmul(std::move(ev)))->setflag(status_flags::dynallocated).eval();
+ return dynallocate<ncmul>(std::move(ev));
}
ex ncmul::real_part() const
for (size_t i=0; i<num; ++i) {
ex e = seq[i].diff(s);
e.swap(ncmulseq[i]);
- addseq.push_back((new ncmul(ncmulseq))->setflag(status_flags::dynallocated));
+ addseq.push_back(dynallocate<ncmul>(ncmulseq));
e.swap(ncmulseq[i]);
}
- return (new add(addseq))->setflag(status_flags::dynallocated);
+ return dynallocate<add>(addseq);
}
int ncmul::compare_same_type(const basic & other) const
bool all_commutative = true;
exvector::const_iterator noncommutative_element; // point to first found nc element
- exvector::const_iterator i = seq.begin(), end = seq.end();
+ auto i = seq.begin(), end = seq.end();
while (i != end) {
unsigned rt = i->return_type();
if (rt == return_types::noncommutative_composite)
ex reeval_ncmul(const exvector & v)
{
- return (new ncmul(v))->setflag(status_flags::dynallocated);
+ return dynallocate<ncmul>(v);
}
ex hold_ncmul(const exvector & v)
else if (v.size() == 1)
return v[0];
else
- return (new ncmul(v))->setflag(status_flags::dynallocated |
- status_flags::evaluated);
+ return dynallocate<ncmul>(v).setflag(status_flags::evaluated);
}
GINAC_BIND_UNARCHIVER(ncmul);