samwise samwise - 1 year ago 81
C++ Question

sympy ccode number type

I am using Sympy to manipulate and differentiate a user-defined input function in order to generate a C++ library to be used with an external C++ program. It works great, except that for the fact that Sympy insists on expressing 1/2 as 1.0L/2.0L. Fine, except some of the variables in the main code are of type std::complex, so this is causing a compile-time error since it can't (implicitly) multiply/add/subtract a complex with long doubles (or ints, for that matter). I tried compiling with -std=c++14 since this has more support for implicit type casting, but the "problem" persists.

In the meantime, I've written a set of helper functions to deal with those operations, but I was wondering if there is any way to tell Sympy to output any numerical value it has as a double? For example, instead of outputting 1.0L/2.0L to the C code, can I force it to just write 1.0/2.0 (or even 0.5)? Likewise, instead of writing an int such as 2, I'd like it to write 2.0. I tried setting the precision flag (in the sympy.printing.ccode function call) but it did not change anything. I couldn't seem to find anything online

I'd be very grateful for any advice.

Many thanks,
Sam

Answer Source

Right now there isn't an option for this (I opened an issue for it).

A workaround is to subclass sympy.printing.ccode.CCodePrinter and override _print_Rational. This is the current definition:

def _print_Rational(self, expr):
    p, q = int(expr.p), int(expr.q)
    return '%d.0L/%d.0L' % (p, q)

So you can write something like

class MyCCodePrinter(CCodePrinter):
    def _print_Rational(self, expr):
        p, q = int(expr.p), int(expr.q)
        return '%d.0/%d.0' % (p, q)

You can then print expressions with MyCCodePrinter().doprint(expr).