]> www.ginac.de Git - ginac.git/blobdiff - ginac/ncmul.cpp
Prettified source code.
[ginac.git] / ginac / ncmul.cpp
index abad2d1616c910a180c5cfa9c7b42260d6839aaf..0c22a81f159b0a8318002a89b84ea41ad7036c97 100644 (file)
@@ -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
  *
  *  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 <algorithm>
-#include <iostream>
-#include <stdexcept>
-
 #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 <algorithm>
+#include <iostream>
+#include <stdexcept>
+
 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;
 }
 
 //////////
@@ -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<exvector> vp) : inherited(vp)
 {
-       tinfo_key = TINFO_ncmul;
 }
 
 //////////
 // archiving
 //////////
 
-DEFAULT_ARCHIVING(ncmul)
-       
+
 //////////
 // functions overriding virtual functions from base classes
 //////////
@@ -122,7 +115,7 @@ bool ncmul::info(unsigned inf) const
        return inherited::info(inf);
 }
 
-typedef std::vector<int> intvector;
+typedef std::vector<std::size_t> uintvector;
 
 ex ncmul::expand(unsigned options) const
 {
@@ -132,8 +125,8 @@ ex ncmul::expand(unsigned options) const
        
        // 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;
@@ -165,12 +158,28 @@ 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<expanded_seq.size(); i++) {
+               if (i == positions_of_adds[j]) {
+                       expanded_seq_mod.push_back(_ex1);
+                       j++;
+               } else {
+                       expanded_seq_mod.push_back(rename_dummy_indices_uniquely(va, expanded_seq[i], true));
+               }
+       }
 
        while (true) {
-               exvector term = expanded_seq;
-               for (size_t i=0; i<number_of_adds; i++)
-                       term[positions_of_adds[i]] = expanded_seq[positions_of_adds[i]].op(k[i]);
+               exvector term = expanded_seq_mod;
+               for (size_t i=0; i<number_of_adds; i++) {
+                       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(term, true))->
                                    setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
 
@@ -317,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;
 
@@ -380,17 +392,17 @@ ex ncmul::eval(int level) const
 
                size_t assoc_num = assocseq.size();
                exvectorvector evv;
-               unsignedvector rttinfos;
+               std::vector<return_type_t> 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; i<rtt_num; ++i) {
-                               if (ti == rttinfos[i]) {
+                               if(ti == rttinfos[i]) {
                                        evv[i].push_back(*cit);
                                        break;
                                }
@@ -416,8 +428,9 @@ 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);
@@ -476,7 +489,7 @@ ex ncmul::conjugate() const
                return exprseq::conjugate();
        }
 
-       if ((return_type_tinfo() & 0xffffff00U) != TINFO_clifford) {
+       if (!is_clifford_tinfo(return_type_tinfo())) {
                return exprseq::conjugate();
        }
 
@@ -489,6 +502,16 @@ ex ncmul::conjugate() const
        return (new ncmul(ev, true))->setflag(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
@@ -536,10 +559,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;
        }
@@ -548,10 +569,10 @@ unsigned ncmul::return_type() const
        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<ncmul>();
 
        // return type_info of first noncommutative element
        exvector::const_iterator i = seq.begin(), end = seq.end();
@@ -562,7 +583,7 @@ unsigned ncmul::return_type_tinfo() const
        }
 
        // no noncommutative element found, should not happen
-       return tinfo_key;
+       return make_return_type_t<ncmul>();
 }
 
 //////////
@@ -630,4 +651,6 @@ ex hold_ncmul(const exvector & v)
                                               status_flags::evaluated);
 }
 
+GINAC_BIND_UNARCHIVER(ncmul);
+
 } // namespace GiNaC