Subject: [UFL-dev] Representing implicit sums explicitly

From: "Martin Sandve Alnæs" <[email-masked]>
Date: Tue, 20 Jan 2009 11:01:13 +0100

I'm considering rewriting some parts of UFL to represent
implicit sums as an explicit expression tree node.
This will not affect the user interface.

Implicit sums can occur in these three situations:

Indexed: v[i,i]
SpatialDerivative: v[i].dx(i)
Product: v[i]*u[i]

Currently an implicit sum over repeated indices is assumed
when, for an Indexed, SpatialDerivative or Product object o,
o.repeated_indices() != ().

This leads to a lot of special casing and duplicated handling
of repeated indices for these three types with subtle differences
in some algorithms.

With the addition of an IndexSum class, we can remove
the repeated_indices function and handle all implicit sums
over indices in one place for each algorithm.

An example to clarify:

# Input:
a = v[i,i]

# Currently represented as:
a = Indexed(v, (i,i)) # a.repeated_indices() == (i,)

# New representation:
summand = Indexed(v, (i,i))
a = IndexSum(summand, i)

# Multiple repeated indices can be handled in two ways:
a = v[i,j]*u[j,i]

# Currently represented as:
vv = Indexed(v, (i, j))
uu = Indexed(u, (j, i))
a = Product(vv, uu)  # a.repeated_indices() == (i,j)

# New representation:
vv = Indexed(v, (i, j))
uu = Indexed(u, (j, i))
summand = Product(vv, uu)
a = IndexSum(summand, (i,j)) # version 1
a = IndexSum(IndexSum(summand, i), j) # version 2

I will probably opt for version 2, one index per IndexSum object.

I still need to look over some parts of the implementation to see
if this can have other side effects, but it feels right to do this.

Does anyone have objections?

Martin