MakeRule dummy treatment

833 views
Skip to first unread message

Teake Nutma

unread,
Oct 14, 2011, 2:56:58 PM10/14/11
to xAct Tensor Computer Algebra
Hi all,

I ran into some unexpected behaviour with MakeRule and repeated
dummies today, and decided to share my findings. Consider this code:

=====

(* Define manifold and metric *)
DefManifold[M, 4, IndexRange[a, l]]
DefMetric[-1, metric[-a, -b], CD]

(* Define tensor for which we'll make rules *)
DefTensor[T[-a, -b], M]
DefTensor[S[], M]

(* Make two rules sending S to the same combination of T's *)
LHS = S[]
goodRHS = T[-a, -b] T[a, b] + T[-c, c] T[-d, d] // Validate
goodRule = MakeRule[Evaluate[{LHS,goodRHS}]]

wrongRHS = T[-a, -b] T[a, b] + T[-a, a] T[-b, b] // Validate
wrongRule= MakeRule[Evaluate[{LHS,wrongRHS}]]

(* Applying the wrong rule gives repeated dummy indices xAct can't
handle *)
S[] S[] /. wrongRule // Simplification

(* Applying the good rule works as expected *)
S[] S[] /. goodRule // Simplification


=====

The point is that, to be on the safe side, it's better to make rules
for tensors that have a different symbol for every dummy pair in the
RHS. Note that

MakeRule[Evaluate[{LHS, ReplaceDummies[wrongRHS]}]]

also doesn't produce a good rule, because ReplaceDummies replaces the
pairs of identical dummies in wrongRHS with a new set of identical
pairs.
Jose, can ReplaceDummies be updated to work as (I) expected in this
case, i.e. treat sums a bit differently? And if updated, should it be
used automatically in MakeRule, or should we let the user worry about
this?

Best,


Teake Nutma

JMM

unread,
Oct 14, 2011, 7:44:58 PM10/14/11
to xAct Tensor Computer Algebra
Hi Teake,

Thanks for the example. There is an issue here, but it is not what you
think it is. The problem is the following:

You start with the expression

S[] S[]

and then apply the rules. However, before the rules are applied,
Mathematica has already transformed that product into

S[]^2

Therefore when you replace S[] by a tensorial expression with indices
you are effectively writing something like T[a,-a]^2, which is
syntactically incorrect because it is equivalent to T[a,-a] T[a,-a].

There is an easy solution for this type of issue: wrap the tensorial
expressions with Scalar. That is, change your wrongRHS to

wrongRHS = Scalar[ T[-a, -b] T[a, b] + T[-a, a] T[-b, b] ]

and then everything should work fine. After performing the
replacement, you can get rid of the Scalar head using NoScalar:

S[] S[] /. wrongRule // NoScalar // Simplification

Concerning your suggestion, having ReplaceDummies in the RHS of a rule
would be redundant: that is precisely what the Module is for.

Cheers,
Jose.

Teake Nutma

unread,
Oct 15, 2011, 3:15:50 AM10/15/11
to xAct Tensor Computer Algebra
Hi Jose,

Thanks for the reply! Let me try to recap what you said:

* The Module in the rule takes care of repeated dummy indices (because
for every replacement it generates a new one).
* This only fails if Mathematica rewrites two tensors as one
expression.
* But this only happens for products of identical scalars, for which
the above problem can be circumvented with a PutScalar.

In my example, an 'good' RHS can also be obtained by doing
NoScalar[PutScalar[wrongRHS]]. I'm guessing this equivalent to keeping
the Scalar head in the rule and getting rid of it after replacement,
right?

There's still one thing that bugs me about this issue, and that's the
fact that Validate doesn't approve of repeated indices on different
tensors, but does of repeated indices on identical tensors:

U[-a, -b, b] + T[b, -b] // Validate (* problem *)
U[-a, -b, b] + U[b, -b, -a] // Validate (* ok *)

Normally I wouldn't write down either one of those two lines, and
would like to see Validate reject them both. Is there a reason why the
last line is accepted?

Cheers,


Teake

Leo Stein

unread,
Oct 15, 2011, 6:13:57 AM10/15/11
to JMM, xAct Tensor Computer Algebra
On a related note, the same type of problem arises with
RicciScalarCD[]^2 // ChangeCurvature
or the old RiemannToChristoffel. This can be fixed by modifying
changeRicciScalar in Sec. 11.1.6, 4c) of xTensor.nb. It would read:
changeRicciScalar[covd1_, covd2_, metricofcovd1_][] :=
Module[{a = DummyIn[TangentBundleOfCovD[covd1]],
b = DummyIn[TangentBundleOfCovD[covd1]]},
Scalar[ Inv[metricofcovd1][a, b] changeRicci[covd1, covd2,
HELLO][-a, -b] ] ];

Best,
Leo

JMM

unread,
Oct 15, 2011, 11:01:07 AM10/15/11
to xAct Tensor Computer Algebra
Hi again Teake,

> Thanks for the reply! Let me try to recap what you said:
>
> * The Module in the rule takes care of repeated dummy indices (because
> for every replacement it generates a new one).

We have to be more precise here. The Module is there to avoid what I
call "dummy collisions": If you start with a syntactically correct
product of two tensors (scalars or not) and you replace both of them
by expressions containing dummy indices then it might happen that you
end up with a tensor product with a repeated pair of dummy, say T[a,-
a] U[a,-a]. That is a dummy collision and must be avoided. The way
this works in xTensor is by producing a new dummy index any time that
a rule dealing with dummies is used. This is done by abusing Module to
produce b$12031 from b, with a different number in each call. Execute
this line in Mathematica:

{ a, a } /. a :> Module[ { b }, b ]

The important thing there is not that we change a to b, but that b has
a different number after the dollar each time the rule is used.

Now, concerning "index repetition", let also try to fix the terms of
the discussion:

1) The expression T[ a, -a ] does not contain repeated indices. The
indices a and -a are different, but they both form a dummy pair.

