Cadabra
a field-theory motivated approach to computer algebra

Using SymPy on Cadabra expressions

While Cadabra contains a large number of function for expression manipulation, there are many things for which it does not attempt to re-invent the wheel, and calls into SymPy instead. If you want to write functions which manipulate Cadabra expressions and call SymPy functionality on them yourself, you need to know how to export expressions to SymPy form, and read them back once it has done processing. This is somewhat non-trivial, because Cadabra's notation allows for much more general expressions than SymPy. Think of LaTeX expressions, super- and sub-scripts but also objects which depend implicitly on other variables. These things all need converting to something which SymPy can handle, and converting back once SymPy has produced a result.
The main object to deal with this conversion is SympyBridge. This object takes the expression you want to share with SymPy. Let us start with a non-trivial Cadabra expression,
\partial{#}::PartialDerivative; t::Coordinate; x::Depends(t);
\(\displaystyle{}\text{Property PartialDerivative attached to }\backslash\texttt{partial}\{\#\}.\)
\(\displaystyle{}\text{Property Coordinate attached to }t.\)
\(\displaystyle{}\text{Property Depends attached to }x.\)
ex:= \sin(x)**2 + \cos(x)**2 + \partial_{t}{x};
\(\displaystyle{}{\left(\sin{x}\right)}^{2\,} +{\left(\cos{x}\right)}^{2\,} +\partial_{t}{x}\)
The above expression contains \sin and \cos (which SymPy does not understand) and it also contains a variable $x$ which implicitly depends on $t$ (the dependence is not shown in the output). In order to be able to feed this into SymPy, and get it back later, we create a SympyBridge object, passing it the expression:
sb = SympyBridge(ex);
<cadabra2.SympyBridge object at 0xe74381340c70>
In order to retrieve the SymPy object, use the to_sympy() function,
ex_sympy = sb.to_sympy() print(type(ex_sympy))
<class 'sympy.core.add.Add'>
As you can see, the expression is now a SymPy object. If you print it, you will note that Cadabra has converted the LaTeX symbols \sin and \cos to something SymPy understands, and it has also written out the implicit dependence on the $t$ variable,
print(ex_sympy)
sin(x(t))**2 + cos(x(t))**2 + Derivative(x(t), t)
You can now manipulate this expression as you want, using standard SymPy functionality. Let's simplify this,
res = sympy.simplify( ex_sympy ); print(type(res))
\(\displaystyle{}\frac{d}{d t} x{\left(t \right)} + 1\)
<class 'sympy.core.add.Add'>
This is of course still a SymPy expression. We can pull it back into Cadabra by using the SympyBridge again,
sb.from_sympy( res );
None
This does not return a new expression (the return value is None), but instead puts the SymPy expression back into the original Cadabra expression that we started with when we constructed the bridge; here that is ex. Indeed,
ex;
\(\displaystyle{}\partial_{t}{x} +1\)
Note how this has nicely removed the explicit dependence on $t$ and turned it back into an implicit notation, writing just $x$ and not $x(t)$.
Copyright © 2001-2025 Kasper Peeters
Questions? info@cadabra.science