* Implementation of GiNaC's indexed expressions. */
/*
- * 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
// default constructor
//////////
-indexed::indexed() : symtree(sy_none())
+indexed::indexed() : symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
}
// other constructors
//////////
-indexed::indexed(const ex & b) : inherited(b), symtree(sy_none())
+indexed::indexed(const ex & b) : inherited(b), symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
validate();
}
-indexed::indexed(const ex & b, const ex & i1) : inherited(b, i1), symtree(sy_none())
+indexed::indexed(const ex & b, const ex & i1) : inherited(b, i1), symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
validate();
}
-indexed::indexed(const ex & b, const ex & i1, const ex & i2) : inherited(b, i1, i2), symtree(sy_none())
+indexed::indexed(const ex & b, const ex & i1, const ex & i2) : inherited(b, i1, i2), symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
validate();
}
-indexed::indexed(const ex & b, const ex & i1, const ex & i2, const ex & i3) : inherited(b, i1, i2, i3), symtree(sy_none())
+indexed::indexed(const ex & b, const ex & i1, const ex & i2, const ex & i3) : inherited(b, i1, i2, i3), symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
validate();
}
-indexed::indexed(const ex & b, const ex & i1, const ex & i2, const ex & i3, const ex & i4) : inherited(b, i1, i2, i3, i4), symtree(sy_none())
+indexed::indexed(const ex & b, const ex & i1, const ex & i2, const ex & i3, const ex & i4) : inherited(b, i1, i2, i3, i4), symtree(not_symmetric())
{
tinfo_key = TINFO_indexed;
validate();
validate();
}
-indexed::indexed(const ex & b, const exvector & v) : inherited(b), symtree(sy_none())
+indexed::indexed(const ex & b, const exvector & v) : inherited(b), symtree(not_symmetric())
{
seq.insert(seq.end(), v.begin(), v.end());
tinfo_key = TINFO_indexed;
symtree = sy_anti();
break;
default:
- symtree = sy_none();
+ symtree = not_symmetric();
break;
}
const_cast<symmetry &>(ex_to<symmetry>(symtree)).validate(seq.size() - 1);
{
GINAC_ASSERT(seq.size() > 0);
- if ((options & expand_options::expand_indexed) && is_exactly_a<add>(seq[0])) {
-
- // expand_indexed expands (a+b).i -> a.i + b.i
- const ex & base = seq[0];
- ex sum = _ex0;
- for (size_t i=0; i<base.nops(); i++) {
+ if (options & expand_options::expand_indexed) {
+ ex newbase = seq[0].expand(options);
+ if (is_exactly_a<add>(newbase)) {
+ ex sum = _ex0;
+ for (size_t i=0; i<newbase.nops(); i++) {
+ exvector s = seq;
+ s[0] = newbase.op(i);
+ sum += thiscontainer(s).expand(options);
+ }
+ return sum;
+ }
+ if (!are_ex_trivially_equal(newbase, seq[0])) {
exvector s = seq;
- s[0] = base.op(i);
- sum += thiscontainer(s).expand();
+ s[0] = newbase;
+ return ex_to<indexed>(thiscontainer(s)).inherited::expand(options);
}
- return sum;
-
- } else
- return inherited::expand(options);
+ }
+ return inherited::expand(options);
}
//////////
return free_indices;
}
+struct is_summation_idx : public std::unary_function<ex, bool> {
+ bool operator()(const ex & e)
+ {
+ return is_dummy_pair(e, e);
+ }
+};
+
exvector power::get_free_indices() const
{
- // Return free indices of basis
- return basis.get_free_indices();
+ // Get free indices of basis
+ exvector basis_indices = basis.get_free_indices();
+
+ if (exponent.info(info_flags::even)) {
+ // If the exponent is an even number, then any "free" index that
+ // forms a dummy pair with itself is actually a summation index
+ exvector really_free;
+ std::remove_copy_if(basis_indices.begin(), basis_indices.end(),
+ std::back_inserter(really_free), is_summation_idx());
+ return really_free;
+ } else
+ return basis_indices;
}
/** Rename dummy indices in an expression.
* performs contraction of dummy indices where possible and checks whether
* the free indices in sums are consistent.
*
+ * @param options Simplification options (currently unused)
* @return simplified expression */
ex ex::simplify_indexed(unsigned options) const
{
* scalar products by known values if desired.
*
* @param sp Scalar products to be replaced automatically
+ * @param options Simplification options (currently unused)
* @return simplified expression */
ex ex::simplify_indexed(const scalar_products & sp, unsigned options) const
{