Cadabra
a field-theory motivated approach to computer algebra

The kernel and other internals

Because Cadabra stores mathematical expressions in a separate expression tree in Ex objects, it behaves somewhat differently from systems in which expressions are stored as a Python expression tree. In Cadabra, the meaning of a particular symbol in a mathematical expression is determined by the properties which you have attached to it, not by the Python type of that symbol (it does not have a Python type). To see what the above means, consider the following example:
A_{m n}::Symmetric; ex:= A_{m n} + A_{n m}; canonicalise(ex);
\(\displaystyle{}\text{Property Symmetric attached to }A_{m n}.\)
\(\displaystyle{}A_{m n} +A_{n m}\)
A_{m n} + A_{n m}
\(\displaystyle{}2A_{m n}\)
2A_{m n}
Here, the symbol A_{m n} is not a Python object, but rather a string which can appear in a mathematical expression. If you look under the hood, the above cell can be written in pure Python as
Symmetric( Ex(r" A_{m n} ") ); ex = Ex(r" A_{m n} + A_{n m} " ); canonicalise(ex);
\(\displaystyle{}\text{Property Symmetric attached to }A_{m n}.\)
\(\displaystyle{}A_{m n} +A_{n m}\)
A_{m n} + A_{n m}
\(\displaystyle{}2A_{m n}\)
2A_{m n}
From this example, it should hopefully be clear that the only Python object is ex, and the mathematics is not stored as Python functions/objects. So how does Cadabra now know that A_{m n} is symmetric in its indices? Where did that property get stored? It is not because A_{m n} is of Python type Symmetric (it cannot be, because A_{m n} is not even a valid Python identifier name). Rather, the first line in the example above makes this information go into the Cadabra kernel. The kernel is a global object which automatically gets created when you start Cadabra (or when you import cadabra2 if you use it from pure Python). It has the name __cdbkernel__:
__cdbkernel__;
<cadabra2.Kernel object at 0xffffaa9d1a30>
All Cadabra algorithms look for this object and use it to extract or store property information about the symbols which appear in mathematical expressions.
For most situations, having just this single global kernel object is sufficient, as you will want the properties of mathematical symbols to be shared between all expressions, whether they get created at global scope or in some local context inside a function. However, there are situations where you might want to "start with a clean slate" inside a function. In that case, you can create a new local kernel scope by doing
__cdbkernel__ = create_scope();
<cadabra2.Kernel object at 0xffffaa3fea70>
You will see this used in the test programs in the test/ folder of the Cadabra source code.

Kernel parameters and options

Various global Cadabra settings can be queried and configured by setting options in the current kernel. In order to determine the current version and build, there are some read-only options:
__cdbkernel__.version; __cdbkernel__.build;
2.5.9
3436.a19d6939e3
To switch between the display of fractions in two-dimensional form or using the $(...)^{-1}$ notation,
__cdbkernel__.display_fractions=True ex:= a/b;
\(\displaystyle{}\frac{a}{b}\)
a (b)**(-1)
__cdbkernel__.display_fractions=False ex:= a/b;
\(\displaystyle{}a {b}^{-1}\)
a (b)**(-1)
To switch the scalar backend used for simplification of scalar expressions using simplify, there are currently two options: scalar_backend_t.mathematica and scalar_backend_t.sympy.
__cdbkernel__.scalar_backend = scalar_backend_t.mathematica
Unless you have built Cadabra with Mathematica support, the expression below will remain unsimplified:
simplify($\sin(x)**2 + \cos(x)**2$);
\(\displaystyle{}{\left(\sin{x}\right)}^{2} +{\left(\cos{x}\right)}^{2}\)
(\sin(x))**2 + (\cos(x))**2
__cdbkernel__.scalar_backend=scalar_backend_t.sympy
simplify($\sin(x)**2 + \cos(x)**2$);
\(\displaystyle{}1\)
1
If you want to be able to write mathematical expressions which contain Python functions acting on sub-expressions, use
__cdbkernel__.call_embedded_python_functions=True
ex:= distribute( (A+B)*(C+D) );
\(\displaystyle{}A C +A D +B C +B D\)
A C + A D + B C + B D
Compare the above to what happens when this functionality is turned off (the default):
__cdbkernel__.call_embedded_python_functions=False
ex:= distribute( (A+B)*(C+D) );
\(\displaystyle{}distribute\left(\left(A +B\right) \left(C +D\right)\right)\)
distribute((A + B) (C + D))
Copyright © 2001-2024 Kasper Peeters
Questions? info@cadabra.science