Code printers

The most basic form of code generation are the code printers. The convert SymPy expressions into the target language.

The most common languages are C, C++, Fortran, and Python, but over a dozen languages are supported. Here, we will quickly go over each supported language.

In [1]:
from sympy import *
init_printing()

Let us use the function $$|\sin(x^2)|.$$

In [2]:
x = symbols('x')
expr = abs(sin(x**2))
expr
Out[2]:
$$\left|{\sin{\left (x^{2} \right )}}\right|$$
In [3]:
ccode(expr)
Out[3]:
'fabs(sin(pow(x, 2)))'
In [4]:
fcode(expr)
Out[4]:
'      abs(sin(x**2))'
In [5]:
julia_code(expr)
Out[5]:
'abs(sin(x.^2))'
In [6]:
jscode(expr)
Out[6]:
'Math.abs(Math.sin(Math.pow(x, 2)))'
In [7]:
mathematica_code(expr)
Out[7]:
'Abs[Sin[x^2]]'
In [8]:
octave_code(expr)
Out[8]:
'abs(sin(x.^2))'
In [9]:
from sympy.printing.rust import rust_code
rust_code(expr)
Out[9]:
'(x.powi(2)).sin().abs()'
In [10]:
rcode(expr)
Out[10]:
'abs(sin(x^2))'
In [11]:
from sympy.printing.cxxcode import cxxcode
cxxcode(expr)
Out[11]:
'fabs(sin(std::pow(x, 2)))'

Exercise: Codegen your own function

Come up with a symbolic expression and try generating code for it in each language. Note, some languages don't support everything. What works and what doesn't? What things are the same across languages and what things are different?

Reminder: If you click a cell and press b it will add a new cell below it.

In [12]:
# Write your answer here

Exercise: Plotting SymPy Functions with JavaScript

One use case that works nicely with the Jupyter notebook is plotting mathematical functions using JavaScript plotting libraries. There are a variety of plotting libraries available and the notebook makes it relatively easy to use. Here we will use Chart.js to plot functions of a single variable. We can use the %%javascript magic to type JavaScript directly into a notebook cell. In this cell we load in the Chart.js library:

In [13]:
%%javascript
require.config({
  paths: {
      'chartjs': '//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart'
  }
});

We've also prepared some Javascript to do the plotting. This code will take two mathematical expressions written in Javascript and plot the functions.

In [14]:
from scipy2017codegen.plotting import js_template
In [15]:
print(js_template.format(top_function='***fill me in!***',
                         bottom_function='***fill me in!***',
                         chart_id='***fill me in!***'))
require(['chartjs'], function(chartjs){

function f(x) {
    return ***fill me in!***
};

function g(x) {
    return ***fill me in!***
};

function linspace(a,b,n) {
    // From: https://gist.github.com/joates/6584908
    if(typeof n === "undefined") n = Math.max(Math.round(b-a)+1,1);
    if(n<2) { return n===1?[a]:[]; }
    var i,ret = Array(n);
    n--;
    for(i=n;i>=0;i--) { ret[i] = (i*b+(n-i)*a)/n; }
    return ret;
}

var ctx = document.getElementById("***fill me in!***");
var data = {
    labels: linspace(-7.5, 7.5, 500),
    datasets: [{
        label: "top",
        function: f,
        borderColor: "rgba(75, 192, 192, 1)",
        data: [],
        fill: false,
        lineTension: 0,
    },
    {
        label: "bottom",
        function: g,
        borderColor: "rgba(153, 102, 255, 1)",
        data: [],
        fill: false,
        lineTension: 0,
    }]
};

chartjs.Chart.pluginService.register({
    beforeInit: function(chart) {
        var data = chart.config.data;
        for (var i = 0; i < data.datasets.length; i++) {
            for (var j = 0; j < data.labels.length; j++) {
                var fct = data.datasets[i].function,
                    x = data.labels[j],
                    y = fct(x);
                data.datasets[i].data.push(y);
            }
        }
    }
});

var myBarChart = new chartjs.Chart(ctx, {
    type: 'line',
    data: data,
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});

});

element.append("<canvas id='***fill me in!***' width='400'></canvas>");

Now SymPy functions can be plotted by filling in the two missing expressions in the above code and then calling the Javascript display function on that code.

In [16]:
from IPython.display import Javascript
In [17]:
x = symbols('x')
f1 = sin(x)
f2 = cos(x)
In [18]:
Javascript(js_template.format(top_function=jscode(f1),
                              bottom_function=jscode(f2),
                              chart_id='sincos'))
Out[18]:

Exercise: Batman!

Plot the equations below for top and bottom.

There are all kind of functions that can be plotted, but one particularly interesting set of functions are called the Batman Equations. We've provided the piecewise versions of these functions written in SymPy below. Try plotting these with the JS plotter we've created.

In [19]:
from scipy2017codegen.plotting import batman_equations
In [20]:
top, bottom = batman_equations()
In [21]:
top
Out[21]:
$$\begin{cases} \frac{3}{7} \sqrt{- x^{2} + 49} & \text{for}\: x \geq 3 \\- \frac{\left|{x}\right|}{2} - \frac{3 \sqrt{10}}{7} \left|{\sqrt{- \left(\left|{x}\right| - 1\right)^{2} + 4}}\right| + \frac{3}{2} + \frac{6 \sqrt{10}}{7} & \text{for}\: x \geq 1 \\- 8 \left|{x}\right| + 9 & \text{for}\: x \geq \frac{3}{4} \\3 \left|{x}\right| + \frac{3}{4} & \text{for}\: x \geq \frac{7}{12} \\\frac{5}{2} & \text{for}\: x \geq - \frac{7}{12} \\3 \left|{x}\right| + \frac{3}{4} & \text{for}\: x \geq - \frac{3}{4} \\- 8 \left|{x}\right| + 9 & \text{for}\: x \geq -1 \\- \frac{\left|{x}\right|}{2} - \frac{3 \sqrt{10}}{7} \left|{\sqrt{- \left(\left|{x}\right| - 1\right)^{2} + 4}}\right| + \frac{3}{2} + \frac{6 \sqrt{10}}{7} & \text{for}\: x \geq -3 \\\frac{3}{7} \sqrt{- x^{2} + 49} & \text{otherwise} \end{cases}$$
In [22]:
bottom
Out[22]:
$$\begin{cases} - \frac{3}{7} \sqrt{- x^{2} + 49} & \text{for}\: x \geq 4 \\- x^{2} \left(- \frac{1}{16} + \frac{3 \sqrt{33}}{112}\right) + \sqrt{- \left(\left|{\left|{x}\right| - 2}\right| - 1\right)^{2} + 1} + \frac{\left|{x}\right|}{2} - 3 & \text{for}\: x \geq -4 \\- \frac{3}{7} \sqrt{- x^{2} + 49} & \text{otherwise} \end{cases}$$
In [23]:
# Write your answer here