NOTE

This notebook will make more sense (provide speed-up) once the LLVM backend is exposed in the python wrappers for SymEngine. I need to get back working on that here.

In this notebook we will use symengine the increase the performance of our callbacks produced by lambdify in SymPy.


In [ ]:
import json
import numpy as np
from scipy2017codegen.odesys import ODEsys
from scipy2017codegen.chem import mk_rsys

The ODEsys class and convenience functions from previous notebook (35) has been put in two modules for easy importing. Recapping what we did last:


In [ ]:
watrad_data = json.load(open('../scipy2017codegen/data/radiolysis_300_Gy_s.json'))
watrad = mk_rsys(ODEsys, **watrad_data)
tout = np.logspace(-6, 3, 200)  # close to one hour of operation
c0 = {'H2O': 55.4e3, 'H+': 1e-4, 'OH-': 1e-4}
y0 = [c0.get(symb.name, 0) for symb in watrad.y]

In [ ]:
%timeit yout, info = watrad.integrate_odeint(tout, y0)

so that is the benchmark to beat.


In [ ]:
import symengine as se
def _lambdify(args, exprs):
    if isinstance(exprs, sym.MutableDenseMatrix):
        exprs = se.DenseMatrix(exprs.shape[0], exprs.shape[1], exprs.tolist())
    lmb = se.Lambdify(args, exprs)
    return lambda *args: lmb(args)

watrad_symengine = mk_rsys(ODEsys, **watrad_data, lambdify=_lambdify)

In [ ]:
%timeit watrad_symengine.integrate_odeint(tout, y0)

In [ ]:
import matplotlib.pyplot as plt
%matplotlib inline

Just to see that everything looks alright:


In [ ]:
fig, ax = plt.subplots(1, 1, figsize=(14, 6))
watrad_symengine.plot_result(tout, *watrad_symengine.integrate_odeint(tout, y0), ax=ax)
ax.set_xscale('log')
ax.set_yscale('log')