# Export to C code

Is it possible to export the result of a calculation to C source code? To be more specific, I have a very long equation emerging from a Sage calculation which I need to feed into a C simulation program, but C doesn't understand the x^2, x^3, ... syntax. I ended up using the re module to manually replace the terms with the proper pow function calls, but I thought maybe there is a more elegant solution to this.

edit retag close merge delete

Sort by ยป oldest newest most voted

Just to chime in here on this long abandoned question, the code generation module that DSM mentions is now included in Sage. Here's a short example:

sage: x, y = var('x, y')
sage: f = x**2 + sin(y)/sqrt(5*x+9*y)
sage: fs = f._sympy_() # convert to a sympy symbolic expression
sage: [(c_name, c_code), (h_name, c_header)] = codegen(("f", fs), "C", "test")
sage: print c_code
/******************************************************************************
*                      Code generated with sympy 0.7.1                       *
*                                                                            *
*              See http://www.sympy.org/ for more information.               *
*                                                                            *
*                       This file is part of 'project'                       *
******************************************************************************/
#include "test.h"
#include <math.h>

double f(double x, double y) {

return pow(x, 2) + sin(y)/sqrt(5*x + 9*y);

}

more

Hooray! This is one of the things which you seldom need, but when you do need, it's uber-handy.

( 2013-02-22 06:04:20 -0500 )edit
1

Thanks for this great solution. Just a detail, this line is also required before calling codegen: from sympy.utilities.codegen import codegen

( 2016-10-07 06:47:15 -0500 )edit

Another comment @benjaminfjones : this line fs = f._sympy_() is really necessary ? I've noticed that even if I exclude it the conversion gets done and the code returned is identical... ANSWERING MY OWN COMMENT: yes sympy is necessary, in some cases I would get an error if not converting to sympy, so you can ignore my comment...

( 2016-12-19 03:38:39 -0500 )edit

If I understand you, then you're looking for the equivalent of maple's CodeGeneration package, which nicely turns Maple functions into fortran or C code which you can then include in your own code (done this many times myself). Unfortunately I couldn't find what you're looking for.

(1) I tried looking at the existing expression conversions (for sympy, maxima, etc.) but none of them seemed to need to do this.

(2) Apparently there are tricks to do it from maxima (using the "subst" command), but I couldn't get any of them to work, at least not via the Sage-Maxima interface. My Maxima-fu is pretty weak, though. Unfortunately Fortran has the "**" operator, so using maxima.fortran wouldn't help!

(3) I don't think Cython will be that useful here, because the C code that it generates is pretty messy, and parsing it to recover something that you could insert in a non-Cython C code -- though doable -- would be much harder and more error-prone than simply turning (a)^(b) into pow((a), (b)) in the first place!

This would be a very useful feature, though; doing algebra in a CAS and then moving it to code used to be one of the main things I used Maple for.

more

I'm upvoting this since I think I misunderstood the original question.

( 2011-02-09 11:23:02 -0500 )edit

Cython (included with Sage) converts Python-like code into C which can then be compiled into a shared-object library and used by Python / Sage. It's intended use is to write code that is easy to use like Python but is optimized to use fast C data types instead of slower Python data structures. However, one could certainly just write Python without any optimizations and have Cython generate the C equivalent.

Create a .pyx file containing your code and execute

\$ sage -cython -a mycythonfile.pyx


This will output a corresponding .c file which can be compiled into a shared object library and imported in Python along with an.html file that neatly shows the C equivalent of each line of code.

Be warned that the corresponding C code, though optimized, looks really messy.

For more information on compiling Cython code, take a look at the Cython compilation documentation.

more

Is there a way to do this from a Sage notebook? To make myself more clear: I want to feed the result of a (symbolic) Taylor expansion from a Sage notebook into a C program, which I have already written.

( 2011-02-07 04:08:00 -0500 )edit

Type %cython at the top of a notebook cell to have Cython convert and compile the contents of the cell. (It will automatically link the .so to the currently running notebook session.) Two links will appear as the cell output. One is a link to the C-source. The other is the handy html guide to what happened in the Cython-C conversion process.

( 2011-02-07 04:25:00 -0500 )edit

I somehow don't get to grips with Cython. Could you point me to a minimal example of using it from within a Sage notebook? I tried something like %cython x=0; x^2; , but it doesn't convert x^2 to pow(x,2).

( 2011-02-07 08:01:56 -0500 )edit

Take a look at http://uw.sagenb.org/home/pub/49 and follow the instructions. I hope this is what you're looking for and not me misinterpreting your question.

( 2011-02-07 10:16:24 -0500 )edit

It looks like sympy 0.6.7 has a codegen package, but the version in Sage (0.6.4 in Sage 4.7) doesn't. We should upgrade and make sure it works with ._sympy_(), this is a very useful feature.

more

Very interesting. I know that some of the Sympy folks have been involved with f2py, a Fortran to Python wrapping utility. Quite interesting that they have a C codegen as well!

( 2011-06-03 06:27:27 -0500 )edit

If you just add %cython to the beginning of the notebook it gives a c file. The file is a bit messy but you can always include it in other c files and call functions.

more

Hi Hennes,

Did you ever figure out how to translate Sage code into C code? I have the exact same problem and can't find a way to do that. Besides, the link cswiercz gave is now broken.

more

Which link are you talking about? They work fine for me.

( 2011-06-02 12:48:44 -0500 )edit

Just to add to the list of answers, I'm linking a post I've made which shows how to expand Benjamin Jones' solution to a system of functions and their gradients: http://louisgagnon.com/scBlog/sageCpp...

more