You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Float comparison issues with time and quantity #6970
Actually, it is a bit of a stranger rounding problem: since hours are not a constant fraction of a day, the time is converted to TAI before the duration is subtracted, and then converted back to UTC. The problem doesn't happen if we start with TAI:
In [15]: start = Time('2016-02-06 03:00:00', scale='tai')
In [16]: end_time = start + duration
In [17]: end_time - duration == start
Out[17]: True
I think the underlying cause of the change is #6653 - I think the problem it fixed is greater than this one, though.
Yes, I think any tests like this on time should test closeness (<1ns is reasonable) rather than equality.
Actually I'm not sure I agree there. You never know when someone really wanted to check that it's closer than 1 ns...? Same reason why we don't do equality in coordinates et al - "equals" really is ambiguous here if you don't mean literally bit-wise equality...?
@eteq - the comment was about tests on round-tripping. Since this depends on float rounding working the way we want, I don't think we can guarantee equality, so all I am suggesting is that we do not use __eq__ in tests, not that we adjust the meaning of __eq__!
Hi Patrick,
I understand you have been in touch last Summer with Tim Jenness (CC'd)
about a small round-trip problem in astropy, which we traced back to
SOFA (see
https://github.com/astropy/astropy/issues/6970#issuecomment-351461606).
I found a fix for it already at the time, and vaguely recall trying to
pass it on, but apparently it never made it, so let me try here again.
The problem is that UTC->TAI->UTC does not roundtrip, even though there
really is nothing to prevent it from doing so if one is careful with how
floats are dealt with. In this case, the patch is very simple:
diff jd2cal.c~ jd2cal.c
85c85
< d2 -= 0.5;
---
> d1 -= 0.5;
Here, the trick is to subtract 0.5 from the larger of the two doubles.
Since this is always a large positive number, the subtraction of 0.5 is
guaranteed to be exact, while for the smaller of the two doublds, this
is not the case. The same change should be made in jdcalf.c.:
diff jdcalf.c~ jdcalf.c
91c91
< d2 -= 0.5;
---
> d1 -= 0.5;
For a regression test, you might want to use the attached additional
test (note the negative input value of d2; by subtracting 0.5 one looses
one bit of precision). Note that this is for the specific issue we
found, so it covers jd2cal (indirectly) but not jdcalf. It might be
better to have a specific test for jd2cal itself.
With all best wishes,
Marten
p.s. It would be so good if SOFA got an issue tracker, or even better
allowed pull requests, or at least have a git version so one can
send e-mail patches.
--
Prof. M. H. van Kerkwijk
Dept. of Astronomy & Astroph., 50 St George St., Toronto, ON, M5S 3H4, Canada
McLennan Labs, room 1203B, tel: +1(416)9467288, fax: +1(416)9467287
[email protected], http://www.astro.utoronto.ca/~mhvk
diff t_sofa_c.c~ t_sofa_c.c
9630a9631,9661
> static void t_utctaiutc(int *status)
> /*
> ** - - - - - - - - -
> ** t _ u t c t a i
> ** - - - - - - - - -
> **
> ** Test iauUtctai and iauTaiutc functions, verifying roundtrip.
> **
> ** Returned:
> ** status int FALSE = success, TRUE = fail
> **
> ** Called: iauUtctai, iauTaiutc, vvd, viv
> **
> ** This revision: 2020 April 8
> */
> {
> double u1, u2, t1, t2, ru1, ru2;
> int j;
>
> u1 = 2457425.0;
> u2 = -0.375;
>
> j = iauUtctai(u1, u2, &t1, &t2);
> viv(j, 0, "iauUtctai", "j", status);
> j = iauTaiutc(t1, t2, &ru1, &ru2);
> viv(j, 0, "iauTaiutc", "j", status);
> vvd(ru1, u1, 0., "iauUtctai,iauTaiutc", "ru1", status);
> vvd(ru2, u2, 0., "iauUtctai,iauTaiutc", "ru2", status);
>
> }
>
10140a10172
> t_utctaiutc(&status);
After quite a bit of back and forth with Pat, he convinced me that perfect roundtripping was simply impossible, since adding and subtracting the UTC-TAI difference cannot always be done without precision loss. But with fixes to jd2cal (the above plus some extra), at least the maximum precision loss has been reduced by a factor 4.
Given this, I think the remaining to-do issue is to add documentation that for times in UTC, round-tripping errors can cause even adding 0 seconds to give a non-identical time.
Activity
mhvk commentedon Dec 12, 2017
This is weird. Same problem on master, but
It clearly is some kind of rounding problem, though:
mhvk commentedon Dec 12, 2017
Actually, it is a bit of a stranger rounding problem: since hours are not a constant fraction of a day, the time is converted to
TAIbefore the duration is subtracted, and then converted back toUTC. The problem doesn't happen if we start withTAI:I think the underlying cause of the change is #6653 - I think the problem it fixed is greater than this one, though.
mhvk commentedon Dec 12, 2017
p.s.
integerforTimeis days; 2 hours = 1/12 of a day, so not exactly representable in binary.[-]Float comparison issues with time and "integer" quantity[/-][+]Float comparison issues with time and quantity[/+]mhvk commentedon Dec 12, 2017
A bit further investigation: it is a round-trip error in converting from utc to tai:
Note that it is just unlucky rounding. The same happens in 2.0.2 if I ensure input is rounded as it normally is:
mhvk commentedon Dec 13, 2017
Checking even further, it boils down to
erfanot quite round-tripping:I can make the particular problem go away with a small change in
jd2cal. Arguably, it is now an upstream problem.bsipocz commentedon Dec 13, 2017
@mhvk - Thanks for investigating. Take away for downstream will be to adjust those tests as all of it is upstream from astroplan.
mhvk commentedon Dec 13, 2017
Yes, I think any tests like this on time should test closeness (<1ns is reasonable) rather than equality.
eteq commentedon Mar 15, 2018
Actually I'm not sure I agree there. You never know when someone really wanted to check that it's closer than 1 ns...? Same reason why we don't do equality in
coordinateset al - "equals" really is ambiguous here if you don't mean literally bit-wise equality...?mhvk commentedon Mar 15, 2018
@eteq - the comment was about tests on round-tripping. Since this depends on float rounding working the way we want, I don't think we can guarantee equality, so all I am suggesting is that we do not use
__eq__in tests, not that we adjust the meaning of__eq__!astrojuanlu commentedon May 13, 2018
Maybe it's because of #6653?
astrojuanlu commentedon May 13, 2018
Sorry for the noise, @mhvk said exactly that - should have "Ctrl+F"-ed.
mhvk commentedon Mar 25, 2019
Looking at older issues, I think the summary here is whether it is worth trying to improve round-tripping for ERFA/SOFA, and push that upstream.
mhvk commentedon Apr 8, 2020
Sent the following to SOFA:
mhvk commentedon Apr 10, 2020
After quite a bit of back and forth with Pat, he convinced me that perfect roundtripping was simply impossible, since adding and subtracting the UTC-TAI difference cannot always be done without precision loss. But with fixes to
jd2cal(the above plus some extra), at least the maximum precision loss has been reduced by a factor 4.Given this, I think the remaining to-do issue is to add documentation that for times in UTC, round-tripping errors can cause even adding 0 seconds to give a non-identical time.