Computer Algebra Interfaces¶
DDA implements a few parts of computer algebra system (CAS), especially with it’s Abstract Syntax tree. Since we don’t want to reinvent the wheel, we interface with common computer algebra systems. There are at least two popular for the Python ecosystem available:
SymPy, bundled within the SciPy package, can be easily used as a pure python library.
Sagemath, which is more of a monolithic software. The symbolic foundation of sage is provided by Ginac and Pynac, respectively. Many open source computer algebra systems are bundled with sage, such as Maxima and Octave. Furthermore, interfaces to many others such as Maple, Mupad or Mathematica are part of sage.
So far, we had quick success with adopting SymPy (see next section).
SymPy module API reference¶
This module provides interplay with the SymPy package. SymPy is a lightweight pure-python computer algebra system which is bundled with SciPy. An adapter to/from SymPy allows to use powerful Computer Algebra basic functions such as expression simplification.
We use this currently to provide a lean latex representation for the cumbersome DDA expressions.
-
dda.sympy.
from_sympy
(sympy_equation_list)[source]¶ Import a state from a set of equations from SymPy.
This function expects a python list of sympy equations where there is a single sympy symbol on one hand and an expression on the other hand (see examples below).
The mapping basically follows the SymPy key invariant: “Every well-formed SymPy expression must either have empty
args
or satisfyexpr == expr.func(*expr.args)
”.Therefore we basically map a sympy expression
(expr.func, expr.args)
to the DDA(head, tail)
notation. While the heads are easy to map (for instance,sympy.Mul
equalsdda.mult
), special attention must be given to the tails, for instance SymPysMul(a,b,c)
translates to DDAsmult(mult(a,b),c)
(in DDA we always assume commutative real-valued variables). Also in DDA there isneg(x)
ordiv(x,y)
which is represented in SymPy asMul(Integer(-1), x)
andMul(Symbol('x'), Pow(Symbol('y'), Integer(-1)))
, respectively.
-
dda.sympy.
to_sympy
(state, symbol_mapper=<function <lambda>>, round_n=15)[source]¶ Export a state to a set of equations for SymPy. Returns a list of
sympy.Eq
objects. Of course it requires Sympy installed/available.Note
The heart of this function is a mapping from
ast.Symbol
terms (functions) to Sympy functions, for instance by mappingSymbol("int")(...)
to-sympy.Integral(sympy.Add(...), t)
.Thanks to the ease of the computing elements, this mapping does not require pattern matching but can be performed on a basic level. However, not all terms are yet supported.
The argument symbol_mapper allows to apply another mapping on the DDA Symbol heads. By default, it is the identity function.
With Sympy, you can do all funny things, such as:
>>> from dda import * >>> x,int,neg=symbols("x,int,neg") >>> state = State({'x': int(neg(x), 0.2, 1)}) >>> to_sympy(state) [Eq(x, -Integral(1.2 - x, t))]
-
dda.sympy.
to_latex
(state, chunk_n=None)[source]¶ Export to latex, using sympy.
This mostly differs from
sympy.latex
for large equation systems where we use the align latex environment instead of a single equation. For the above example:>>> import sympy, dda >>> x,int,neg=dda.symbols("x,int,neg") >>> state = dda.State({'x': int(neg(x), 0.2, 1)}) >>> print(sympy.latex(to_sympy(state))) \left[ x = - \int \left(1.2 - x\right)\, dt\right] >>> print(to_latex(state)) \begin{align} x &= - \int \left(1.2 - x\right)\, dt \end{align}