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

Within the documentation the function converge looks like a python function.

Is it possible to define python functions within Cadabra? How? I've tried but it didn't work.

in General questions by (15.0k points)

2 Answers

+1 vote
 
Best answer

Yes, Cadabra input cells can contain any normal Python code, and you can use Python functions to act on Cadabra expressions. You can see a simple example at the very bottom of http://cadabra.science/notebooks/for_previous_users.html. You can also access elements of a Cadabra expression, like

ex:= A + B; ex[1];

(For completeness: the converge operator is an extension provided by Cadabra, and gets translated from

converge(ex):
     do_something(ex)

to

ex.reset()
while(ex.changed()):
     do_something(ex)

before it is fed to Python. Under normal circumstances you should not have to worry about this).

by (82.6k points)
selected by

Very useful examples, but I was thinking more in something like a function definition with def foo(): something; return 3*something Is this possible?

Sure,

def foo():
    ex:= 3 A_{m n} A^{m n};
    return ex

After which you can do e.g.

substitute( foo(), $ A_{m n} -> B_{m n} $);

Note that in order to be able to write maths in a Python function, you can't just do

return 3 A_{m n} A^{m n};

but you have to first declare an expression ('ex' in the example above) using the standard ':=' Cadabra assignment operator.

0 votes

I wanted to present an example of the use of Python functions within Cadabra.

First I define my (Cadabra) variables, a rule of substitution, and a post_process algorithm

{a,b}::NonCommuting.
{a,b}::Distributable.
{b}::SelfAntiCommuting.
rl := b * b = 0;
def post_process(ex):
    substitute( distribute( expand_power(ex) ), rl)

Then, I proceed to calculate my expression

expr := (a + b) ** 7;

(I don't know how to show the output here! Sorry for that)

Say that I want to manipulate the terms in this expression as python strings. I would like to know first if the expression can be translated to a python string, and

str(expr);

does the job... but not in a useful form.

Therefore, I would like to remove the asterisks (*) of multiplication, and separate the terms into monomials,

mylist = str(expr).replace("*", "").split('+')
mylist;

Well, then you can use it as you wish!

Until this point, we have used python functions, but we haven't defined our own. Say then that we want to compare terms on our list, and know if these are related through a circular transformation (or cyclic transformation). We define our function

def isCircular(arr1, arr2):
    return arr1 in arr2*2

and compare

isCircular( mylist[1], mylist[3]);
isCircular( mylist[0], mylist[1]);

Cheers.

by (15.0k points)
...