]> www.ginac.de Git - ginac.git/blobdiff - ginac/ncmul.cpp
fixed operator precedence
[ginac.git] / ginac / ncmul.cpp
index e3a6b552f7e6d0294022fb69603083325ec40b4f..ccc91c490d4be13f853739e61b8d423c076e6fe4 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's non-commutative products of expressions. */
 
 /*
  *  Implementation of GiNaC's non-commutative products of expressions. */
 
 /*
- *  GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2004 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
  *
  *  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
@@ -36,7 +36,7 @@ namespace GiNaC {
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq,
   print_func<print_context>(&ncmul::do_print).
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(ncmul, exprseq,
   print_func<print_context>(&ncmul::do_print).
-  print_func<print_tree>(&basic::do_print_tree).
+  print_func<print_tree>(&ncmul::do_print_tree).
   print_func<print_csrc>(&ncmul::do_print_csrc).
   print_func<print_python_repr>(&ncmul::do_print_csrc))
 
   print_func<print_csrc>(&ncmul::do_print_csrc).
   print_func<print_python_repr>(&ncmul::do_print_csrc))
 
@@ -127,7 +127,8 @@ typedef std::vector<int> intvector;
 ex ncmul::expand(unsigned options) const
 {
        // First, expand the children
 ex ncmul::expand(unsigned options) const
 {
        // First, expand the children
-       exvector expanded_seq = expandchildren(options);
+       std::auto_ptr<exvector> 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.
        
        // Now, look for all the factors that are sums and remember their
        // position and number of terms.
@@ -151,9 +152,13 @@ ex ncmul::expand(unsigned options) const
        }
 
        // If there are no sums, we are done
        }
 
        // 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
 
        // Now, form all possible products of the terms of the sums with the
        // remaining factors, and add them together
@@ -456,6 +461,25 @@ ex ncmul::thiscontainer(std::auto_ptr<exvector> vp) const
        return (new ncmul(vp))->setflag(status_flags::dynallocated);
 }
 
        return (new ncmul(vp))->setflag(status_flags::dynallocated);
 }
 
+ex ncmul::conjugate() const
+{
+       if (return_type() != return_types::noncommutative) {
+               return exprseq::conjugate();
+       }
+
+       if ((return_type_tinfo() & 0xffffff00U) != TINFO_clifford) {
+               return exprseq::conjugate();
+       }
+
+       exvector ev;
+       ev.reserve(nops());
+       for (const_iterator i=end(); i!=begin();) {
+               --i;
+               ev.push_back(i->conjugate());
+       }
+       return (new ncmul(ev, true))->setflag(status_flags::dynallocated).eval();
+}
+
 // protected
 
 /** Implementation of ex::diff() for a non-commutative product. It applies
 // protected
 
 /** Implementation of ex::diff() for a non-commutative product. It applies
@@ -542,16 +566,34 @@ unsigned ncmul::return_type_tinfo() const
 // non-virtual functions in this class
 //////////
 
 // non-virtual functions in this class
 //////////
 
-exvector ncmul::expandchildren(unsigned options) const
+std::auto_ptr<exvector> 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<exvector> 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<exvector>(0); // nothing has changed
 }
 
 const exvector & ncmul::get_factors() const
 }
 
 const exvector & ncmul::get_factors() const