Welcome to Cadabra Q&A, where you can ask questions and receive answers from other members of the community.
+1 vote

Hello

I'm running the following:

{a#,b#}::Indices.
\delta{#}::KroneckerDelta.
{a#,b#}::Integer(0..3)
\partial{#}::PartialDerivative.
\epsilon{#}::EpsilonTensor(delta=-\delta).
h_{a1 b1}::Symmetric.
toh := {h_{a1 a1} = h, h_{a1}^{a1} = h}.
def LLmanip(ex):
    product_rule(ex) 
    distribute(ex)
    product_rule(ex)
    distribute(ex)
    epsilon_to_delta(ex)
    expand_delta(ex)
    distribute(ex)
    eliminate_kronecker(ex)
    canonicalise(ex)
    rename_dummies(ex)
    distribute(ex) 
    sort_product(ex)
    sort_sum(ex)
    substitute(ex, toh)
    lower_free_indices(ex)
    canonicalise(ex)
    rename_dummies(ex)
    collect_factors(ex)
    return(ex)

LL := \delta^{a1 b1 a2 b2 a3 b3 a4 b4} \partial_{a1}{h_{a2 b2}} \partial_{b1}{h_{a3 b3}} h_{a4 b4};
LLmanip(LL);

The result i get has these two terms:

\partial_{a1}{h_{a1 a2}} \partial_{a2}{h} h

and

\partial_{a1}{h} \partial_{a2}{h_{a1 a2}} h

which are the same but are not collected into one.

Is there some way to combine the terms?

Thanks

in General questions by (160 points)

2 Answers

+1 vote
 
Best answer

Use sort_product(LL) to get factors in the same order.

by (83.1k points)
selected by

Thanks!

it was sort_product and canonicalise that were missing in my function.

0 votes

Hi alonli!

The notation you're using makes me think that you've read our article. If so, thank you very much! It is awesome to note that our work benefits other researchers.

Now, I understand that what you're providing in the question is (probably) a simple example of what you really want to do. However, there are many manipulations that are doing nothing (including the indiscriminate use of the algorithm canonicalise, which is slow because it tries many "simplification" algorithms).

I came out with a shorter list of algorithms that work better in your example (you might have to modify it to fit your necessities):

{a#,b#}::Indices.
\delta{#}::KroneckerDelta.
{a#,b#}::Integer(0..3)
\partial{#}::PartialDerivative.
\epsilon{#}::EpsilonTensor(delta=-\delta).
h_{a1 b1}::Symmetric.
toh := {h_{a1 a1} = h, h_{a1}^{a1} = h}.

def LLmanip(ex):
    expand_delta(ex)
    distribute(ex)
    eliminate_kronecker(ex)
    substitute(ex, toh)
    sort_product(ex)
    rename_dummies(ex)
    lower_free_indices(ex)
    meld(ex)
    rename_dummies(ex)
    return ex

LL := \delta^{a1 b1 a2 b2 a3 b3 a4 b4} \partial_{a1}{h_{a2 b2}} \partial_{b1}{h_{a3 b3}} h_{a4 b4};
LLmanip(LL);

I want to drive your attention to the single use of the algorithm meld intead of several canonicalise, single sort_product and rename_dummies, and the lack of the sort_sum (perhaps you might still want it there).

I know that it is useful to define functions for general purpose manipulations, but it is important to keep them "optimal", because once your expressions start to get a bit complex, the functions become very time consuming.

Cheers, Dox.

by (15.1k points)
...