0

Seems like SymPy makes it pretty easy to do the opposite - convert all floats to ints, but I'm curious how to do the reverse?

The specific problem I'm running into is with the RustCodeGen spitting out expressions with mixed f64/int types, which makes the compiler unhappy.

Any suggestions on ways to get around this programmatically would be greatly appreciated!

Simple example:

>> variables = [symbols('x1')]
>> expression = 'x1 % 0.5'
>> expr = parse_expr(expression, evaluate=0)
>> print(expr)  # Notice it has injected a multiply by 2 
0.5*(Mod(2*x1, 1))
>> CG = RustCodeGen()
>> routine = CG.routine("", expr, variables, {})
>> CG._call_printer(routine)
['let out1 = 0.5*(2*x1 - (2*x1).floor());\n', 'out1', '\n']

which doesn't compile:

error[E0277]: cannot multiply `{integer}` by `{float}`
 --> src/main.rs:5:22
  |
5 |     let out1 = 0.5*(2*x1 - (2*x1).floor());
  |                      ^ no implementation for `{integer} * {float}`

1 Answers1

1

I would recommend faking the integer with a symbol having desired float name:

>>> f= expr.xreplace({i:Symbol(str(i)+".") for i in expr.atoms(Integer)})
>>> routine = CG.routine("", f, variables, {})
>>> CG._call_printer(routine)```
smichr
  • 16,948
  • 2
  • 27
  • 34
  • Thanks! I like this approach, but it now raises this error: ```sympy.utilities.codegen.CodeGenArgumentListError: ("Argument list didn't specify: 1.0, 2.0 ", [InputArgument(1.0), InputArgument(2.0)])```, so I think argument fields need to be updated as well? – Chris Sullivan Dec 03 '22 at 03:16
  • Can you specify a value for a variable in the call to codegen? Is that what the dictionary argument is for? `{Symbol('1.'):1.0, Symbol('2.'):2.0}` – smichr Dec 03 '22 at 03:28
  • Interestingly, wrapping it in a string so it's re-evaluated seems to work? ```routine = CG.routine("", str(f), variables, {})``` – Chris Sullivan Dec 03 '22 at 03:29
  • I thought it would do that automatically, but that was the intent. The idea is that SymPy wants to make the expression canonical wrt floats so you can circumvent that by replacing Integer with symbols that look like floating versions of the same and when it is parsed (as a string) the parser can't tell the difference. – smichr Dec 03 '22 at 05:30