]> www.ginac.de Git - ginac.git/blobdiff - ginac/idx.cpp
Synced to HEAD
[ginac.git] / ginac / idx.cpp
index 1b4bf6f5e3d2f781d00080892f8f719ce2c2012d..c95c07c72fc87ef01655d157ef256e21a587bf78 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's indices. */
 
 /*
- *  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
@@ -29,7 +29,6 @@
 #include "lst.h"
 #include "relational.h"
 #include "operators.h"
-#include "print.h"
 #include "archive.h"
 #include "utils.h"
 
@@ -42,7 +41,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(idx, basic,
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(varidx, idx,
   print_func<print_context>(&varidx::do_print).
-  // print_latex inherited from idx
+  print_func<print_latex>(&varidx::do_print_latex).
   print_func<print_tree>(&varidx::do_print_tree))
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(spinidx, varidx,
@@ -134,7 +133,7 @@ DEFAULT_UNARCHIVE(spinidx)
 // functions overriding virtual functions from base classes
 //////////
 
-void idx::do_print_idx(const print_context & c, unsigned level) const
+void idx::print_index(const print_context & c, unsigned level) const
 {
        bool need_parens = !(is_exactly_a<numeric>(value) || is_a<symbol>(value));
        if (need_parens)
@@ -152,19 +151,19 @@ void idx::do_print_idx(const print_context & c, unsigned level) const
 void idx::do_print(const print_context & c, unsigned level) const
 {
        c.s << ".";
-       do_print_idx(c, level);
+       print_index(c, level);
 }
 
 void idx::do_print_latex(const print_latex & c, unsigned level) const
 {
        c.s << "{";
-       do_print_idx(c, level);
+       print_index(c, level);
        c.s << "}";
 }
 
 void idx::do_print_tree(const print_tree & c, unsigned level) const
 {
-       c.s << std::string(level, ' ') << class_name()
+       c.s << std::string(level, ' ') << class_name() << " @" << this
            << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
            << std::endl;
        value.print(c, level +  c.delta_indent);
@@ -177,12 +176,12 @@ void varidx::do_print(const print_context & c, unsigned level) const
                c.s << ".";
        else
                c.s << "~";
-       do_print_idx(c, level);
+       print_index(c, level);
 }
 
 void varidx::do_print_tree(const print_tree & c, unsigned level) const
 {
-       c.s << std::string(level, ' ') << class_name()
+       c.s << std::string(level, ' ') << class_name() << " @" << this
            << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
            << (covariant ? ", covariant" : ", contravariant")
            << std::endl;
@@ -198,7 +197,7 @@ void spinidx::do_print(const print_context & c, unsigned level) const
                c.s << "~";
        if (dotted)
                c.s << "*";
-       do_print_idx(c, level);
+       print_index(c, level);
 }
 
 void spinidx::do_print_latex(const print_latex & c, unsigned level) const
@@ -207,13 +206,13 @@ void spinidx::do_print_latex(const print_latex & c, unsigned level) const
                c.s << "\\dot{";
        else
                c.s << "{";
-       do_print_idx(c, level);
+       print_index(c, level);
        c.s << "}";
 }
 
 void spinidx::do_print_tree(const print_tree & c, unsigned level) const
 {
-       c.s << std::string(level, ' ') << class_name()
+       c.s << std::string(level, ' ') << class_name() << " @" << this
            << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
            << (covariant ? ", covariant" : ", contravariant")
            << (dotted ? ", dotted" : ", undotted")
@@ -243,11 +242,16 @@ ex idx::op(size_t i) const
 
 ex idx::map(map_function & f) const
 {
-       idx *copy = duplicate();
-       copy->setflag(status_flags::dynallocated);
-       copy->clearflag(status_flags::hash_calculated);
-       copy->value = f(value);
-       return *copy;
+       const ex &mapped_value = f(value);
+       if (are_ex_trivially_equal(value, mapped_value))
+               return *this;
+       else {
+               idx *copy = duplicate();
+               copy->setflag(status_flags::dynallocated);
+               copy->clearflag(status_flags::hash_calculated);
+               copy->value = mapped_value;
+               return *copy;
+       }
 }
 
 /** Returns order relation between two indices of the same type. The order
@@ -326,11 +330,17 @@ bool spinidx::match_same_type(const basic & other) const
 
 unsigned idx::calchash() const
 {
+       // NOTE: The code in simplify_indexed() assumes that canonically
+       // ordered sequences of indices have the two members of dummy index
+       // pairs lying next to each other. The hash values for indices must
+       // be devised accordingly. The easiest (only?) way to guarantee the
+       // desired ordering is to make indices with the same value have equal
+       // hash keys. That is, the hash values must not depend on the index
+       // dimensions or other attributes (variance etc.).
+       // The compare_same_type() methods will take care of the rest.
        unsigned v = golden_ratio_hash(tinfo());
        v = rotate_left(v);
        v ^= value.gethash();
-       v = rotate_left(v);
-       v ^= dim.gethash();
 
        // Store calculated hash value only if object is already evaluated
        if (flags & status_flags::evaluated) {