-
Notifications
You must be signed in to change notification settings - Fork 178
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
[stdlib_math] add is_close
routines.
#488
Conversation
Thanks, @zoziha. There's already PR #353 by @arjenmarkus which we reviewed a little bit, and discussed on a monthly call, but there didn't seem to be much enthusiasm from others. Perhaps we can revisit this now and get more feedback to see if people would like to see something like this in stdlib. Overall, I think it's in scope and useful. I like having a function like is_close(), and I like tolerant operators in #353. It'd be great if we can try and follow the Workflow, I think we'd more easily narrow down to a) whether a function/module is in scope; b) whether there is interest; c) what kind of API would people like to see. |
I would like to contribute to this, either in discussion or code ;). There
is a lot of misunderstanding regarding floating-point calculations and
comparisons.
Op do 19 aug. 2021 om 05:27 schreef Milan Curcic ***@***.***>:
… Thanks, @zoziha <https://github.com/zoziha>. There's already PR #353
<#353> by @arjenmarkus
<https://github.com/arjenmarkus> which we reviewed a little bit, and
discussed on a monthly call, but there didn't seem to be much enthusiasm
from others. Perhaps we can revisit this now and get more feedback to see
if people would like to see something like this in stdlib.
Overall, I think it's in scope and useful. I like having a function like
is_close(), and I like tolerant operators in #353
<#353>.
It'd be great if we can try and follow the Workflow
<https://github.com/fortran-lang/stdlib/blob/master/WORKFLOW.md>, I think
we'd more easily narrow down to a) whether a function/module is in scope;
b) whether there is interest; c) what kind of API would people like to see.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#488 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN6YR7IGW62AFX7VTAP6S3T5R2ZVANCNFSM5CNGXJEQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
.
|
There are two more related issues:
We should consider some of the other name suggestions too. Personally I am not convinced this needs a new module. Could the |
I also like the math module better for this. |
stdlib_logic
module and is_close
routines.stdlib_math
module and is_close
routines.
stdlib_math
module and is_close
routines.is_close
routines.
I re-improved bool = all(is_close(a, b [, rtol, atol])) In addition, when I was compiling the |
While you are following Warning The default atol is not appropriate for comparing numbers that are much smaller than one (see Notes).
Mainly for the reasons emphasized above, I personally tend to prefer the standard lib
For completeness' sake, I say this mainly as a "simple" user of isclose (e.g. when writing tests), not as a numerical algorithms practitioner deeply versed in the intricacies of floating point math. 😸 |
Thank you for your suggestion @bilderbuchi ! !! abs(a - b) <= rtol*max(abs(a), abs(b)) + atol
bool = [[stdlib_math(module):is_close(interface)]] (a, b [, rtol=1.0e-5, atol=0.0]) The value of |
I would not have expected the errors to be added together, but as mentioned I'm not a floating-point specialist. If there are no good reasons to do otherwise, I think there is value in following already established popular approaches, if only to make it easier for developers to be familiar with a function's behaviour (i.e. you can say in the docs "behaves like Julia and Python stdlib"). In this case, Julia's
It probably makes sense to just follow that, if you agree with my assesssment of Indeed, atol default should be 0.0, and rtol is probably a matter of taste. |
Maybe the API still needs discussion, but I just tried to update |
@zoziha do you think it in-scope/a reasonable effort to also add an array form of |
Also, I don't know where the stdlib lies on the spectrum between "complete features, seldomly changed" and "frequent iteration", but considering the API of
If that is not available, checking two arrays with missing values (nan) for closeness will never succeeed because two nans are never considered close. |
@bilderbuchi In fact, the Fortran language has limited support for arrays of uncertain rank.
interface all_close
logical function all_close_1(a, b, rel_tol, abs_tol)
real(rk), intent(in) :: a(:), b(:), rel_tol, abs_tol
end function all_close_1
logical function all_close_2(a, b, rel_tol, abs_tol)
real(rk), intent(in) :: a(:, :), b(:, :), rel_tol, abs_tol
end function all_close_2
...
end interface all_close
logical function all_close(a, b, rel_tol, abs_tol) result(close)
real(rk), intent(in) :: a(..), b(..), rel_tol, abs_tol
select rank(a)
rank(1)
select rank(b)
rank(1)
close = all(is_close(a, b, rel_tol, abs_tol))
rank default
error stop "The ranks of a and b are not equal"
end select
rank(2)
select rank(b)
rank(2)
close = all(is_close(a, b, rel_tol, abs_tol))
rank default
error stop "The ranks of `a` and `b` are not equal"
end select
...
rank default
error stop "The rank of `a` is too large to be supported"
end select
end function all_close |
Because But it seems that 14 | select rank(a)
| 1
Error: Unclassifiable statement at (1)
/home/runner/work/stdlib/stdlib/build/src/stdlib_math_all_close.f90:22:15: |
Yes, according to their feature page, https://gcc.gnu.org/wiki/Fortran2018Status, select rank has been implemented for v10.0 in October 2019. |
Because gcc9.0 used by |
So far we follow GCC's recommendation of supported releases. Once GCC 12 is available, GCC 9 will most likely get dropped and we can upgrade our requirements for stdlib. |
for `**_close` in stdlib_math.
I added the |
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.
Thank you @zoziha . Here are some comments and suggestions.
1.0e-9 -> sqrt(epsilon(..))
Three changes:
|
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.
Thanks, looks good to me.
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 only have a small edit. I'll commit it and merge this PR.
Thank you @zoziha
|
||
contains | ||
|
||
#! Determines whether the values of `a` and `b` are close. |
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.
#! Determines whether the values of `a` and `b` are close. | |
! Determines whether the values of `a` and `b` are close. |
is_close
forreal/complex
value tests and checksrel_tol/abs_tol
all_close
. (gcc 9.0 not supportselect rank
)(usestdlib_stats
solution)is_close/all_close
(need to discuss) [stdlib_math] addis_close
routines. #488 (comment)fypp
style tests.sqrt(epsilon(..))
Decsription
When we are testing,
is_close
andall_close
are very useful.APIs are:
Prior Arts