2

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

samwise
  • 23
  • 4

1 Answers1

1

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).

asmeurer
  • 86,894
  • 26
  • 169
  • 240
  • Thanks, @asmeurer, that's a great help. Since I wanted to remove all occurrences of `L`, I then used `CCodePrinter._print_Rational = MyCCodePrinter._print_Rational` to rebind the `_print_Rational` function used by `sympy.printing.ccode()` to my subclass. This is exactly what I was looking for. – samwise Nov 10 '16 at 12:18
  • There's no need to monkey patch the SymPy code. You can print from your class with `doprint`. See my updated answer. – asmeurer Nov 10 '16 at 20:56
  • Ah thank you, that is much neater. Apologies, I'm quite new to Python. If I had enough rep to upvote your answer I would! – samwise Nov 24 '16 at 16:01