X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fncmul.cpp;h=103e7d6d7f2a13734aebc38e7156a973f2ec1c0b;hp=da416099266c11cbcd706a6852f1f50b8d7de9bd;hb=0c7b386201bff979f58b6e79d4b1e407334659cc;hpb=695f6ae955ec530cded8f21efd5569df39447f76 diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index da416099..103e7d6d 100644 --- a/ginac/ncmul.cpp +++ b/ginac/ncmul.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's non-commutative products of expressions. */ /* - * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2016 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 @@ -17,21 +17,23 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include - #include "ncmul.h" #include "ex.h" #include "add.h" #include "mul.h" +#include "clifford.h" #include "matrix.h" #include "archive.h" +#include "indexed.h" #include "utils.h" +#include +#include +#include + namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq, @@ -47,7 +49,6 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq, ncmul::ncmul() { - tinfo_key = TINFO_ncmul; } ////////// @@ -56,50 +57,42 @@ ncmul::ncmul() // public -ncmul::ncmul(const ex & lh, const ex & rh) : inherited(lh,rh) +ncmul::ncmul(const ex & lh, const ex & rh) : inherited{lh,rh} { - tinfo_key = TINFO_ncmul; } -ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3) : inherited(f1,f2,f3) +ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3) : inherited{f1,f2,f3} { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3, - const ex & f4) : inherited(f1,f2,f3,f4) + const ex & f4) : inherited{f1,f2,f3,f4} { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3, - const ex & f4, const ex & f5) : inherited(f1,f2,f3,f4,f5) + const ex & f4, const ex & f5) : inherited{f1,f2,f3,f4,f5} { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3, - const ex & f4, const ex & f5, const ex & f6) : inherited(f1,f2,f3,f4,f5,f6) + const ex & f4, const ex & f5, const ex & f6) : inherited{f1,f2,f3,f4,f5,f6} { - tinfo_key = TINFO_ncmul; } -ncmul::ncmul(const exvector & v, bool discardable) : inherited(v,discardable) +ncmul::ncmul(const exvector & v) : inherited(v) { - tinfo_key = TINFO_ncmul; } -ncmul::ncmul(std::auto_ptr vp) : inherited(vp) +ncmul::ncmul(exvector && v) : inherited(std::move(v)) { - tinfo_key = TINFO_ncmul; } ////////// // archiving ////////// -DEFAULT_ARCHIVING(ncmul) - + ////////// // functions overriding virtual functions from base classes ////////// @@ -122,28 +115,27 @@ bool ncmul::info(unsigned inf) const return inherited::info(inf); } -typedef std::vector intvector; +typedef std::vector uintvector; ex ncmul::expand(unsigned options) const { // First, expand the children - std::auto_ptr vp = expandchildren(options); - const exvector &expanded_seq = vp.get() ? *vp : this->seq; + exvector v = expandchildren(options); + const exvector &expanded_seq = v.empty() ? this->seq : v; // Now, look for all the factors that are sums and remember their // position and number of terms. - intvector positions_of_adds(expanded_seq.size()); - intvector number_of_add_operands(expanded_seq.size()); + uintvector positions_of_adds(expanded_seq.size()); + uintvector number_of_add_operands(expanded_seq.size()); size_t number_of_adds = 0; size_t number_of_expanded_terms = 1; size_t current_position = 0; - exvector::const_iterator last = expanded_seq.end(); - for (exvector::const_iterator cit=expanded_seq.begin(); cit!=last; ++cit) { - if (is_exactly_a(*cit)) { + for (auto & it : expanded_seq) { + if (is_exactly_a(it)) { positions_of_adds[number_of_adds] = current_position; - size_t num_ops = cit->nops(); + size_t num_ops = it.nops(); number_of_add_operands[number_of_adds] = num_ops; number_of_expanded_terms *= num_ops; number_of_adds++; @@ -153,9 +145,8 @@ ex ncmul::expand(unsigned options) const // If there are no sums, we are done if (number_of_adds == 0) { - if (vp.get()) - return (new ncmul(vp))-> - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + if (!v.empty()) + return dynallocate(std::move(v)).setflag(options == 0 ? status_flags::expanded : 0); else return *this; } @@ -165,14 +156,29 @@ ex ncmul::expand(unsigned options) const exvector distrseq; distrseq.reserve(number_of_expanded_terms); - intvector k(number_of_adds); + uintvector k(number_of_adds); + + /* Rename indices in the static members of the product */ + exvector expanded_seq_mod; + size_t j = 0; + exvector va; + + for (size_t i=0; i - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); + exvector term = expanded_seq_mod; + for (size_t i=0; i(std::move(term)).setflag(options == 0 ? status_flags::expanded : 0)); // increment k[] int l = number_of_adds-1; @@ -184,8 +190,7 @@ ex ncmul::expand(unsigned options) const break; } - return (new add(distrseq))-> - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + return dynallocate(distrseq).setflag(options == 0 ? status_flags::expanded : 0); } int ncmul::degree(const ex & s) const @@ -195,11 +200,8 @@ int ncmul::degree(const ex & s) const // Sum up degrees of factors int deg_sum = 0; - exvector::const_iterator i = seq.begin(), end = seq.end(); - while (i != end) { - deg_sum += i->degree(s); - ++i; - } + for (auto & i : seq) + deg_sum += i.degree(s); return deg_sum; } @@ -210,11 +212,8 @@ int ncmul::ldegree(const ex & s) const // Sum up degrees of factors int deg_sum = 0; - exvector::const_iterator i = seq.begin(), end = seq.end(); - while (i != end) { - deg_sum += i->degree(s); - ++i; - } + for (auto & i : seq) + deg_sum += i.degree(s); return deg_sum; } @@ -229,28 +228,24 @@ ex ncmul::coeff(const ex & s, int n) const if (n == 0) { // product of individual coeffs // if a non-zero power of s is found, the resulting product will be 0 - exvector::const_iterator it=seq.begin(); - while (it!=seq.end()) { - coeffseq.push_back((*it).coeff(s,n)); - ++it; - } - return (new ncmul(coeffseq,1))->setflag(status_flags::dynallocated); + for (auto & it : seq) + coeffseq.push_back(it.coeff(s,n)); + return dynallocate(std::move(coeffseq)); } - exvector::const_iterator i = seq.begin(), end = seq.end(); bool coeff_found = false; - while (i != end) { - ex c = i->coeff(s,n); + for (auto & i : seq) { + ex c = i.coeff(s,n); if (c.is_zero()) { - coeffseq.push_back(*i); + coeffseq.push_back(i); } else { coeffseq.push_back(c); coeff_found = true; } - ++i; } - if (coeff_found) return (new ncmul(coeffseq,1))->setflag(status_flags::dynallocated); + if (coeff_found) + return dynallocate(std::move(coeffseq)); return _ex0; } @@ -290,9 +285,8 @@ typedef std::vector exvectorvector; * - 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() @@ -301,24 +295,23 @@ ex ncmul::eval(int level) const // 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; - exvector::const_iterator cit = evaledseq.begin(), citend = evaledseq.end(); - while (cit != citend) - factors += count_factors(*cit++); + for (auto & it : seq) + factors += count_factors(it); exvector assocseq; assocseq.reserve(factors); - cit = evaledseq.begin(); - while (cit != citend) - append_factors(assocseq, *cit++); + make_flat_inserter mf(seq, true); + for (auto & it : seq) { + ex factor = mf.handle_factor(it, 1); + append_factors(assocseq, factor); + } // ncmul(x) -> x if (assocseq.size()==1) return *(seq.begin()); @@ -327,15 +320,14 @@ ex ncmul::eval(int level) const if (assocseq.empty()) return _ex1; // determine return types - unsignedvector rettypes; - rettypes.reserve(assocseq.size()); + unsignedvector rettypes(assocseq.size()); size_t i = 0; size_t count_commutative=0; size_t count_noncommutative=0; size_t count_noncommutative_composite=0; - cit = assocseq.begin(); citend = assocseq.end(); - while (cit != citend) { - switch (rettypes[i] = cit->return_type()) { + for (auto & it : assocseq) { + rettypes[i] = it.return_type(); + switch (rettypes[i]) { case return_types::commutative: count_commutative++; break; @@ -348,7 +340,7 @@ ex ncmul::eval(int level) const default: throw(std::logic_error("ncmul::eval(): invalid return type")); } - ++i; ++cit; + ++i; } GINAC_ASSERT(count_commutative+count_noncommutative+count_noncommutative_composite==assocseq.size()); @@ -366,8 +358,8 @@ ex ncmul::eval(int level) const else noncommutativeseq.push_back(assocseq[i]); } - commutativeseq.push_back((new ncmul(noncommutativeseq,1))->setflag(status_flags::dynallocated)); - return (new mul(commutativeseq))->setflag(status_flags::dynallocated); + commutativeseq.push_back(dynallocate(std::move(noncommutativeseq))); + return dynallocate(std::move(commutativeseq)); } // ncmul(x1,y1,x2,y2) -> *(ncmul(x1,x2),ncmul(y1,y2)) @@ -380,18 +372,17 @@ ex ncmul::eval(int level) const size_t assoc_num = assocseq.size(); exvectorvector evv; - unsignedvector rttinfos; + std::vector rttinfos; evv.reserve(assoc_num); rttinfos.reserve(assoc_num); - cit = assocseq.begin(), citend = assocseq.end(); - while (cit != citend) { - unsigned ti = cit->return_type_tinfo(); + for (auto & it : assocseq) { + return_type_t ti = it.return_type_tinfo(); size_t rtt_num = rttinfos.size(); // search type in vector of known types for (i=0; ireserve(assoc_num); - (evv.end()-1)->push_back(*cit); + (evv.end()-1)->push_back(it); } - ++cit; } size_t evv_num = evv.size(); @@ -416,34 +406,31 @@ ex ncmul::eval(int level) const #endif // def DO_GINAC_ASSERT // if all elements are of same type, simplify the string - if (evv_num == 1) + if (evv_num == 1) { return evv[0][0].eval_ncmul(evv[0]); + } exvector splitseq; splitseq.reserve(evv_num); for (i=0; isetflag(status_flags::dynallocated)); + splitseq.push_back(dynallocate(evv[i])); - return (new mul(splitseq))->setflag(status_flags::dynallocated); + return dynallocate(splitseq); } - return (new ncmul(assocseq))->setflag(status_flags::dynallocated | - status_flags::evaluated); + return dynallocate(assocseq).setflag(status_flags::evaluated); } ex ncmul::evalm() const { // Evaluate children first - std::auto_ptr s(new exvector); - s->reserve(seq.size()); - exvector::const_iterator it = seq.begin(), itend = seq.end(); - while (it != itend) { - s->push_back(it->evalm()); - it++; - } + exvector s; + s.reserve(seq.size()); + for (auto & it : seq) + s.push_back(it.evalm()); // If there are only matrices, simply multiply them - it = s->begin(); itend = s->end(); + auto it = s.begin(), itend = s.end(); if (is_a(*it)) { matrix prod(ex_to(*it)); it++; @@ -457,17 +444,17 @@ ex ncmul::evalm() const } no_matrix: - return (new ncmul(s))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s)); } ex ncmul::thiscontainer(const exvector & v) const { - return (new ncmul(v))->setflag(status_flags::dynallocated); + return dynallocate(v); } -ex ncmul::thiscontainer(std::auto_ptr vp) const +ex ncmul::thiscontainer(exvector && v) const { - return (new ncmul(vp))->setflag(status_flags::dynallocated); + return dynallocate(std::move(v)); } ex ncmul::conjugate() const @@ -476,17 +463,27 @@ ex ncmul::conjugate() const return exprseq::conjugate(); } - if ((return_type_tinfo() & 0xffffff00U) != TINFO_clifford) { + if (!is_clifford_tinfo(return_type_tinfo())) { return exprseq::conjugate(); } exvector ev; ev.reserve(nops()); - for (const_iterator i=end(); i!=begin();) { + for (auto i=end(); i!=begin();) { --i; ev.push_back(i->conjugate()); } - return (new ncmul(ev, true))->setflag(status_flags::dynallocated).eval(); + return dynallocate(std::move(ev)); +} + +ex ncmul::real_part() const +{ + return basic::real_part(); +} + +ex ncmul::imag_part() const +{ + return basic::imag_part(); } // protected @@ -505,10 +502,10 @@ ex ncmul::derivative(const symbol & s) const for (size_t i=0; isetflag(status_flags::dynallocated)); + addseq.push_back(dynallocate(ncmulseq)); e.swap(ncmulseq[i]); } - return (new add(addseq))->setflag(status_flags::dynallocated); + return dynallocate(addseq); } int ncmul::compare_same_type(const basic & other) const @@ -524,7 +521,7 @@ unsigned ncmul::return_type() 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) @@ -536,10 +533,8 @@ unsigned ncmul::return_type() const } if ((rt == return_types::noncommutative) && (!all_commutative)) { // another nc element found, compare type_infos - if (noncommutative_element->return_type_tinfo() != i->return_type_tinfo()) { - // diffent types -> mul is ncc - return return_types::noncommutative_composite; - } + if(noncommutative_element->return_type_tinfo() != i->return_type_tinfo()) + return return_types::noncommutative_composite; } ++i; } @@ -547,22 +542,19 @@ unsigned ncmul::return_type() const GINAC_ASSERT(!all_commutative); // not all factors should commutate, because this is a ncmul(); return all_commutative ? return_types::commutative : return_types::noncommutative; } - -unsigned ncmul::return_type_tinfo() const + +return_type_t ncmul::return_type_tinfo() const { if (seq.empty()) - return tinfo_key; + return make_return_type_t(); // return type_info of first noncommutative element - exvector::const_iterator i = seq.begin(), end = seq.end(); - while (i != end) { - if (i->return_type() == return_types::noncommutative) - return i->return_type_tinfo(); - ++i; - } + for (auto & i : seq) + if (i.return_type() == return_types::noncommutative) + return i.return_type_tinfo(); // no noncommutative element found, should not happen - return tinfo_key; + return make_return_type_t(); } ////////// @@ -575,24 +567,24 @@ unsigned ncmul::return_type_tinfo() const // non-virtual functions in this class ////////// -std::auto_ptr ncmul::expandchildren(unsigned options) const +exvector ncmul::expandchildren(unsigned options) const { - const_iterator cit = this->seq.begin(), end = this->seq.end(); + auto cit = this->seq.begin(), end = this->seq.end(); while (cit != end) { const ex & expanded_ex = cit->expand(options); if (!are_ex_trivially_equal(*cit, expanded_ex)) { // copy first part of seq which hasn't changed - std::auto_ptr s(new exvector(this->seq.begin(), cit)); - reserve(*s, this->seq.size()); + exvector s(this->seq.begin(), cit); + s.reserve(this->seq.size()); // insert changed element - s->push_back(expanded_ex); + s.push_back(expanded_ex); ++cit; // copy rest while (cit != end) { - s->push_back(cit->expand(options)); + s.push_back(cit->expand(options)); ++cit; } @@ -602,7 +594,7 @@ std::auto_ptr ncmul::expandchildren(unsigned options) const ++cit; } - return std::auto_ptr(0); // nothing has changed + return exvector(); // nothing has changed } const exvector & ncmul::get_factors() const @@ -616,7 +608,7 @@ const exvector & ncmul::get_factors() const ex reeval_ncmul(const exvector & v) { - return (new ncmul(v))->setflag(status_flags::dynallocated); + return dynallocate(v); } ex hold_ncmul(const exvector & v) @@ -626,8 +618,9 @@ 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(v).setflag(status_flags::evaluated); } +GINAC_BIND_UNARCHIVER(ncmul); + } // namespace GiNaC