return i.hold();
}
-/** Try to contract two indexed expressions. If a contraction exists, the
- * function overwrites one or both arguments and returns true. Otherwise it
- * returns false. It is guaranteed that both expressions are of class
- * indexed (or a subclass) and that at least one dummy index has been
- * found.
+/** Add two indexed expressions. They are guaranteed to be of class indexed
+ * (or a subclass) and their indices are compatible. This function is used
+ * internally by simplify_indexed().
*
- * @param self The first indexed expression; it's base object is *this
- * @param other The second indexed expression
- * @return true if the contraction was successful, false otherwise */
-bool basic::contract_with(ex & self, ex & other) const
+ * @param self First indexed expression; it's base object is *this
+ * @param other Second indexed expression
+ * @return sum of self and other
+ * @see ex::simplify_indexed() */
+ex basic::add_indexed(const ex & self, const ex & other) const
+{
+ return self + other;
+}
+
+/** Multiply an indexed expression with a scalar. This function is used
+ * internally by simplify_indexed().
+ *
+ * @param self Indexed expression; it's base object is *this
+ * @param other Numeric value
+ * @return product of self and other
+ * @see ex::simplify_indexed() */
+ex basic::scalar_mul_indexed(const ex & self, const numeric & other) const
+{
+ return self * other;
+}
+
+/** Try to contract two indexed expressions that appear in the same product.
+ * If a contraction exists, the function overwrites one or both of the
+ * expressions and returns true. Otherwise it returns false. It is
+ * guaranteed that both expressions are of class indexed (or a subclass)
+ * and that at least one dummy index has been found. This functions is
+ * used internally by simplify_indexed().
+ *
+ * @param self Pointer to first indexed expression; it's base object is *this
+ * @param other Pointer to second indexed expression
+ * @param v The complete vector of factors
+ * @return true if the contraction was successful, false otherwise
+ * @see ex::simplify_indexed() */
+bool basic::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
{
// Do nothing
return false;
/** Returns order relation between two objects of same type. This needs to be
* implemented by each class. It may never return anything else than 0,
* signalling equality, or +1 and -1 signalling inequality and determining
- * the canonical ordering. */
+ * the canonical ordering. (Perl hackers will wonder why C++ doesn't feature
+ * the spaceship operator <=> for denoting just this.) */
int basic::compare_same_type(const basic & other) const
{
return compare_pointers(this, &other);
GINAC_ASSERT(typeid(*this)==typeid(other));
- int cmpval = compare_same_type(other);
- if ((cmpval!=0) && (hash_this<0x80000000U)) {
+// int cmpval = compare_same_type(other);
+// if ((cmpval!=0) && (hash_this<0x80000000U)) {
// std::cout << "hash collision, same type: "
// << *this << " and " << other << std::endl;
// this->printraw(std::cout);
// std::cout << " and ";
// other.printraw(std::cout);
// std::cout << std::endl;
- }
- return cmpval;
+// }
+// return cmpval;
+
+ return compare_same_type(other);
}
/** Test for equality.