Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not contract X*X*X to pow(X,3) in sympy's `printing.ccode` method

I have a sympy equation that I need to translate to CUDA.

In its default configuration, sympy.printing.ccode will transform the expression x*x into pow(x,2) which unfortunately, CUDA behaves a bit strangely with (e.g. pow(0.1,2) is 0 according to CUDA).

I would prefer sympy.printing.ccode to leave these kinds of expressions unaltered, or put another way, I would like it to expand any instance of pow into a simple product. E.g. pow(x,4) would become x*x*x*x -- does anyone know how to make this happen?

like image 890
weemattisnot Avatar asked Sep 15 '25 20:09

weemattisnot


1 Answers

This should do it:

>>> import sympy as sp
>>> from sympy.utilities.codegen import CCodePrinter
>>> print(sp.__version__)
0.7.6.1
>>> x = sp.Symbol('x')
>>> CCodePrinter().doprint(x*x*x)
'pow(x, 3)'
>>> class MyCCodePrinter(CCodePrinter):
...     def _print_Pow(self, expr):
...         if expr.exp.is_integer and expr.exp.is_number:
...             return '(' + '*'.join([self._print(expr.base)]*expr.exp) + ')'
...         else:
...             return super(MyCCodePrinter, self)._print_Pow(expr)
... 
>>> MyCCodePrinter().doprint(x*x*x)
'x*x*x'

Note that this was a proposed change (with a restriction on this size of the exponent) for a while. Then the motivation was performance of regular C code, but flags such as -ffast-math made to point moot. However if this is something that is useful for CUDA code we should definitely support the behaviour through a setting, feel free to open an issue for it if you think it is needed.

like image 153
Bjoern Dahlgren Avatar answered Sep 19 '25 14:09

Bjoern Dahlgren