-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggest more-accurate float functions for hand-written formulas #2040
Comments
Just as a sidenote: https://github.com/mcarton/rust-herbie-lint is a project which would also figure out more elaborate transformations but unfortunately hasn't been been update in a year. The actual tool Herbie had a 1.0 release in June so maybe some folks which are familiar with compiler internals could revive rust-herbie-lint. (I failed miserably the last time I tried...) |
Herbie looks like a fantastic tool; it'd be great if we could leverage that somehow. |
For good reason: it's almost as accurate as (Check out glibc's implementation at https://github.com/lattera/glibc/blob/master/math/w_hypot.c and https://github.com/lattera/glibc/blob/master/sysdeps/ieee754/dbl-64/e_hypot.c to see the difference.) It would still make sense in a explicit "lint-for-numeric-accuracy" mode (and Herbie would be amazing for that), but questionable for a default lint. The other suggestions all seem like much more likely wins. |
You do make a good point, @jpetkau, and I think it would make sense to allow configuring the lint to prefer either performance or accuracy. |
…nctions, r=flip1995 Add lint to improve floating-point expressions Looks for floating-point expressions that can be expressed using built-in methods to improve accuracy, performance and/or succinctness. changelog: Add lint `floating_point_improvements`. Fixes #4726 Partly addresses [#2040](#2040) Currently linted expressions: | Expression | Suggestion | |---------------------------------|------------| | x.log(2.0) | x.log2() | | x.log(10.0) | x.log10() | | x.log(std::f32::consts::E) | x.ln() | | (1 + x).ln() | x.ln_1p() | | (2.0).powf(x) | x.exp2() | | (std::f32::consts::E).powf(x) | x.exp() | | x.powf(1/2) | x.sqrt() | | x.powf(1/3) | x.cbrt() | | x.powf(y), where y is whole | x.powi(y) | | x.exp() - 1 | x.exp_m1() | |x * y + z|x.mul_add(y, z)|
I'd liike to tackle the remaining suggestions on this issue. As I understand it, they are:
|
Some accuracy lints for floating point operations This will add some lints for accuracy on floating point operations suggested by @clarfon in #2040 (fixes #2040). These are the remaining lints: - [x] x.powi(2) => x * x - [x] x.logN() / y.logN() => x.logbase(y) - [x] x.logbase(E) => x.log() - [x] x.logbase(10) => x.log10() - [x] x.logbase(2) => x.log2(). - [x] x * PI / 180 => x.to_radians() - [x] x * 180 / PI => x.to_degrees() - [x] (x + 1).log() => x.log_1p() - [x] sqrt(x * x + y * y) => x.hypot(y) changelog: Included some accuracy lints for floating point operations
Some accuracy lints for floating point operations This will add some lints for accuracy on floating point operations suggested by @clarfon in rust-lang#2040 (fixes rust-lang#2040). These are the remaining lints: - [x] x.powi(2) => x * x - [x] x.logN() / y.logN() => x.logbase(y) - [x] x.logbase(E) => x.log() - [x] x.logbase(10) => x.log10() - [x] x.logbase(2) => x.log2(). - [x] x * PI / 180 => x.to_radians() - [x] x * 180 / PI => x.to_degrees() - [x] (x + 1).log() => x.log_1p() - [x] sqrt(x * x + y * y) => x.hypot(y) changelog: Included some accuracy lints for floating point operations
Some accuracy lints for floating point operations This will add some lints for accuracy on floating point operations suggested by @clarfon in #2040 (fixes #2040). These are the remaining lints: - [x] x.powi(2) => x * x - [x] x.logN() / y.logN() => x.logbase(y) - [x] x.logbase(E) => x.log() - [x] x.logbase(10) => x.log10() - [x] x.logbase(2) => x.log2(). - [x] x * PI / 180 => x.to_radians() - [x] x * 180 / PI => x.to_degrees() - [x] (x + 1).log() => x.log_1p() - [x] sqrt(x * x + y * y) => x.hypot(y) changelog: Included some accuracy lints for floating point operations
Were all of the things listed in the OP implemented in the merged PR? Not sure if this should be kept open or not |
cc @thiagoarrais do you know if some of the suggestions in the OP are still missing? |
Thanks for checking! Just wanted to make sure nothing got missed. :) |
Last summer I worked with MATLAB code that was copied-down from equations directly, when floating point math allows for a lot of optimisations that aren't always obvious, like
exp_m1
. Here are a few lints I thought of that specifically apply to floats:a * b + c => a.mul_add(b, c)
x.powf(y) => x.powi(y)
(wheny
is an integer)x.powi(2) => x * x
2.powf(x) => x.exp2()
x.logN() / y.logN() => x.logbase(y)
x.logbase(E) => x.log()
x.logbase(10) => x.log10()
x.logbase(2) => x.log2()
.x * PI / 180 => x.to_radians()
x * 180 / PI => x.to_degrees()
x.powf(1/3) => x.cbrt()
(not equivalent, but almost certainly what was meant)x.powf(1/2) => x.sqrt()
x.exp() - 1 => x.exp_m1()
(x + 1).log() => x.log_1p()
sqrt(x * x + y * y) => x.hypot(y)
(I see this one used a lot)Obviously we can't catch every case, and these would be best as hints rather than suggestions, but it'd be nice to at least suggest these options to the user so that they're aware that they exist.
I think that the scope of this should be limited to just suggesting builtin functions for now because the list of mathematical identities is way too large for clippy to incorporate. People who do things like
x.log() + y.log()
instead of(xy).log()
can simplify their equations themselves, but people who don't know thatx.hypot(y)
exists for example should be made aware.The text was updated successfully, but these errors were encountered: