This tutorial will introduce code generation concepts using the SymPy library. SymPy is a pure Python library for symbolic mathematics. Code generation refers to the act of converting a SymPy symbolic expression into equivalent code in some language, typically for numeric evaluation. This allows one to use SymPy to symbolically model a problem and generate fast numerical code for specific platforms that executes that model. This is a powerful tool that is useful to scientists in many domains. Code generation allows users to speed up existing code, to deal only with the high level mathematics of a problem, avoids mathematical errors and typos, makes it possible to deal with expressions that would otherwise be too large to write by hand, and opens possibilities to perform automatic mathematical optimizations of expressions.

SymPy supports generating code for C, C++, Fortran, MATLAB/Octave, Python, Cython, Julia, JavaScript, LLVM, Rust, Haskell, Mathematica, Tensorflow, and Theano, and can easily be extended to other languages. SymPy’s code generation is used by libraries such as PyDy, pyodesys, sympybotics, pycalphad, and many other programs.

You can run this tutorial online with Binder. Otherwise, follow the instructions in the README to install the tutorial materials.

- Björn Dahlgren, KTH Royal Institute of Technology
- Kenneth Lyons, University of California, Davis
- Aaron Meurer, University of South Carolina
- Jason Moore, University of California, Davis

Attendees will be able to:

- write SymPy expressions describing mathematical functions and identify the function arguments and outputs,
- use the SymPy code printers to transform SymPy expressions representing common domain specific functions into multiple output languages,
- use the SymPy code generation routines to output compilable C code and use Cython to access these functions in Python,
- generate custom vectorized functions with the three SymPy functions: lambdify, ufuncify, and autowrap,
- create both custom code printers that make use of specialized C libraries and common subexpression elimination (CSE),
- subclass the core SymPy printers and create a printer for a custom language.

**Description**

Introduction of the topic, speakers, and software.

**Description**

Writing common domain specific mathematical expressions with SymPy.

**Motivating Examples**

Long expressions, Matrix operations, and Loop Fusion from classical mechanics, chemical kinetics, nuclear dynamics, and materials science.

- Expressions
- Reminders on common gotchas
- Floating point representation
- Undefined Functions
- Derivatives
- Matrices
- Matrix Symbols
- Indexed

**Description**

Printing expressions in multiple languages (C, Fortran, Rust, Julia, Octave, Javascript, etc)

**Motivating Example**

2D interactive plot in a Jupyter notebook by Javascript injection

- [15 min] Code printing
**Exercise:**Codegen your own function

- [15 min]
**Exercise:**Plotting SymPy Functions with Javascript

**Description**

Generate python functions from symbolic expressions.

**Motivating Example**

Generate a Jacobian function for a chemical kinetic problem.

- [10 minutes] Refresher on ordinary differential equations
- [5 minutes]
**Exercise:**write an analytic Jacobian function by hand

- [10 minutes] Introduction to
`lambdify`

- [5 minutes]
**Exercise:**Create a function from a SymPy expression

- [5 minutes] Governings equations for systems of ODEs in chemical kinetics.
- [5 minutes]
**Exercise:**generate a function evaluating the rhs of an ODE system

- [10 minutes]
**Exercise:**construct SymPy expressions from a simple data structure - [10 minutes]
**Exercise:**derive a Jacobian symbolically and generate a function evaluating it

**Description**

Convert SymPy matrices to a C program and speed up numerical execution by extending the printer with common subexpression elimination.

**Motivating Example**

Evaluate a chemical kinetic ordinary differential equation and its Jacobian using C.

- [5 minutes] Introduction
- [5 minutes]
**Exercise:**Load the ODE expression, compute the Jacobian, and inspect the results. - [5 minutes] Printing C Code
- [5 minutes]
**Exercise:**Generate C code for the Jacobian expression.

- [5 minutes] Extending and Customizing Printers
- [10 minutes]
**Exercise:**Construct custom exponential printing and symbol names.

- [5 minutes] Common Sub-expression Elimination
- [15 minutes]
**Exercise:**Generate C code (w/ CSE) for the ODE and Jacobian expressions. - [5 minutes]
**Bonus:**Compile and execute the C code.

**Description**

Generate C code to evaluate an ordinary differential equation and and its Jacobian and wrap it for use with SciPy’s integrators. Additionally, demonstrate how one might access external C libraries.

**Motivating Example**

Integrating the water radiolysis system of ODEs.

- [2 minutes] Explanation of Cython
- [3 minutes] Example: writing Cython and compiling in a notebook

`codegen()`

¶- [2 minutes] Review the water radiolysis system
- [2 minutes] First exposure to
`codegen`

- [3 minutes]
**Exercise**generate code with a cleaner function signature - [3 minutes]
**Exercise**generate an even cleaner function signature

- [5 minutes] Overview of the wrapping process
- [3 minutes] Explanation of the build process
- [3 minutes] Explanation of the wrapper code
- [3 minutes]
**Exercise**: use the wrapped function with some random inputs - [3 minutes] Use
`odeint`

to integrate the ODEs using the wrapped function

- [3 minutes] Overview of the
`autowrap`

function - [5 minutes]
**Exercise**: explore the`autowrap`

generated files - [5 minutes]
**Exercise**: use the wrapped function with some random inputs - [2 minutes] Writing a wrapper around the wrapper
- [8 minutes]
**Exercise**: generate a function to compute the Jacobian

`autowrap`

¶- [2 minutes] Overview of
`CodeGen`

and`CodePrinter`

- [2 minutes] Explanation of fastapprox library
- [8 minutes]
**Exercise**: implement a custom code printer to use`fastpow`

instead of`pow`

- [3 minutes] Including
`fastpow.h`

- [3 minutes] Using the new function and proving it worked
- [2 minutes]
**Exercise**: compare outputs of the callables using`pow`

and`fastpow`

functions

The attendees will come away with a powerful set of tools that will allow them to develop high performance numerical code using Python that compliments NumPy and SciPy. This tutorial will be ideal for users of the SciPy Stack that would like to increase the performance of their Python code, get into some of the depths of how low-level languages can interact and be used from Python, or to learn a new technique for expressing mathematical models in Python.

- Radioactive decay chain: Tc-99m
- Chemical Kinetics: Using a Cython template
- Chemical Kinetics: Using a Cython template & another SciPy solver
- Chemical Kinetics: Using a C template and an external solver's C API
- Chemical Kinetics: Adding diffusion (mixing hand-written & generated functions)
- More Cython Examples