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

Sorry for the newbie question, I actually did carefully read the doc and do some of the tutorials, but haven't found the probably obvious answer.

I have an expression with two partial derivative terms and some other terms, of the form

R = dA + B + A * (G^(-1) dG) + C

Of course I would like it to simplify to

R = G^(-1) d(GA) + B + C

I tried collect_terms but no luck, the above expression remains unchanged.

Note that the above is simplified, in the actual problem the A,B,C also have indices.

Any advice please?

Many Thanks GPN

in General questions by (2.0k points)
edited by

2 Answers

+1 vote
 
Best answer

Hi GPN,

Thanks for sharing your doubts and ideas. I found your solution very useful, and it inspired me to try a different approach.

My solutions uses the algorithm isolate from the library manip, so the notebook starts like:

import cdb.core.manip as manip

Then, I modify your approach (in particular the notation of the inverse, and taking care of the space between the operators A and G):

\partial{#}::PartialDerivative.
ex := \partial{A} + B + A  (G**(-1) \partial{G}) + C.
sort_product(ex);

The algorithm sort_product will ensure the same order of the factors (the usefulness wuold be seen shortly.

Then, I define the contracted expression

contracted := G**(-1) \partial{(G A)};

and the expanded one. Following your idea, I manipulate the expanded expression and define a substitution rule

expanded := @(contracted);
product_rule(expanded)
distribute(expanded)
collect_factors(expanded)
sort_product(expanded)
contraction_rule := @(expanded) = @(contracted);

Note the appearance of sort_product again. Since the desired expression to substitute is not isolated on the left-hand-side of the substitution rule, we use isolate to isolate it:

manip.isolate(contraction_rule, $A \partial{G} G**(-1)$);

And finally we use the contraction_rule on the original expression ex:

substitute(ex, contraction_rule);

Hope you find this aproach useful! Dox.

by (15.0k points)
selected by

Nice! More accurate code, better than mine. Thanks.

+1 vote

I actually managed to figure this out (it was a good exercise). Basically, what I did is below. I hope it helps someone.

The below is pseudo-code.

\partial{#}::PartialDerivative.
ex := \partial{A} + B + A  (G^(-1) \partial{G}) + C

\# define a contraction rule
from copy import *
contracted := G^(-1) \partial{(GA)}.
expanded = deepcopy(contracted)
product_rule(expanded)
distribute(expanded)
collect_factors(expanded)
contraction_rule := @(expanded) -> @(contracted);

\# now use the rule
substitute(ex, contraction_rule);

Good luck!

by (2.0k points)
...