]> www.ginac.de Git - ginac.git/blobdiff - ginac/idx.cpp
- added symmetrize() and antisymmetrize() functions
[ginac.git] / ginac / idx.cpp
index 90ac3a425a35bfd6b2158e60b40eb8e8d36277fb..c72e478e305bc02398394aa7486ceafe3d1d9150 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <stdexcept>
+#include <algorithm>
 
 #include "idx.h"
 #include "symbol.h"
@@ -304,20 +305,48 @@ int spinidx::compare_same_type(const basic & other) const
        GINAC_ASSERT(is_of_type(other, spinidx));
        const spinidx &o = static_cast<const spinidx &>(other);
 
+       // Check dottedness first so dummy indices will end up next to each other
+       if (dotted != o.dotted)
+               return dotted ? -1 : 1;
+
        int cmpval = inherited::compare_same_type(other);
        if (cmpval)
                return cmpval;
 
-       // Check variance and dottedness last so dummy indices will end up next to each other
+       return 0;
+}
+
+bool idx::match(const ex & pattern, lst & repl_lst) const
+{
+       if (!is_ex_of_type(pattern, idx))
+               return false;
+       const idx &o = ex_to_idx(pattern);
+       if (!dim.is_equal(o.dim))
+               return false;
+       return value.match(o.value, repl_lst);
+}
+
+bool varidx::match(const ex & pattern, lst & repl_lst) const
+{
+       if (!is_ex_of_type(pattern, varidx))
+               return false;
+       const varidx &o = ex_to_varidx(pattern);
        if (covariant != o.covariant)
-               return covariant ? -1 : 1;
-       if (dotted != o.dotted)
-               return dotted ? -1 : 1;
+               return false;
+       return inherited::match(pattern, repl_lst);
+}
 
-       return 0;
+bool spinidx::match(const ex & pattern, lst & repl_lst) const
+{
+       if (!is_ex_of_type(pattern, spinidx))
+               return false;
+       const spinidx &o = ex_to_spinidx(pattern);
+       if (dotted != o.dotted)
+               return false;
+       return inherited::match(pattern, repl_lst);
 }
 
-ex idx::subs(const lst & ls, const lst & lr) const
+ex idx::subs(const lst & ls, const lst & lr, bool no_pattern) const
 {
        GINAC_ASSERT(ls.nops() == lr.nops());
 
@@ -338,7 +367,7 @@ ex idx::subs(const lst & ls, const lst & lr) const
        }
 
        // None, substitute objects in value (not in dimension)
-       const ex &subsed_value = value.subs(ls, lr);
+       const ex &subsed_value = value.subs(ls, lr, no_pattern);
        if (are_ex_trivially_equal(value, subsed_value))
                return *this;
 
@@ -443,29 +472,6 @@ bool is_dummy_pair(const ex & e1, const ex & e2)
        return is_dummy_pair(ex_to_idx(e1), ex_to_idx(e2));
 }
 
-/** Bring a vector of indices into a canonic order. Dummy indices will lie
- *  next to each other after the sorting. */
-static void sort_index_vector(exvector &v)
-{
-       // Nothing to sort if less than 2 elements
-       if (v.size() < 2)
-               return;
-
-       // Simple bubble sort algorithm should be sufficient for the small
-       // number of indices expected
-       exvector::iterator it1 = v.begin(), itend = v.end(), next_to_last_idx = itend - 1;
-       while (it1 != next_to_last_idx) {
-               exvector::iterator it2 = it1 + 1;
-               while (it2 != itend) {
-                       if (it1->compare(*it2) > 0)
-                               it1->swap(*it2);
-                       it2++;
-               }
-               it1++;
-       }
-}
-
-
 void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector & out_free, exvector & out_dummy)
 {
        out_free.clear();
@@ -485,7 +491,7 @@ void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator i
        // Sort index vector. This will cause dummy indices come to lie next
        // to each other (because the sort order is defined to guarantee this).
        exvector v(it, itend);
-       sort_index_vector(v);
+       shaker_sort(v.begin(), v.end(), ex_is_less());
 
        // Find dummy pairs and free indices
        it = v.begin(); itend = v.end();
@@ -506,27 +512,4 @@ void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator i
                out_free.push_back(*last);
 }
 
-exvector index_set_difference(const exvector & set1, const exvector & set2)
-{
-       exvector ret;
-
-       exvector::const_iterator ait = set1.begin(), aitend = set1.end();
-       while (ait != aitend) {
-               exvector::const_iterator bit = set2.begin(), bitend = set2.end();
-               bool found = false;
-               while (bit != bitend) {
-                       if (ait->is_equal(*bit)) {
-                               found = true;
-                               break;
-                       }
-                       bit++;
-               }
-               if (!found)
-                       ret.push_back(*ait);
-               ait++;
-       }
-
-       return ret;
-}
-
 } // namespace GiNaC