Error in dt comparison due to float64 precision #99
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I have added a small margin to comparisons checking for the minimum instruction duration. In Runmanager, for particular requested transition times (that I knew to be allowed), I was getting this error:
File "C:\Users\rorys\anaconda3\lib\site-packages\labscript\labscript.py", line 828, in collect_change_times raise LabscriptError( labscript.labscript.LabscriptError: Commands have been issued to devices attached to Narwhal_Devices_Pulse_Generator_pseudoclock at t=3.0000000000000004e-08 and t=4e-08. This Pseudoclock cannot support update delays shorter than 1e-08 seconds. Compilation aborted.
Some "common" float64 values don't store "exactly". eg 40 nanoseconds compared with 30nanoseconds:
In [1]: 4*10E-9 Out[1]: 4e-08 In [2]: 3*10E-9 Out[2]: 3.0000000000000004e-08
So what is happening in the affected lines is this:
In [4]: (4*10E-9 - 3*10E-9) < 1*10E-9 Out[4]: True
Which raises the LabscriptError.
I have subtracted a small mI have added a small margin to comparisons checking for the minimum instruction duration. In Runmanager, for particular requested transition times (that I knew to be allowed), I was getting this error:
File "C:\Users\rorys\anaconda3\lib\site-packages\labscript\labscript.py", line 828, in collect_change_times raise LabscriptError( labscript.labscript.LabscriptError: Commands have been issued to devices attached to Narwhal_Devices_Pulse_Generator_pseudoclock at t=3.0000000000000004e-08 and t=4e-08. This Pseudoclock cannot support update delays shorter than 1e-08 seconds. Compilation aborted.
Some "common" float64 values don't store "exactly". eg 40 nanoseconds compared with 30nanoseconds:
In [1]: 4*10E-9 Out[1]: 4e-08 In [2]: 3*10E-9 Out[2]: 3.0000000000000004e-08
So what is happening in the affected lines is this:
In [4]: (4*10E-9 - 3*10E-9) < 1*10E-9 Out[4]: True
Which raises the LabscriptError.
I have subtracted a small margin from four instances where this seemed to likely affect the code. Only I only got errors for three of them, but it seemed likely that the 4th might just not have been "triggered" by the specific instructions I tried.
I'm not exactly sure how common these numbers are, but they aren't uncommon:
In [11]: a = np.arange(0, 100E-9, 10E-9) In [12]: [print(x) for x in a] Out [12]: 0.0 1e-08 2e-08 3.0000000000000004e-08 4e-08 5e-08 6.000000000000001e-08 7e-08 8e-08 9e-08
Other methods of adding a margin to account for float precision also worked, eg
if dt < 1.0/self.clock_limit*0.999999999999999:
works just fine. So use whatever you like. I prefer the explicit addition of epsilon.I tested this only on Windows 11, running Python 3.8.16. Though I suspect it hasn't changed for newer versions.