On MakeRule

186 views
Skip to first unread message

user657

unread,
Oct 18, 2018, 12:53:30 AM10/18/18
to xAct Tensor Computer Algebra
Dear all,

I have a question related to using MakeRule.

Suppose I have defined 3 scalars: A, B and C. After this, I do some symbolic tensor calculations with these scalars (and possibly some other tensors, with covariant/partial derivatives). The end result, suppose, is A[] - PD[-a]@PD[a]B.

Question: I want to replace the occurrence of every expression A[] - PD[-a]@PD[a]B by C. How could I achieve that using MakeRule, or perhaps something else?

I tried MakeRule[{A[] - PD[-a]@PD[a]B, C[]}, MetricOn -> All, ContractMetrics -> True] which gives me an error: MakeRule::terms: There is more than one term on the LHS of rule. It seems like I can replace the occurrence of a single term by a linear combination of multiple terms, but not vice versa.

Thank you for your help.

Jose

unread,
Oct 20, 2018, 10:07:56 PM10/20/18
to xAct Tensor Computer Algebra
Hi,

MakeRule is not prepared to handle a sum of terms on the lhs of the rules.

Can you do A[] -> C[] + PD[-a][PD[a][B[]]] instead? MakeRule can handle that.

If not, then you will need a manual rule like

rule = A[] - PD[a_][PD[b_][B[]]] -> C[] /; PairQ[a, b]

Note that this rule only matches the exact expression on the left. If you have something like 2 A[] - 2 PD[-a][...] then you will not get 2 C[]. If such a thing is also needed then the rule will get more complicated. If you can use the rule A[] -> ... things would be easier, and it would be able to handle linear combinations.

Cheers,
Jose.

user657

unread,
Oct 21, 2018, 8:09:00 PM10/21/18
to xAct Tensor Computer Algebra
Dear Jose,

Thank you for your reply and suggestions.

A[] -> C[]... will not work for me. There will be terms exactly in the form of a particular linear combination. And you got it right, that expression can occur as multiples too, so the rule will get complicated as you said. If there is still a reasonably simple way to implement it, that would be great. But it's not too bad if the rule is too convoluted; the linear combination would not be very hard to identify from my final expressions, and I could just manually read them off.

Thank you for your time.

Jose

unread,
Oct 21, 2018, 9:44:40 PM10/21/18
to xAct Tensor Computer Algebra
Then I would try something like

rule = p_. A[] + q_. PD[a_][PD[b_][B[]]] :> p C[] /; q == -p && PairQ[a, b]

The use of _. instead of just _ is needed to include the case of 1. The use of PairQ is assuming that the metric has zero PD-derivative. If that's not the case, you need to hardwire the only combination possible, say

rule = p_. A[] + q_. PD[-a_][PD[a_][B[]]] :> p C[] /; q == -p

Still, I don't know what you want to do with a case like 2 A[] - 3 PD[-a][PD[a][B[]]].

Cheers,
Jose.

user657

unread,
Oct 23, 2018, 2:33:41 PM10/23/18
to xAct Tensor Computer Algebra
Dear Jose,

Thank you very much for your reply. Yes, that works! 

I know that terms like 2 A[] - 3 PD[-a][PD[a][B[]]] will not occur in the final expression after implementing ToCanonical, ContractMetric, SortCovDsToDiv, etc. But they might come up inside derivatives. For example, when looking for C[] where it's defined as: C[] = A[] - PD[-a]@PD[a]@B[], there might be terms in my final expression like 
PD[-b]@PD[b]@A[] - PD[-b]@PD[b]@PD[-a]@PD[a]@B[]. I tried "collecting" the PD[-b]@PD[b] part so that implementing your rule would give me PD[-b]@PD[b] C[], but it doesn't work. Is there a way to "collect" derivatives. This exhausts the possibilities C[] can occur in: either in multiples, or inside derivatives. Also, the derivatives will always be covariant. In the rule you showed me previously, replacing PD with CD works well.

Thank you for your help.

Jose

unread,
Oct 27, 2018, 12:33:08 PM10/27/18
to xAct Tensor Computer Algebra
There are no "derivative collect" commands in xTensor. Derivatives thread automatically over sums, like D itself does, so any collection operation would be immediately undone by the collected derivative operator, unless we inserted some Hold or Inactive wrapper.

If you know that your problem only has first and second order derivatives, say, then the simplest (and fastest) thing to do here is to write separate rules for first and second order derivatives of your original rule.

But let us suppose that your problem involves very high derivative orders, and you don't want to write separate rules. Then you could do the following. I will simplify your problem, for the sake of clarity. Start with a basic setup:

<< xAct`xTensor`

DefManifold[M, 4, {a, b, c, d, e, f}]

DefMetric[-1, g[-a, -b], CD]

DefTensor[A[], M]
DefTensor[B[], M]
DefTensor[F[], M]

Imagine that you want to replace A[] + B[] -> F[] inside an expression that contains high order derivatives of A[] and B[].

Define this recursive function:

LinearCollect[expr_, patt_, rule_] := Quiet[Module[{p}, 
   expr /. ((p: patt)[expr1_] + (p: patt)[expr2_] :> p[LinearCollect[expr1 + expr2, patt, rule]]) /. rule
]]

Take for example the expression:

expr = PD[-a][PD[-b][A[]]] + PD[-a][PD[-b][B[]]]

Then we can do this:

In[]:= LinearCollect[expr, PD[_], A[] + B[] -> F[]]
Out[]= PD[-a][PD[-b][F[]]]

The second argument specifies the head pattern you want to collect, and the third argument specifies the internal rule you want to apply. The pattern should not have names inside (i.e. do not use PD[a_]).

The key point in the construction is to use a pattern name p to make sure that we are collecting the exact same pattern, including index names. For example this does not work:

expr = PD[-a][PD[-b][A[]]] + PD[-b][PD[-a][B[]]]

In[]:= LinearCollect[expr, PD[_], A[] + B[] -> F[]]
Out[]= PD[-a][PD[-b][A[]]] + PD[-b][PD[-a][B[]]]

because the indices of the two double derivatives are sorted differently.

Cheers,
Jose.

user657

unread,
Oct 31, 2018, 4:41:53 PM10/31/18
to xAct Tensor Computer Algebra
Dear Jose,

Great, thank you very much, that works quite well for me.
Reply all
Reply to author
Forward
0 new messages