2) The expression T[ a, -a ] + U[ a, -a ] does not contain repeated
indices, and it is perfectly syntactically correct. Dummies in
different terms of a sum are independent. The danger of collision is
always in the products (and in the powers, which represent products).

3) The expression T[ a, a, b, -b ] contains repeated free indices. It
is syntactically incorrect.

4) The expression T[ a, -a, b ] U[ a, -a, c ] contains repeated dummy
indices (a dummy collision). It is syntactically incorrect.

> * This only fails if Mathematica rewrites two tensors as one
> expression.

I don't understand such very general statement. There is nothing wrong
in Mathematica converting S[] S[] into S[]^2, or S[] + S[] into 2 S[].
Mathematica is an eager evaluator and will try to advance your
computation as much as possible as soon as possible. That is a very
good thing in general, and xTensor follows that principle as well.
However, there is the (unrelated) issue of using rules scalar ->
tensor_with_dummies on products and powers, and there xTensor is
designed so that the user has to decide whether to use Scalar or not.
Perhaps MakeRule or even IndexRule should send a warning message
reporting the fact that such rules might be dangerous in some
scenarios.

> * But this only happens for products of identical scalars, for which
> the above problem can be circumvented with a PutScalar.

Scalar is a general solution to a more general problem. Scalar fully
shields dummies so that the expression Scalar[ v[a] v[-a] ] can be
treated as s[]. Think for example of the expression 1 / (1 + s[] ) and
now try to replace s[] by v[a]v[-a]. Suddenly we find dummies in a
denominator, and that might confuse xTensor quite seriously. Imagine
an operation like (T[b, -a] v[a] ) / ( v[a] v[-a ] ) in which both
numerator and denominator are well defined, but Mathematica is going
to destroy that expression immediately. If you wrap the denominator
with Scalar, then it works fine.

> In my example, an 'good' RHS can also be obtained by doing
> NoScalar[PutScalar[wrongRHS]]. I'm guessing this equivalent to keeping
> the Scalar head in the rule and getting rid of it after replacement,
> right?

