Hi,
Now that
SymEngine has enough methods ported from sympy.core, it can be used in other parts of sympy.
For example, I've been adding methods to
symengine.py to mirror the SymPy API so that `n_link_pendulum_on_cart` from PyDy can run without any conversions from SymEngine to SymPy and vice versa. We chose sympy.physics and PyDy because it uses less amount of things from other sympy modules.
For those who are unfamiliar let me explain how SymEngine and SymPy can interoperate. In almost all functions in sympy, sympify is called on inputs before doing anything. Symengine objects when sympified are converted into sympy and therefore can be used in those functions. Similarly in symengine, all methods call symengine's sympify which would convert sympy objects to symengine. One additional thing that symengine do is that when it goes through a sympy expression's tree and finds a function not defined in symengine like Ynm, then it will create a PyFunction object to wrap the Ynm object. Logic is there so that methods like subs, eval, hash, compare can fallback to Python.
This is okay, but doesn't really help with sympy's speed as symengine objects are converted to sympy as soon as a sympy function is called. To avoid these conversions, I've started a PR
here. What it does is it looks for an environment variable USE_SYMENGINE and if found it uses symengine's methods instead of sympy methods.
import os
if os.environ.get('USE_SYMENGINE'):
from symengine import sympify, diff, sin, cos, Matrix, symbols, UndefFunction as Function
else:
from sympy import sympify, diff, sin, cos, Matrix, symbols, Function
Advantages over sympy is that symengine is faster. Symengine keeps objects in data structures that are used to creating them. For example, an Add keeps the dictionary of coefficients (output of expr.as_coefficients_dict()). This structure is used throughout symengine without flattening it to a list of Mul objects. So this leads to a better time complexity than sympy.
Also since symengine is written in C++, true threading is also possible. I've tried using OpenMP for embarrassingly parallel algorithms like taking the jacobian of a matrix and differentiating all elements of a matrix and it gives a good speedup for `n_link_pendulum_on_cart`.
One question I have is how do we test this? Is this something that should be tested in symengine or sympy? Since symengine is written in C++ and the default C++ compiler is different on different platforms, symengine is tested on Linux (gcc, clang), OS X (gcc, AppleClang) and Windows (MSVC, MinGW, MinGW-w64) with different compilers using Travis-CI and Appveyor.
Jason was okay to merge the PR as an undocumented feature, but what should be done to support this officially?
Thanks,
Isuru Fernando