SymbolicUtils.jl icon indicating copy to clipboard operation
SymbolicUtils.jl copied to clipboard

lazy evaluation of rational powers

Open mxhbl opened this issue 1 year ago • 3 comments

Rational powers are currently eagerly evaluated, so that, for example,

using SymbolicUtils
@syms x
(2x) ^ (1//2) == 1.414… * x^(1//2)
simplify(term(^, 2, 1//2)) == 1.414…

and so on. While this might be intentional, it often causes precision loss and makes many analytical expressions rather ugly.

This PR adds branches to basicsymbolic and ^ to prevent evaluation of powers if the base is a literal number and the exponent is a rational. Integer or float exponents still get evaluated. With this PR, we therefore have behavior like

(2x) ^ (1//2) ==  2^(1//2) * x^(1//2)
simplify(term(^, 2, 1//2)) == 2^(1//2)
simplify(term(^, 1//3, 2)) == 1//9
simplify(term(^, 2, 0.5)) == 1.414…

However, there is a small quirk. Currently (2x) ^ 2 results in (4//1) * x^2, i.e. the integer prefactor is converted to a rational, due to the behavior of the unstable_pow function. I am not sure if this is intentional and I did not follow this conversion in the code in this PR. This means with this PR and a rational exponent, we have (2x) ^ (2//1) == 4 * x^(2//1). I guess if this PR gets merged, this behavior should be made consistent, one way or another.

I am curious if this all sounds like a reasonable change, or if there other reasons why immediate evaluation of all powers is preferable — please let me know what you think!

mxhbl avatar Aug 28 '24 12:08 mxhbl

Benchmark Results

master e06f2c78ec761e... master/e06f2c78ec761e...
overhead/acrule/a+2 0.728 ± 0.016 μs 0.757 ± 0.019 μs 0.962
overhead/acrule/a+2+b 0.698 ± 0.013 μs 0.725 ± 0.017 μs 0.962
overhead/acrule/a+b 0.251 ± 0.0089 μs 0.258 ± 0.0097 μs 0.975
overhead/acrule/noop:Int 25.1 ± 0.92 ns 26.2 ± 0.91 ns 0.955
overhead/acrule/noop:Sym 0.0365 ± 0.005 μs 0.0368 ± 0.0054 μs 0.992
overhead/rule/noop:Int 0.0441 ± 0.0012 μs 0.0443 ± 0.00084 μs 0.997
overhead/rule/noop:Sym 0.0549 ± 0.0023 μs 0.0548 ± 0.003 μs 1
overhead/rule/noop:Term 0.0547 ± 0.0022 μs 0.055 ± 0.003 μs 0.994
overhead/ruleset/noop:Int 0.128 ± 0.0042 μs 0.129 ± 0.0032 μs 0.99
overhead/ruleset/noop:Sym 0.148 ± 0.0041 μs 0.16 ± 0.0066 μs 0.927
overhead/ruleset/noop:Term 3.12 ± 0.12 μs 3.09 ± 0.1 μs 1.01
overhead/simplify/noop:Int 0.144 ± 0.004 μs 0.14 ± 0.0032 μs 1.03
overhead/simplify/noop:Sym 0.158 ± 0.0055 μs 0.159 ± 0.0065 μs 0.995
overhead/simplify/noop:Term 0.0354 ± 0.0024 ms 0.0378 ± 0.0022 ms 0.936
overhead/simplify/randterm (+, *):serial 0.0838 ± 0.0012 s 0.0897 ± 0.00082 s 0.935
overhead/simplify/randterm (+, *):thread 0.0503 ± 0.03 s 0.0518 ± 0.029 s 0.97
overhead/simplify/randterm (/, *):serial 0.209 ± 0.0067 ms 0.223 ± 0.0078 ms 0.939
overhead/simplify/randterm (/, *):thread 0.236 ± 0.0075 ms 0.254 ± 0.0088 ms 0.929
overhead/substitute/a 0.0582 ± 0.0014 ms 0.0576 ± 0.0014 ms 1.01
overhead/substitute/a,b 0.0511 ± 0.0015 ms 0.0515 ± 0.0014 ms 0.993
overhead/substitute/a,b,c 16.9 ± 0.61 μs 17.6 ± 0.73 μs 0.963
polyform/easy_iszero 28.7 ± 1.7 μs 29.5 ± 1.7 μs 0.972
polyform/isone 2.79 ± 0.01 ns 2.79 ± 0.01 ns 0.997
polyform/iszero 1.11 ± 0.03 ms 1.12 ± 0.032 ms 0.991
polyform/simplify_fractions 1.61 ± 0.043 ms 1.6 ± 0.044 ms 1.01
time_to_load 2.1 ± 0.01 s 2.13 ± 0.023 s 0.988

Benchmark Plots

A plot of the benchmark results have been uploaded as an artifact to the workflow run for this PR. Go to "Actions"->"Benchmark a pull request"->[the most recent run]->"Artifacts" (at the bottom).

github-actions[bot] avatar Aug 28 '24 12:08 github-actions[bot]

Done! Let me know if there is anything else.

mxhbl avatar Aug 29 '24 15:08 mxhbl

:warning: Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 82.07%. Comparing base (0288135) to head (2daeb7e). Report is 3 commits behind head on master.

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #641      +/-   ##
==========================================
+ Coverage   81.86%   82.07%   +0.20%     
==========================================
  Files          16       16              
  Lines        1908     1919      +11     
==========================================
+ Hits         1562     1575      +13     
+ Misses        346      344       -2     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov-commenter avatar Aug 29 '24 16:08 codecov-commenter