Not really. The Scalar head must be there at the moment of using the
rule. That is, PutScalar must be used before using the rule and
NoScalar must be used after using the rule. If you are telling me that
both PutScalar and NoScalar are in the delayed RHS of the rule (i.e.
inside the Module) then it might also work, but it is unnecessarily
complicated.

> There's still one thing that bugs me about this issue, and that's the
> fact that Validate doesn't approve of repeated indices on different
> tensors, but does of repeated indices on identical tensors:
>
> U[-a, -b, b]  + T[b, -b] // Validate (* problem *)

Isn't this a problem because the free indices are inhomogeneous? I
mean, change T[b,-b] to T[b,-b,-a] and it should work, as I said
above. Are you working with any graded algebra allowing addition of
tensors of different ranks? xTensor does not support such a thing.

> U[-a, -b, b]  + U[b, -b, -a] // Validate (* ok *)
>
> Normally I wouldn't write down either one of those two lines, and
> would like to see Validate reject them both. Is there a reason why the
> last line is accepted?

The last line is perfectly OK, assuming your vector space has a
metric. Sums are never a problem with dummies.

Cheers,
Jose.

JMM

unread,
Oct 15, 2011, 11:07:55 AM10/15/11
to xAct Tensor Computer Algebra
Thanks Leo,

Yes. This is a good example of a rule scalar_without_indices :>
scalar_with_indices, and needs Scalar on the RHS to make it safe in
all scenarios.

Will be fixed in the next version.

Thanks again,
Jose.

Teake Nutma

unread,
Oct 15, 2011, 11:54:25 AM10/15/11
to xAct Tensor Computer Algebra
Hi Jose,

Thanks for the clarifications.

> However, there is the (unrelated) issue of using rules scalar ->
> tensor_with_dummies on products and powers, and there xTensor is
> designed so that the user has to decide whether to use Scalar or not.
> Perhaps MakeRule or even IndexRule should send a warning message
> reporting the fact that such rules might be dangerous in some
> scenarios.

A warning would be nice, that would have saved me some trouble. But
why not be on the safe side and automatically put a Scalar in
MakeRule[{lhs_without_indices,rhs_with_indices}]?

>> U[-a, -b, b]  + T[b, -b] // Validate (* problem *)
>
> Isn't this a problem because the free indices are inhomogeneous?

Yes, that was a typo. Doh.
Btw, my solution to this problem was

