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

Hi,

I want to do a diffrentiation w.r.t r variable of a particular expression, which i am typing below. Unfortunately i am getting some problem in the expressions. below is my code

def post_process(ex): sort_product(ex) canonicalise(ex) collect_terms(ex)

{u,r,z1,z2}::Coordinate; {a,b,c,d,e,f,g,h,i,j,k,l,m,n#}::Indices(values={z1,z2}, position=fixed);

q{a b}::Metric; q^{a b}::InverseMetric; A1{a}::Depends(u,z1,z2); A2{a}::Depends(u,z1,z2); A{a}::Depends(u,r,z1,z2); B1{a}::Depends(u,z1,z2); B2{a}::Depends(u,z1,z2); B_{a}::Depends(u,r,z1,z2);

aexp:=A{a}=((A1{a})/r) + ((A2{a})/r**2); bexp:=B{a}=((B1{a})/r) + ((B2{a})/r**2); S:=A{a} B{a};

substitute(S,aexp); substitute(_,bexp); distribute(S); collectfactors(); S*($r**4$); distribute(_); collectfactors(); diff(_,$r$);

after this i am getting an output as

$2rA{1}(DNa)B{1}(DNa)+A{1}(DNa)B{2}(DNa)+A{2}(DNa)B{1}(DNa)$

I was expecting to get

$2rA1{a}B1{a}+A1{a}B2{a}+A2{a}B1{a}$

Is this just a display issue or am i doing something wrong?

in General questions by (630 points)

1 Answer

+2 votes
 
Best answer

First an explanation of what happens here (feel free to skip): When you call diff, what you are actually doing is calling a Sympy function. In order for Sympy to act on your Cadabra expression, it will convert it to a Sympy object by calling S._sympy_(). However, that will produce a version of your expression in which tensor indices are replaced with DN+name or UP+name depending on the position. Once the diff function completes, it returns a Sympy expression, which then stays that way; it does not magically become a Cadabra Ex expression again.

So you need to define your own diff, which converts the Cadabra expression to Sympy form, applies the Sympy function, and then converts back to a Cadabra expression. That's easy,

def diff(ex1, ex2):
   ret = $@(ex1)$
   sb = SympyBridge(ret)
   sb.from_sympy( str(sympy.diff( sb.to_sympy(), ex2 ) ) )
   return ret

Then this works:

ex := A_{a}(r) r;
diff( ex, $r$ )

which produces a new Cadabra expression

$$r \partial_{r}( A_{a}(r) ) + A_{a}(r)$$

Final note: yes, functions like that really should be part of the cdb.sympy package. Lack of time...

by (64.9k points)
selected by

thank you very much.. this was really helpful.

...