Cadabra
Computer algebra system for field theory problems
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Files | Classes | Functions
Python Core

Module Description

Python wrapper around the C++ core module, making the entire functionality of Cadabra accessible from Python.

This consists of two parts. One is core/cadabra2_defaults.py, which is a pure-python file. It contains the display function to show Cadabra objects to the user in a UI-independent way (e.g. switching between a text representation on the command line and a LaTeX representation when running in a notebook). The other part is core/PythonCdb.cc, which builds the cadabra2 module for python, to be imported with 'from cadabra2 import *'.

Files

file  cadabra2_defaults.py
 Cadabra2 pure Python functionality.
 

Classes

class  BaseProperty
 Helper class to ensure that all Python property objects derive from the same base class. More...
 
class  Property< T >
 Property is a templated wrapper around a C++ property object. More...
 

Functions

void pull_in (std::shared_ptr< cadabra::Ex > ex)
 Replace any objects of the form '@(...)' in the expression tree by the python expression '...' if it exists. More...
 
bool __eq__Ex_Ex (const cadabra::Ex &, const cadabra::Ex &)
 Comparison operator for Ex objects in Python. More...
 
bool __eq__Ex_int (const cadabra::Ex &, int)
 Comparison operator for Ex objects in Python. More...
 
std::string Ex_str_ (const cadabra::Ex &)
 Generate the Python str() and repr() representation of the Ex object. More...
 
std::string Ex_latex_ (const cadabra::Ex &)
 The Python 'print' function always calls the 'str' member on objects to be printed. More...
 
cadabra::Ex operator+ (const cadabra::Ex &ex1, const cadabra::Ex &ex2)
 Add two expressions, adding a top-level node if required. More...
 
cadabra::Ex operator- (const cadabra::Ex &ex1, const cadabra::Ex &ex2)
 Subtract two expressions, adding a top-level node if required. More...
 
cadabra::Kernelcreate_scope ()
 Setup of kernels in current scope, callable from Python. More...
 
void inject_defaults (cadabra::Kernel *)
 Inject properties directly into the Kernel, even if the kernel is not yet on the Python stack (needed when we create a new local scope: in this case we create the kernel and pass it back to be turned into local cdbkernel by Python, but we want to populate the kernel with defaults before we hand it back). More...
 
cadabra::Kernelget_kernel_from_scope ()
 Get a pointer to the currently visible kernel. More...
 
void call_post_process (cadabra::Kernel &, cadabra::Ex &ex)
 Run the post-process Python function (if defined) on the given expression. More...
 

Function Documentation

bool __eq__Ex_Ex ( const cadabra::Ex ,
const cadabra::Ex  
)

Comparison operator for Ex objects in Python.

Since comparison operators need a Properties object, we cannot have such operator== things in C++, but we can in Python since we can get the kernel in the current scope.

bool __eq__Ex_int ( const cadabra::Ex ,
int   
)

Comparison operator for Ex objects in Python.

See __eq__Ex_Ex for more.

void call_post_process ( cadabra::Kernel ,
cadabra::Ex ex 
)

Run the post-process Python function (if defined) on the given expression.

cadabra::Kernel* create_scope ( )

Setup of kernels in current scope, callable from Python.

When the decision was made to graft Cadabra onto Python, a choice had to be made about how Python variable scope would influence the visibility of Cadabra properties. It clearly makes sense to be able to declare properties which only hold inside a particular function. However Cadabra expressions and properties do not directly correspond to Python objects. Rather, declaring a property is more like a function call into the Cadabra module, which leaves its imprint on the state of the C++ part but does not change anything on the Python side, as you typically do not assign the created property to a Python symbol. Therefore, properties do not naturally inherit Python's scoping rules.{This is different from e.g.~SymPy, in which mathematical objects are always in one-to-one correspondence with a Python object.} A more fundamental problem is that properties can be attached to patterns, and those patterns can involve more than just the symbols which one passes into a function.

In order to not burden the user, properties are therefore by default global variables, stored in a single global Cadabra object |__cdbkernel__| which is initialised at import of the Cadabra module. If you add new properties inside a function scope, these will go into this already existing {global} property list by default. If you want to create a local scope for your computations, create a new |__cdbkernel__| as in {verbatim} def fun(): cdbkernel = cadabra.create_scope(); [your code here] {verbatim} Now computations will not see the global properties at all. If you want to import the global properties, use instead {verbatim} def fun(): cdbkernel = cadabra.create_scope_from_global() [your code here] {verbatim} It is crucial that the |__cdbkernel__| symbol is referenced from within Python and visible to the bytecompiler, because it is not possible to create new variables on the local stack at runtime. Internally, the second version above fetches, at runtime, the |__cdbkernel__| from the globals stack, copies all properties in there into a new kernel, and returns the latter.

Both versions above do populate the newly created kernel with Cadabra's default properties. If you want a completely clean slate (for e.g.~testing purposes, or because you really do not want default rules for sums and products), use {verbatim} def fun(): cdbkernel = cadabra.create_empty_scope() [your code here] {verbatim} Note that in all these cases, changes to properties remain local and do not leak into the global property list.

All Cadabra algorithms, when called from Python, will first look for a kernel on the locals stack (i.e.~what |locals()| produces). If there is no kernel available locally, they will then revert to using the global kernel.

std::string Ex_latex_ ( const cadabra::Ex )

The Python 'print' function always calls the 'str' member on objects to be printed.

This one is required to produce output which looks readable but is also still valid input. In order to produce proper LaTeX output, this is therefore not the right function to use, because Cadabra only reads a restricted subset of LaTeX (for instance, we output spacing commands like '\,' but do not accept it on input). So we have a separate latex() member on each object, which internally uses DisplayTeX to do the actual printing.

std::string Ex_str_ ( const cadabra::Ex )

Generate the Python str() and repr() representation of the Ex object.

cadabra::Kernel* get_kernel_from_scope ( )

Get a pointer to the currently visible kernel.

void inject_defaults ( cadabra::Kernel )

Inject properties directly into the Kernel, even if the kernel is not yet on the Python stack (needed when we create a new local scope: in this case we create the kernel and pass it back to be turned into local cdbkernel by Python, but we want to populate the kernel with defaults before we hand it back).

cadabra::Ex operator+ ( const cadabra::Ex ex1,
const cadabra::Ex ex2 
)

Add two expressions, adding a top-level node if required.

cadabra::Ex operator- ( const cadabra::Ex ex1,
const cadabra::Ex ex2 
)

Subtract two expressions, adding a top-level node if required.

void pull_in ( std::shared_ptr< cadabra::Ex ex)

Replace any objects of the form '@(...)' in the expression tree by the python expression '...' if it exists.

Rename dummies to avoid clashes.