X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fncmul.cpp;h=0c22a81f159b0a8318002a89b84ea41ad7036c97;hp=a00bff1e385f2016228f4dd850ce55757a93263f;hb=1602530f716ba1d425a0667b897182b99c374823;hpb=8dc09f48182574d792a2ed7c37b66831d9267a6c diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index a00bff1e..0c22a81f 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-2004 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2009 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,26 +17,28 @@ * * 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, print_func(&ncmul::do_print). - print_func(&basic::do_print_tree). + print_func(&ncmul::do_print_tree). print_func(&ncmul::do_print_csrc). print_func(&ncmul::do_print_csrc)) @@ -47,7 +49,6 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq, ncmul::ncmul() { - tinfo_key = TINFO_ncmul; } ////////// @@ -58,48 +59,40 @@ ncmul::ncmul() 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) { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(const ex & f1, const ex & f2, const ex & f3, 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) { - 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) { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(const exvector & v, bool discardable) : inherited(v,discardable) { - tinfo_key = TINFO_ncmul; } ncmul::ncmul(std::auto_ptr vp) : inherited(vp) { - tinfo_key = TINFO_ncmul; } ////////// // archiving ////////// -DEFAULT_ARCHIVING(ncmul) - + ////////// // functions overriding virtual functions from base classes ////////// @@ -122,17 +115,18 @@ 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 - exvector expanded_seq = expandchildren(options); + std::auto_ptr vp = expandchildren(options); + const exvector &expanded_seq = vp.get() ? *vp : this->seq; // 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; @@ -151,21 +145,41 @@ ex ncmul::expand(unsigned options) const } // If there are no sums, we are done - if (number_of_adds == 0) - return (new ncmul(expanded_seq, true))-> - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + if (number_of_adds == 0) { + if (vp.get()) + return (new ncmul(vp))-> + setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)); + else + return *this; + } // Now, form all possible products of the terms of the sums with the // remaining factors, and add them together 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))); @@ -185,6 +199,9 @@ ex ncmul::expand(unsigned options) const int ncmul::degree(const ex & s) const { + if (is_equal(ex_to(s))) + return 1; + // Sum up degrees of factors int deg_sum = 0; exvector::const_iterator i = seq.begin(), end = seq.end(); @@ -197,6 +214,9 @@ int ncmul::degree(const ex & s) const int ncmul::ldegree(const ex & s) const { + if (is_equal(ex_to(s))) + return 1; + // Sum up degrees of factors int deg_sum = 0; exvector::const_iterator i = seq.begin(), end = seq.end(); @@ -209,6 +229,9 @@ int ncmul::ldegree(const ex & s) const ex ncmul::coeff(const ex & s, int n) const { + if (is_equal(ex_to(s))) + return n==1 ? _ex1 : _ex0; + exvector coeffseq; coeffseq.reserve(seq.size()); @@ -303,12 +326,15 @@ ex ncmul::eval(int level) const exvector assocseq; assocseq.reserve(factors); cit = evaledseq.begin(); + make_flat_inserter mf(evaledseq, true); while (cit != citend) - append_factors(assocseq, *cit++); + { ex factor = mf.handle_factor(*(cit++), 1); + append_factors(assocseq, factor); + } // ncmul(x) -> x if (assocseq.size()==1) return *(seq.begin()); - + // ncmul() -> 1 if (assocseq.empty()) return _ex1; @@ -366,17 +392,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(); + return_type_t ti = cit->return_type_tinfo(); size_t rtt_num = rttinfos.size(); // search type in vector of known types for (i=0; isetflag(status_flags::dynallocated).eval(); } +ex ncmul::real_part() const +{ + return basic::real_part(); +} + +ex ncmul::imag_part() const +{ + return basic::imag_part(); +} + // protected /** Implementation of ex::diff() for a non-commutative product. It applies @@ -522,22 +559,20 @@ 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; } // all factors checked - GINAC_ASSERT(!all_commutative); // not all factors should commute, because this is a ncmul(); + 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(); @@ -548,7 +583,7 @@ unsigned ncmul::return_type_tinfo() const } // no noncommutative element found, should not happen - return tinfo_key; + return make_return_type_t(); } ////////// @@ -561,16 +596,34 @@ unsigned ncmul::return_type_tinfo() const // non-virtual functions in this class ////////// -exvector ncmul::expandchildren(unsigned options) const +std::auto_ptr ncmul::expandchildren(unsigned options) const { - exvector s; - s.reserve(seq.size()); - exvector::const_iterator it = seq.begin(), itend = seq.end(); - while (it != itend) { - s.push_back(it->expand(options)); - it++; + const_iterator 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()); + + // insert changed element + s->push_back(expanded_ex); + ++cit; + + // copy rest + while (cit != end) { + s->push_back(cit->expand(options)); + ++cit; + } + + return s; + } + + ++cit; } - return s; + + return std::auto_ptr(0); // nothing has changed } const exvector & ncmul::get_factors() const @@ -598,4 +651,6 @@ ex hold_ncmul(const exvector & v) status_flags::evaluated); } +GINAC_BIND_UNARCHIVER(ncmul); + } // namespace GiNaC