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

Hi Folks,

The following code does its job nicely (to fully expand the sum)

{a,b,c}::Indices(position=fixed,values={x,y,z}).
{x,y,z}::Coordinate.
ex := A_{a} B^{a};
rl1 := {A_{x}=Ax,A_{y}=Ay,A_{z}=Az};
rl2 := {B^{x}=Bx,B^{y}=By,B^{z}=Bz};
evaluate(ex,rl1+rl2,rhsonly=True);

My intention is to feed the final expression to the sympy printer and codegen packages to produce C code for inclusion in other C codes. For the above example that would be trivial. But if I had some messy expression in the Riemann tensor (which has 256 components in 4 dimensions) the rules that map components like R_{x y x y} to Rxyxy (as an example) would become extremely tedious to write out (and error prone).

Is there a simple way to avoid having to list every component in the rules? I've tried using

rl1 := A_{a?}->A_{a?};
rl2 := B^{a?}->B^{a?};

but Cadabra complains "substitute: Argument is neither a replacement rule nor an equality".

Any suggestions?

Cheers, Leo

in Bug reports by

1 Answer

0 votes
 
Best answer

At the moment the answer is no, as we are still trying to figure out what's the best way to do this internally. It is high on the priority list though.

As a totally ugly workaround (really only meant if you need to get this done yesterday) you can generate those replacement rules programmatically using

str=[]
for a in ["x","y","z"]:
   str.append("A_{"+a+"} = A"+a)
   str.append("B^{"+a+"} = B"+a)  
rl = Ex(','.join(str));

(which builds them as a string and then creates a Cadabra expression from that string), but that of course defeats most of the purpose of Cadabra... Does serve as a nice example that you can use Python to hack your way around deficiencies in Cadabra...

by (76.7k points)

Hi Kasper, Thanks so much for the quick answer and the workaround. Cheers, Leo

In general, the reason why we don't simply do things the brute force way (writing out all 256 components in the example you mention) is that often you want to still restrict to some form of ansatz for the building block tensors. In your case, you probably have a metric ansatz, and want to write out the Riemann tensor components in terms of the functions appearing in that ansatz. So the system should e.g. allow for setting the g_{t i} components (with i spacelike) to zero, while keeping the g_{t t} and all space-space components. So you need some kind of rules which deal in a flexible way with index splits. This takes a bit of time to design properly.

That's correct. I would be reducing the messy Riemann calculations down to the metric so that would make my job somewhat easier. I mentioned the Riemann case only as a way to emphasise the point (that all non-zero terms need to be specified).

...