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
Improved implementation of shooting point selector pick (avoid model that might introduce index error in subclasses) #1110
Conversation
…selector pick implementation
Codecov Report
@@ Coverage Diff @@
## master #1110 +/- ##
==========================================
- Coverage 81.76% 81.75% -0.01%
==========================================
Files 142 142
Lines 15612 15612
==========================================
- Hits 12765 12764 -1
- Misses 2847 2848 +1
Continue to review full report at Codecov.
|
Huh, I don't think I have ever seen someone run into that bound xD Do you mind adding a test for that, probably by overriding |
Hmm, I copied the test to the current I do agree with this fix, but I am a bit puzzled by how this can even be hit.
Did you somehow run this with a random number generator that has |
Hm. Strange that they pass. But maybe not so strange afterall, I agree with your judgment that the first condition should be enough to not start the loop again when we summed up all probabilities. I guess the issue was floating point inaccuracies, i.e. that Admittedly the error came from my own selector which now has (in the relevant part of rand = np.random.random() * sum_bias
idx = 0
prob = biases[0]
while prob <= rand and idx < len(biases) - 1:
idx += 1
prob += biases[idx] And before did not have the |
The problem is is that However, there is a second way to trigger that bug: if all biases are |
I do check for the sum of all biases to not be 0, so yes. For reference, the full code for my own def pick(self, trajectory):
"""Return the index of the chosen snapshot within trajectory."""
biases = self._biases(trajectory)
sum_bias = np.sum(biases)
if sum_bias == 0.:
logger.error('Model not able to give educated guess.\
Choosing based on luck.')
# we can not give any meaningfull advice and choose at random
return np.random.randint(len(trajectory))
rand = np.random.random() * sum_bias
idx = 0
prob = biases[0]
while prob <= rand and idx < len(biases) - 1:
idx += 1
prob += biases[idx]
# let the model know which SP we chose
self.model.register_sp(trajectory[idx])
return idx |
Ah yeah, I think numpy does something clever I do still agree with the fix. I just was a bit puzzled For your own selector, you probably instead want use biases = np.array(self._biases(trajectory))
biases /= np.sum(biases)
idx = np.random.choice(len(trajectory), p=biases) |
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'm fine with the change -- it feels like safer code to me. But I think you're right that the issue is mixing in np.sum
; we're always using left-to-right summation. Because of that, I think we're actually safe from this already (only because we happened to use regular sum
-- I would not have thought of this issue while writing the code!)
This code is an improvement and a better model for others implementing selectors, so accepting it. Marking is as misc PR though (not bugfix).
After 5 years of using ops it bit me today, for the old implementation it was possible to have
idx == len(prob_list)
in the last iteration which would then raise anIndexError
when trying to get the associated probability from prob_list.Or in other words in 5 years of ops I never tried to select the last frame of a trajectory as new shooting point, which is a good thing I would say :)
EDIT: typo