JuliaSymbolics / Symbolics.jl

Symbolic programming for the next generation of numerical software
https://docs.sciml.ai/Symbolics/stable/
Other
1.37k stars 153 forks source link

Substitute with `fold=true` does not preserve rationals #1299

Open hersle opened 1 month ago

hersle commented 1 month ago

It is annoying that

@variables x
substitute(1//2 * cos(x), x => 0)

gives 0.5 and not 1//2.

The reason is natural: cos(0) evaluates to 1.0 (not 1), giving (1//2) * 1.0, which is converted to 0.5. Is there a way to fix this?

ChrisRackauckas commented 1 month ago

@shashi is this intended?

shashi commented 2 weeks ago

well it's incidental like the OP said. Maybe fold could call a narrow_type function which turns floats into integers if is_integer is true.

hersle commented 2 weeks ago

How about if SymbolicUtils.simplify() by default uses the rule

using SymbolicUtils
r = @rule (~x::SymbolicUtils._isinteger) => Int(~x)

Then

r(7.0) # outputs 7

If you think this would work, can you point me to where I should add it for it to work on nested expressions? Like

@syms x
r(7.0*x) # should output 7x

I am not familiar enough with Symbolics to know how it should be added.

ChrisRackauckas commented 2 weeks ago

That's a nice idea. It would probably go in https://github.com/JuliaSymbolics/SymbolicUtils.jl/blob/master/src/simplify_rules.jl