# Getting two terms with derivatives to form a product

+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.

Many Thanks GPN

edited

+1 vote

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 (12.5k 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 (1.2k points)