*/
#include <stdexcept>
+#include <algorithm>
#include "idx.h"
#include "symbol.h"
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());
}
// 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;
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();
// 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();
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