MakeRule[Evaluate[{
lhs_without_indices,
rhs_with_indices /. x_Plus :> ReplaceDummies /@ x
}]

and it seems to work fine. But I guess the PutScalar / NoScalar is a
bit more elegant.
Cheers,

Teake

JMM

unread,
Oct 15, 2011, 12:55:14 PM10/15/11
to xAct Tensor Computer Algebra
> A warning would be nice, that would have saved me some trouble. But
> why not be on the safe side and automatically put a Scalar in
> MakeRule[{lhs_without_indices,rhs_with_indices}]?

That is not the only case in which Scalar is needed. I have mentioned
problems with denominators. Imagine you are working with logarithms of
scalars and at some point you want to convert the sum of logarithms
into a logarithm of the product. Again you might run into dummy
collisions. Think of any expression of the form function[ scalar ] and
now you differentiate it with your own derivative operator using the
chain rule. More possible dummy collisions. There are many different
cases in which Scalar could be needed. It is impossible that MakeRule
is able to detect all of them and introduce Scalar where it is needed.
I never like partial solutions to problems, because they are
misleading. "Use Scalar wherever needed" is a general solution.

> Btw, my solution to this problem was
>
> MakeRule[Evaluate[{
>   lhs_without_indices,
>   rhs_with_indices /. x_Plus :> ReplaceDummies /@ x
>
> }]
>
> and it seems to work fine. But I guess the PutScalar / NoScalar is a
> bit more elegant.

It is not a general solution because it only works if the RHS contains
Plus. As I said, the problem is not related to Plus. Think of this
example:

S[]^2 /. MakeRule[ { S[], T[a,-a] } }

Cheers,
Jose.

Teake Nutma

unread,
Oct 15, 2011, 2:35:07 PM10/15/11
to xAct Tensor Computer Algebra
> I never like partial solutions to problems, because they are
> misleading. "Use Scalar wherever needed" is a general solution.

Point taken. But then the user must know he needs to use Scalar :).

> Think of this example:
>
> S[]^2 /. MakeRule[ { S[], T[a,-a] } }

Hmm, this example just works for me (using Simplification on the
result gives it a Scalar). Hence I discarded a similar expression when
tracing the source of my original problem, which put me onto the path
of expressions with Plus'es.
Cheers,

Teake

JMM

unread,
Oct 15, 2011, 3:11:23 PM10/15/11
to xAct Tensor Computer Algebra
> > S[]^2 /. MakeRule[ { S[], T[a,-a] } }
>
> Hmm, this example just works for me (using Simplification on the
> result gives it a Scalar). Hence I discarded a similar expression when
> tracing the source of my original problem, which put me onto the path
> of expressions with Plus'es.

I see. ToCanonical takes the liberty to put Scalar in simple cases
that are obviously wrong though still with a "more or less" uniquely
defined meaning. But again, ToCanonical does not (it cannot) fix all
wrong cases. This is another partial solution and was misleading you.
The point I was trying to make with that example is that right after
applying the rule the result is syntactically incorrect. Now you add a
ToCanonical at the end: With T[a,-a]^2 ToCanonical decides to fix the
expression by changing it to Scalar[ T[a,-a] ]^2, but if you have a
sum ToCanonical complains instead, because it does not want to lose
time analyzing a potentially large sum of objects. This is certainly
inconsistent behaviour, but only happening on incorrect inputs anyway.

Thanks,
Jose.

Leo Stein

unread,
Oct 15, 2011, 7:19:03 PM10/15/11
to JMM, xAct Tensor Computer Algebra
I had no idea that ToCanonical did this. It sounds quite dangerous!
As an example, what if you instead had the expression
expr = T[a,-b] T[b,-a]
... later ...
expr /. b->a // ToCanonical
This is a bit contrived, since the indices are being manually
manipulated; nonetheless, the expression
T[a,-a] T[a,-a]
can be interpreted as having arisen in two erroneous ways. One way is
the sum of the squares, and the second is the square of the sum, so to
speak.

JMM

unread,
Oct 15, 2011, 8:55:53 PM10/15/11
to xAct Tensor Computer Algebra
Yes, that is precisely what I meant by "more or less" in my previous
email. I can imagine easily replacing S[] by T[a,-a] in S[]^2, but
your example is really a forced error. Indices should never be changed
like that. Free indices must be replaced using a product with the
delta, and dummy indices must be replaced using ReplaceDummies. In any
case, T[a,-a]^2 is syntactically incorrect in xTensor, and once that
expression has appeared the result could be very wrong. Garbage in,
garbage out. I see nothing wrong in that.

Perhaps your suggestion is that ToCanonical should complain if it
finds T[a,-a]^2. I might agree with that. But should it complain if it
finds Log[ T[a,-a] ] or actually any other scalar-function on a
scalar? I don't think so. My opinion here is that users must decide
when to put Scalar and when to remove it.

Cheers,
Jose.

On Oct 15, 6:19 pm, Leo Stein <leo.st...@gmail.com> wrote:
> I had no idea that ToCanonical did this. It sounds quite dangerous!
> As an example, what if you instead had the expression
>   expr = T[a,-b] T[b,-a]
>   ... later ...
>   expr /. b->a // ToCanonical
> This is a bit contrived, since the indices are being manually
> manipulated; nonetheless, the expression
>   T[a,-a] T[a,-a]
> can be interpreted as having arisen in two erroneous ways. One way is
> the sum of the squares, and the second is the square of the sum, so to
> speak.
>
Reply all
Reply to author
Forward
0 new messages