a field-theory motivated approach to computer algebra

Introduction to Cadabra for beginners

This notebook introduces Cadabra to people who have never used it before, or who have used one of the old 1.x versions. It will show you how to enter expressions, attach properties to patterns, perform simple substitutions and so on. If you need help, do not hesitate to email or visit the web site at

Equations of motion

A good example to illustrate a number of Cadabra manipulations is to derive the equations of motion of a field theory from an action. Below we discuss the Maxwell equations, just for simplicity. In Cadabra, the default setting is to do very little automatic simplification (essentially, only equal terms are collected). You can change this, however, by writing a post_process function which contains all the algorithms which you want to run at every step of your notebook. Below is an example:
def post_process(ex): sort_product(ex) canonicalise(ex) collect_terms(ex)
As you can see, this sorts factors in a product (alphabetically, you can change this if you want), then writes indices in canonical form, and collects equal terms. Before we can enter our Maxwell action, we need to declare some properties of the symbols which we want to use. Cadabra is fairly minimalistic with this; you typically only have to declare what you are going to use. Below we declare that $\mu$, $\nu$, $\rho$ are indices, $x$ is a coordinate label, and \partial indicates a partial derivative. We then declare properties of the field strength and the gauge potential. This should all read fairly naturally.
{\mu,\nu,\rho}::Indices(position=free). x::Coordinate. \partial{#}::Derivative. F_{\mu\nu}::AntiSymmetric; F_{\mu\nu}::Depends(x). A_{\mu}::Depends(x,\partial{#}). \delta{#}::Accent;
\(\displaystyle{}\text{Attached property AntiSymmetric to }F_{\mu \nu}.\)
\(\displaystyle{}\text{Attached property Accent to }\delta{\#}.\)
Note how lines ending in a semi-colon get their output printed, while those ending in a period do not. We are now ready to write down our action, very similar to what you would write down in LaTeX. We also write down a rule which says how the field strength is related to the gauge potential. Note how this rule does not automatically get inserted into the action; you need to tell Cadabra to do that.
S:= -1/4 \int{ F_{\mu\nu} F^{\mu\nu} }{x};
\(\displaystyle{} - \frac{1}{4}\int F^{\mu \nu} F_{\mu \nu}\,\,{\rm d}x\)
- 1/4 ∫(F^{\mu \nu} F_{\mu \nu}, x)
rl:= F_{\mu\nu} = \partial_{\mu}{A_{\nu}} - \partial_{\nu}{A_{\mu}};
\(\displaystyle{}F_{\mu \nu} = \partial_{\mu}{A_{\nu}}-\partial_{\nu}{A_{\mu}}\)
F_{\mu \nu} = \partial_{\mu}(A_{\nu})-\partial_{\nu}(A_{\mu})
substitute(S, rl);
\(\displaystyle{} - \frac{1}{4}\int \left(\partial_{\mu}{A_{\nu}}-\partial_{\nu}{A_{\mu}}\right) \left(\partial^{\mu}{A^{\nu}}-\partial^{\nu}{A^{\mu}}\right)\,\,{\rm d}x\)
- 1/4 ∫((\partial_{\mu}(A_{\nu})-\partial_{\nu}(A_{\mu})) (\partial^{\mu}(A^{\nu})-\partial^{\nu}(A^{\mu})), x)
Note how this has automatically replaced the field strength with upper as well as lower indices, by virtue of the fact that the index position was declared with position=free. We can now compute a variational derivative of this object with respect to $A_\mu$. Note the use of inline formulas using the standard TeX \$...\$ construction.
vary(S, $A_{\mu} -> \delta{A_{\mu}}$);
\(\displaystyle{} - \frac{1}{4}\int \left(\left(\partial^{\mu}{A^{\nu}}-\partial^{\nu}{A^{\mu}}\right) \left(\partial_{\mu}{\delta{A_{\nu}}}-\partial_{\nu}{\delta{A_{\mu}}}\right)+\left(\partial_{\mu}{A_{\nu}}-\partial_{\nu}{A_{\mu}}\right) \left(\partial^{\mu}{\delta{A^{\nu}}}-\partial^{\nu}{\delta{A^{\mu}}}\right)\right)\,\,{\rm d}x\)
- 1/4 ∫((\partial^{\mu}(A^{\nu})-\partial^{\nu}(A^{\mu})) (\partial_{\mu}(\delta{A_{\nu}})-\partial_{\nu}(\delta{A_{\mu}})) + (\partial_{\mu}(A_{\nu})-\partial_{\nu}(A_{\mu})) (\partial^{\mu}(\delta{A^{\nu}})-\partial^{\nu}(\delta{A^{\mu}})), x)
We need to distribute the products over the sums, and then integrate by parts, away from the $\delta{A_{\mu}}$ factors:
distribute(S); integrate_by_parts(S, $\delta{A_{\mu}}$);
\(\displaystyle{} - \frac{1}{4}\int \left(4\partial^{\mu}{A^{\nu}} \partial_{\mu}{\delta{A_{\nu}}}-4\partial^{\mu}{A^{\nu}} \partial_{\nu}{\delta{A_{\mu}}}\right)\,\,{\rm d}x\)
- 1/4 ∫(4\partial^{\mu}(A^{\nu}) \partial_{\mu}(\delta{A_{\nu}})-4\partial^{\mu}(A^{\nu}) \partial_{\nu}(\delta{A_{\mu}}), x)
\(\displaystyle{} - \frac{1}{4}\int \left(-4\delta{A^{\mu}} \partial^{\nu}\left(\partial_{\nu}{A_{\mu}}\right)+4\delta{A^{\mu}} \partial^{\nu}\left(\partial_{\mu}{A_{\nu}}\right)\right)\,\,{\rm d}x\)
- 1/4 ∫(-4\delta{A^{\mu}} \partial^{\nu}(\partial_{\nu}(A_{\mu})) + 4\delta{A^{\mu}} \partial^{\nu}(\partial_{\mu}(A_{\nu})), x)
Finally, in order to write this back in terms of the field strength, we use the following rewriting trick,
substitute(_, $\partial_{\mu}{A_{\nu}} -> 1/2 \partial_{\mu}{A_{\nu}} + 1/2 F_{\mu\nu} + 1/2 \partial_{\nu}{A_{\mu}}$);
\(\displaystyle{} - \frac{1}{4}\int \left(-4\delta{A^{\mu}} \partial^{\nu}\left(\frac{1}{2}\partial_{\nu}{A_{\mu}} - \frac{1}{2}F_{\mu \nu}+\frac{1}{2}\partial_{\mu}{A_{\nu}}\right)+4\delta{A^{\mu}} \partial^{\nu}\left(\frac{1}{2}\partial_{\mu}{A_{\nu}}+\frac{1}{2}F_{\mu \nu}+\frac{1}{2}\partial_{\nu}{A_{\mu}}\right)\right)\,\,{\rm d}x\)
- 1/4 ∫(-4\delta{A^{\mu}} \partial^{\nu}(( 1/2 \partial_{\nu}(A_{\mu}) - 1/2 F_{\mu \nu} + 1/2 \partial_{\mu}(A_{\nu}))) + 4\delta{A^{\mu}} \partial^{\nu}(( 1/2 \partial_{\mu}(A_{\nu}) + 1/2 F_{\mu \nu} + 1/2 \partial_{\nu}(A_{\mu}))), x)
\(\displaystyle{}-\int \delta{A^{\mu}} \partial^{\nu}{F_{\mu \nu}}\,\,{\rm d}x\)
-∫(\delta{A^{\mu}} \partial^{\nu}(F_{\mu \nu}), x)
This isolates the equations of motion $\partial^\nu F_{\mu\nu}=0$ in the integrand.
Copyright © 2001-2023 Kasper Peeters