]> www.ginac.de Git - ginac.git/blobdiff - ginac/indexed.cpp
* fixed some mindboggling tremendous superhuge gigantic #*@$&! memory leaks.
[ginac.git] / ginac / indexed.cpp
index 3e333e3f5806563dd28f32b4cd5cb24ebe6c413c..6fbe40b97cb726eaad9a24d395066d0511d6992a 100644 (file)
@@ -28,6 +28,8 @@
 #include "mul.h"
 #include "ncmul.h"
 #include "power.h"
+#include "lst.h"
+#include "print.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -175,42 +177,38 @@ DEFAULT_UNARCHIVE(indexed)
 // functions overriding virtual functions from bases classes
 //////////
 
-void indexed::printraw(std::ostream & os) const
+void indexed::print(const print_context & c, unsigned level) const
 {
-       debugmsg("indexed printraw", LOGLEVEL_PRINT);
+       debugmsg("indexed print", LOGLEVEL_PRINT);
        GINAC_ASSERT(seq.size() > 0);
 
-       os << class_name() << "(";
-       seq[0].printraw(os);
-       os << ",indices=";
-       printrawindices(os);
-       os << ",hash=" << hashvalue << ",flags=" << flags << ")";
-}
-
-void indexed::printtree(std::ostream & os, unsigned indent) const
-{
-       debugmsg("indexed printtree", LOGLEVEL_PRINT);
-       GINAC_ASSERT(seq.size() > 0);
+       if (is_of_type(c, print_tree)) {
 
-       os << std::string(indent, ' ') << class_name() << ", " << seq.size()-1 << " indices";
-       os << ",hash=" << hashvalue << ",flags=" << flags << std::endl;
-       printtreeindices(os, indent);
-}
+               c.s << std::string(level, ' ') << class_name()
+                   << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+                   << ", " << seq.size()-1 << " indices";
+               switch (symmetry) {
+                       case symmetric: c.s << ", symmetric"; break;
+                       case antisymmetric: c.s << ", antisymmetric"; break;
+                       default: break;
+               }
+               c.s << std::endl;
+               unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+               seq[0].print(c, level + delta_indent);
+               printindices(c, level + delta_indent);
 
-void indexed::print(std::ostream & os, unsigned upper_precedence) const
-{
-       debugmsg("indexed print", LOGLEVEL_PRINT);
-       GINAC_ASSERT(seq.size() > 0);
+       } else {
 
-       const ex & base = seq[0];
-       bool need_parens = is_ex_exactly_of_type(base, add) || is_ex_exactly_of_type(base, mul)
-                       || is_ex_exactly_of_type(base, ncmul) || is_ex_exactly_of_type(base, power);
-       if (need_parens)
-               os << "(";
-       os << base;
-       if (need_parens)
-               os << ")";
-       printindices(os);
+               const ex & base = seq[0];
+               bool need_parens = is_ex_exactly_of_type(base, add) || is_ex_exactly_of_type(base, mul)
+                               || is_ex_exactly_of_type(base, ncmul) || is_ex_exactly_of_type(base, power);
+               if (need_parens)
+                       c.s << "(";
+               base.print(c);
+               if (need_parens)
+                       c.s << ")";
+               printindices(c, level);
+       }
 }
 
 bool indexed::info(unsigned inf) const
@@ -408,38 +406,12 @@ ex indexed::expand(unsigned options) const
 // non-virtual functions in this class
 //////////
 
-void indexed::printrawindices(std::ostream & os) const
-{
-       if (seq.size() > 1) {
-               exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
-               while (it != itend) {
-                       it->printraw(os);
-                       it++;
-                       if (it != itend)
-                               os << ",";
-               }
-       }
-}
-
-void indexed::printtreeindices(std::ostream & os, unsigned indent) const
-{
-       if (seq.size() > 1) {
-               exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
-               while (it != itend) {
-                       os << std::string(indent + delta_indent, ' ');
-                       it->printraw(os);
-                       os << std::endl;
-                       it++;
-               }
-       }
-}
-
-void indexed::printindices(std::ostream & os) const
+void indexed::printindices(const print_context & c, unsigned level) const
 {
        if (seq.size() > 1) {
                exvector::const_iterator it=seq.begin() + 1, itend = seq.end();
                while (it != itend) {
-                       it->print(os);
+                       it->print(c, level);
                        it++;
                }
        }
@@ -629,12 +601,12 @@ try_again:
                                continue;
 
                        // At least one dummy index, is it a defined scalar product?
+                       bool contracted = false;
                        if (free.size() == 0) {
                                if (sp.is_defined(*it1, *it2)) {
                                        *it1 = sp.evaluate(*it1, *it2);
                                        *it2 = _ex1();
-                                       something_changed = true;
-                                       goto try_again;
+                                       goto contraction_done;
                                }
                        }
 
@@ -649,7 +621,7 @@ try_again:
                        }
 
                        // Try to contract the first one with the second one
-                       bool contracted = it1->op(0).bp->contract_with(it1, it2, v);
+                       contracted = it1->op(0).bp->contract_with(it1, it2, v);
                        if (!contracted) {
 
                                // That didn't work; maybe the second object knows how to
@@ -657,11 +629,20 @@ try_again:
                                contracted = it2->op(0).bp->contract_with(it2, it1, v);
                        }
                        if (contracted) {
-                               something_changed = true;
+contraction_done:
+                               if (is_ex_exactly_of_type(*it1, add) || is_ex_exactly_of_type(*it2, add)
+                                || is_ex_exactly_of_type(*it1, mul) || is_ex_exactly_of_type(*it2, mul)) {
+
+                                       // One of the factors became a sum or product:
+                                       // re-expand expression and run again
+                                       ex r = non_commutative ? ex(ncmul(v)) : ex(mul(v));
+                                       return simplify_indexed(r, free_indices, sp);
+                               }
 
                                // Both objects may have new indices now or they might
                                // even not be indexed objects any more, so we have to
                                // start over
+                               something_changed = true;
                                goto try_again;
                        }
                }
@@ -678,12 +659,9 @@ try_again:
        find_free_and_dummy(un, free_indices, dummy_indices);
 
        ex r;
-       if (something_changed) {
-               if (non_commutative)
-                       r = ncmul(v);
-               else
-                       r = mul(v);
-       } else
+       if (something_changed)
+               r = non_commutative ? ex(ncmul(v)) : ex(mul(v));
+       else
                r = e;
 
        // Product of indexed object with a scalar?