Using multiple files and notebooks
At some point, you will encounter computations which are best separated out into their own notebook. Or you will do a computation which takes a long time, and you want to write an intermediate result into a file so that you can read it back later easily. There are two options for this in Cadabra: importing notebooks into other notebooks, or writing individual expressions to a file and reading them back.Importing a notebook into another one
The simplest way to separate functionality is to simply write a separate notebook with the properties and expressions which you want to re-use elsewhere. In this way, writing a 'package' for Cadabra is nothing else but writing a separate notebook. You can import any notebook into another one by using the standard Python import logic.Example
Let us say we have a notebooklibrary.cnb
, which contains a single cell with the following
content:
{m,n,p,q,r}::Indices; ex:=A_{q r} A_{q r};You can now import this into another notebook by simply using
from library import *
Cadabra looks for the
library.cnb
notebook in your PYTHONPATH
(just as in ordinary Python programs),
as well as in the current directory. You can see that this worked by e.g. the following:ex;
rename_dummies(ex);
\(\displaystyle{}A_{q r} A_{q r}\)
A_{q r} A_{q r}
\(\displaystyle{}A_{m n} A_{m n}\)
A_{m n} A_{m n}
Note that the import has thus not only imported the
ex
expression, but also the property
information about the index set, which enabled the rename_dummies
to work.Behind the scenes, what happens is that the import statement looks for a file
library.cnb
. If it
finds this, it will first convert that file to a proper Python file (remember the library.cnb
file is a
Cadabra notebook, not a Python file). It then uses the standard Python logic to do the import.Writing expressions to a file and reading them back
A somewhat more difficult way to re-use expressions is to write them to a file using standard Python methods, and then read them back elsewhere. This method is best used for long computations of which you want to write an intermediate result out to disk, to be read in later (instead of doing a re-computation). Be aware that if you write an expression to disk, you do not write the property information of any of the symbols in that expression to disk.Example
The following example declares two expressions and writes them to disk. It then reads the expressions back in again and assigns them to different Python names.ex1:= A_{m n} \sin{x};
ex2:= B_{m n};
with open("output.cdb", "w") as file:
file.write( ex1.input_form()+"\n" )
file.write( ex2.input_form()+"\n" )
\(\displaystyle{}A_{m n} \sin{x}\)
A_{m n} \sin(x)
\(\displaystyle{}B_{m n}\)
B_{m n}
with open("output.cdb", "r") as file:
ex3=Ex( file.readline() )
ex4=Ex( file.readline() )
ex3;
ex4;
\(\displaystyle{}A_{m n} \sin{x}\)
A_{m n} \sin(x)
\(\displaystyle{}B_{m n}\)
B_{m n}
Note that when written in this way, the file
output.cdb
only contains the expressions, not their names
(ex1
and ex2
in the example above).Cadabra's expressions can also be written to disk using Python's pickle functionality. This makes the code slightly less
messy, but note that the file will no longer be human-readable. If you use the pickle module, the example above would read:
import pickle
ex1:= A_{m n} \sin{x};
ex2:= B_{m n};
with open("output.pkl", "wb") as file:
pickle.dump(ex1, file)
pickle.dump(ex2, file)
\(\displaystyle{}A_{m n} \sin{x}\)
A_{m n} \sin(x)
\(\displaystyle{}B_{m n}\)
B_{m n}
with open("output.pkl", "rb") as file:
ex3=pickle.load(file)
ex4=pickle.load(file)
ex3;
ex4;
\(\displaystyle{}A_{m n} \sin{x}\)
A_{m n} \sin(x)
\(\displaystyle{}B_{m n}\)
B_{m n}