-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
GH-44903: [C++] Add the Expm1(exponent) scalar arithmetic function #44904
Conversation
`Expm1(exponent)` is a more accurate way of computing `Exp(exponent) - 1.0` for small values of exponent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM in general. Just a couple minor comments.
"[-0.6321205588285577, 0.0, null, 22025.465794806718]"); | ||
// Ordinary arrays (positive, negative, fractional, and zero inputs) | ||
this->AssertUnaryOp( | ||
expm1, "[-10.0, 0.0, 0.5, 1.0]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: since the main point of expm1
is to be more precise when the input is close to zero, shouldn't we focus on this use case here? Though of course this is all dependent on the stdlib's implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added 0.0 but you're right about the need for other tiny numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. Only one nit.
const FunctionDoc expm1_doc{ | ||
"Compute Euler's number raised to the power of specified exponent, " | ||
"then decrement 1, element-wise", | ||
("If exponent is null the result will be null."), | ||
{"exponent"}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we mention that "this is more accurate than directly computing exp(value) - 1
" in the function doc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered it, but I think it's better to keep this succinct. expm1
is very googlable and explaining why it's more accurate in a short phrase isn't easy.
R test failures seem unrelated. I will merge soon if no one is against it. |
After merging your PR, Conbench analyzed the 3 benchmarking runs that have been run so far on merge-commit 5e476b3. There were 132 benchmark results with an error:
There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 32 possible false positives for unstable benchmarks that are known to sometimes produce them. |
Expm1(exponent)
is a more accurate way of computingExp(exponent) - 1.0
for small values of exponent.Rationale for this change
expm1(x)
is specifically designed to computeexp(x)−1
more accurately, particularly for small x. It uses numerical techniques and approximations that minimize the loss of precision.When x is very small (close to 0),
exp(x)
is approximately1+x
. Subtracting 1 fromexp(x)
(i.e.,(exp(x)−1)
can result in significant cancellation of significant digits due to floating-point arithmetic, leading to a loss of precision).For example:
When
x = 10^−8
,exp(x)
is close to1 + 10^−8
, so subtracting 1 leaves only the small10^−8
, which may lose accuracy due to floating-point limitations.Are these changes tested?
Yes.
Are there any user-facing changes?
Yes and documentation was updated to list the new function.