-/** Given a vector iv3 of three indices and a vector iv2 of two indices
- * where iv2 is a subset of iv3, return the (free) index that is in iv3
- * but not in iv2 and the sign introduced by permuting that index to the
- * front.
- *
- * @param iv3 Vector of 3 indices
- * @param iv2 Vector of 2 indices, must be a subset of iv3
- * @param sig Returns the sign introduced by permuting the free index to the
- * front if the object carrying the indices was antisymmetric (if
- * it's symmetric, you can just ignore the returned value).
- * @return the free index (the one that is in iv3 but not in iv2) */
-ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2, int * sig)
-{
- // match (return value,iv2) to iv3 by permuting indices
- // iv3 is always cyclic
-
- GINAC_ASSERT(iv3.size()==3);
- GINAC_ASSERT(iv2.size()==2);
-
- *sig=1;
-
-#define TEST_PERMUTATION(A,B,C,P) \
- if ((iv3[B].is_equal(iv2[0]))&&(iv3[C].is_equal(iv2[1]))) { \
- *sig=P; \
- return iv3[A]; \
- }
-
- TEST_PERMUTATION(0,1,2, 1);
- TEST_PERMUTATION(0,2,1, -1);
- TEST_PERMUTATION(1,0,2, -1);
- TEST_PERMUTATION(1,2,0, 1);
- TEST_PERMUTATION(2,0,1, 1);
- TEST_PERMUTATION(2,1,0, -1);
- throw(std::logic_error("permute_free_index_to_front(): no valid permutation found"));
-}
-
-/** Substitute one index in a vector of expressions.
- *
- * @param v Vector to substitute in (will be modified)
- * @param is Index being substituted
- * @param ir Index to replace by
- * @return number of performed substitutions */
-unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir)
-{
- exvector::iterator it;
- unsigned replacements=0;
- unsigned current_replacements;
-
- GINAC_ASSERT(is_ex_of_type(is,idx));
- GINAC_ASSERT(is_ex_of_type(ir,idx));
-
- for (it=v.begin(); it!=v.end(); ++it) {
- current_replacements=count_index(*it,is);
- if (current_replacements>0) {
- (*it)=(*it).subs(is==ir);
- }
- replacements += current_replacements;