# Using Cadabra and Sympy together

This notebook illustrates the interaction of Cadabra with Sympy. In particular, it shows how Cadabra expressions can be manipulated by Sympy if they are index-free (i.e. non-tensors).## Scalar expression handling

While Cadabra's main strength is its handling of tensorial expressions, you can of course write down scalar expressions as well. Here is a simple example:ex:=(\sin(x)**2 + \cos(x)**2)/x;

\(\displaystyle{}\left({\left(\sin{x}\right)}^{2}+{\left(\cos{x}\right)}^{2}\right) {x}^{-1}\)

((\sin(x))**2 + (\cos(x))**2) (x)**(-1)

Note the use of LaTeX notation for things like trigonometric functions.
You can then directly call Sympy algorithms on these Cadabra expressions, for instance
to integrate them:

map_sympy(_, "integrate");

\(\displaystyle{}\log\left(x\right)\)

\log(x)

Note how, in the spirit of Cadabra's logic that algorithms act in-place, this changes the actual expression:

`ex`

now contains
the integral of the original expression:ex;

\(\displaystyle{}\log\left(x\right)\)

\log(x)

You can do more complicated things as well, like integrals and sums. Here is an example which is
first entered in Cadabra form (which is inert), and then fed through Sympy, which then immediately evaluates the
expression. Again note the use of
standard LaTeX-like constructions to write down integrals.

ex2:= \int{\sin(x) \cos(x)}{x};

\(\displaystyle{}\int \sin{x} \cos{x}\,\,{\rm d}x\)

\int{\sin(x) \cos(x)}{x}

map_sympy(_);

\(\displaystyle{}\frac{1}{2}{\left(\sin{x}\right)}^{2}\)

1/2 (\sin(x))**2

Note how

`map_sympy`

was used without giving it any Sympy function. This simply makes Sympy evaluate the expression, which in this case
means evaluating the integral.Note that

`map_sympy`

is almost always the way in which you want to invoke Sympy. You can, alternatively, feed expressions directly into
Sympy functions (by virtue of the fact that `Ex`

objects have a `_sympy_()`

method),
but that has the disadvantage that you will not change the original expression (it will not act in-place):ex3:= \sin(x)\cos(x);

\(\displaystyle{}\sin{x} \cos{x}\)

\sin(x) \cos(x)

ex3._sympy_();
print(type(ex3._sympy_()))

\(\displaystyle{}\sin{\left(x \right)} \cos{\left(x \right)}\)

<class 'sympy.core.mul.Mul'>

sympy.integrate(ex3);
print(type(sympy.integrate(ex3)))

\(\displaystyle{}\frac{\sin^{2}{\left(x \right)}}{2}\)

<class 'sympy.core.mul.Mul'>

Observe how the result of these evaluations are non-Cadabra objects (they have not been converted back, the way in which

`map_sympy`

does).The fact that algorithms act in-place may sometimes be a bit unexpected. Here's an example of solving a cubic equation to make this clear:

ex4:= x**3 - x**2 - 4;

\(\displaystyle{}{x}^{3}-{x}^{2}-4\)

(x)**3-(x)**2-4

map_sympy(_, "solve");

\(\displaystyle{}\left[2, - \frac{1}{2} - \frac{1}{2}\sqrt{7} I, - \frac{1}{2}+\frac{1}{2}\sqrt{7} I\right]\)

{2, - 1/2 - 1/2 \sqrt(7) I, - 1/2 + 1/2 \sqrt(7) I}

ex4;

\(\displaystyle{}\left[2, - \frac{1}{2} - \frac{1}{2}\sqrt{7} I, - \frac{1}{2}+\frac{1}{2}\sqrt{7} I\right]\)

{2, - 1/2 - 1/2 \sqrt(7) I, - 1/2 + 1/2 \sqrt(7) I}

## Tensor expression handling

The real power of mixing Cadabra with Sympy lies in the fact that you can act with Sympy on any Cadabra subexpression which is a pure scalar (i.e. which has no indices). Here is a contrived example which has a sum of tensors, with pre-factors which are scalar expressions which Sympy can simplify.{r,t}::Coordinate;
\partial{#}::PartialDerivative;
ex:= (\sin(r)**2 + \cos(r)**2) A_{m} \partial_{r}{r} - A_{m} + \int{r**2}{r} B_{m};

\(\displaystyle{}\text{Attached property Coordinate to }\left[r, t\right].\)

\(\displaystyle{}\text{Attached property PartialDerivative to }\partial{\#}.\)

\(\displaystyle{}\left({\left(\sin{r}\right)}^{2}+{\left(\cos{r}\right)}^{2}\right) A_{m} \partial_{r}{r}-A_{m}+\int {r}^{2}\,\,{\rm d}r B_{m}\)

((\sin(r))**2 + (\cos(r))**2) A_{m} \partial_{r}(r)-A_{m} + \int{(r)**2}{r} B_{m}

map_sympy(_, "simplify");

\(\displaystyle{}\frac{1}{3}{r}^{3} B_{m}\)

1/3 (r)**3 B_{m}

{r,t}::Coordinate;
{\mu,\nu}::Indices(values={r,t});
ex:= \partial_{\mu}{ A^{\mu \nu} };
rl:= A^{t t} -> t \sin(r)**2, A^{r r} -> \int{\cos{r}**2}{r};

\(\displaystyle{}\text{Attached property Coordinate to }\left[r, t\right].\)

\(\displaystyle{}\text{Attached property Indices(position=free) to }\left[\mu, \nu\right].\)

\(\displaystyle{}\partial_{\mu}{A^{\mu \nu}}\)

\partial_{\mu}(A^{\mu \nu})

\(\displaystyle{}\left[A^{t t} \rightarrow t {\left(\sin{r}\right)}^{2}, A^{r r} \rightarrow \int {\left(\cos{r}\right)}^{2}\,\,{\rm d}r\right]\)

{A^{t t} -> t (\sin(r))**2, A^{r r} -> \int{(\cos(r))**2}{r}}

evaluate(ex, rl);

\(\displaystyle{}\square{}^{\nu}\left\{\begin{aligned}\square{}^{r}& = {\left(\cos{r}\right)}^{2}\\[-.5ex]
\square{}^{t}& = {\left(\sin{r}\right)}^{2}\\[-.5ex]
\end{aligned}\right.
\)

\components^{\nu}({{r} = (\cos(r))**2, {t} = (\sin(r))**2})

## Sympy only with sympy notation throughout

Of course, if you do not like or need Cadabra's input format, then you can happily use Sympy in the way you have always used it, but taking advantage of the display logic of the Cadabra notebook:from sympy import *
x,y=var('x,y')
i = Integral(sin(x),(x,0,2));

\(\displaystyle{}\int\limits_{0}^{2} \sin{\left(x \right)}\, dx\)

i.doit();

\(\displaystyle{}1 - \cos{\left(2 \right)}\)

Hope this has triggered your interest; as usual, any feedback to mailto:info@cadabra.science is greatly appreciated.