-
Notifications
You must be signed in to change notification settings - Fork 174
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
Added lower bound option to UniformHypersphere dist #799
Conversation
nengo/dists.py
Outdated
@@ -156,8 +156,10 @@ class UniformHypersphere(Distribution): | |||
|
|||
""" | |||
|
|||
def __init__(self, surface=False): | |||
def __init__(self, low=0, high=1, surface=False): |
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.
Docstring needs to be updated with these parameters, along with an explanation of how they affect the distribution.
Missing unit test. |
Haha. Yeah. I realized after making the pull request that I didn't do the tests for them. 😆 |
Doesn't this make the |
Edit: Ignore my previous comment. I think you are right. 😄 For backwards-compatibility I wouldn't want to remove the |
Yeah. There's some interaction between the |
Hmm, if I'm interpretting this right, setting samples *= rng.uniform(low=self.low ** d, high=self.high ** d, size=(n, 1)) ** (1.0 / d) That said, I'm not sure what the situation is you want these parameters for, so maybe they're more useful the way you have them -- I just thought I'd point out the possibility. :) |
Oh. I think you are right. haha |
Alrighty. I think I've addressed the issues listed here. |
nengo/dists.py
Outdated
self.high = max(high, self.low) | ||
|
||
if surface: | ||
self.low = self.high |
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.
This logic (of the interaction between high, low, and surface) should be documented in the parameters
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.
It is? (well, maybe not the surface one, but the rest are?)
I don't like, the interaction of the arguments and the possible to pass nonsensical combinations. With Not sure if there is a good way to work around this. Maybe deprecate |
That's my concern as well. And right now, the only documentation about this interaction is that "Values provided out of this range will be corrected", which i don't think is clear enough about what this interaction will do. I'm still not sure what the use case is for this change, but one possibility would be to get rid of @xchoo , what is the use case you're thinking of for this change? Would it work without |
Yup! It would work without high. Although, if that's the case, I would move to rename UniformHypersphere to UniformUnitHypersphere. |
But it's only unit if the radius is |
If you leave out |
(Also, the description of the class is |
I would vote against that renaming, just on backwards compatibility reasons. :) |
I guessssssssssss......... |
You could allow a number as argument for |
But how would you indicate if you want to have the points on the surface or not? E.g., you want a hypersphere of radius 2, and all points on the surface. |
Maybe we should implement two distributions: One samples from the whole hypersphere (with arguments |
Your documentation still doesn't indicate the interaction between surface and low. In particular, if surface is True, then low is ignored. Furthermore, your documentation still refers to the I will also note that, how it currently stands, setting surface to True gives exactly the same result as setting low to 1.0, and setting surface to False gives exactly the same result as setting low to 0.0. This suggests that you could also get rid of the |
But naming that parameter |
Hmm... I'd like to avoid bringing Also, before looking at an API change like that, I'd still like to know what the use case is for something like this. I've never wanted to sample from a uniform hyper-doughnut before -- why do we want that capability now? |
I do. Same logic as to why I use a Uniform distribution with a non-zero low when messing around with non standard intercepts. |
(i.e. I want to provide only valid sample points within the intercept ranges) |
It makes as much sense to me as |
I could use the name |
nengo/dists.py
Outdated
Default: False | ||
|
||
""" | ||
|
||
def __init__(self, surface=False): | ||
def __init__(self, min_magnitude=0, surface=False): |
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.
The new parameter should go after the existing surface
, just in case people were using it positionally. Note that this change will affect the position in the docstring and in __repr__
, too.
nengo/dists.py
Outdated
surface : bool | ||
Whether sample points should be distributed uniformly | ||
over the surface of the hyperphere (True), | ||
or within the hypersphere (False). | ||
Note: Setting surface to True generates sample points from the | ||
hypersphere surface regardless of what the value of min_magnitude is. |
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'd remove this note, and in the description of min_magnitude
say that it's ignored if surface == True
.
739daa7
to
f18d8b4
Compare
nengo/dists.py
Outdated
such that the sampled vector magnitudes >= min_magnitude. | ||
The default value and minimum value for min_magnitude is 0. | ||
The maximum value for min_magnitude is 1. Values outside this range | ||
will be clipped to this range. |
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.
Can this be more concise? e.g. "Lower bound on the returned vector magnitudes (i.e. magnitude >= min_magnitude). Must be in the range [0, 1]; defaults to 0. Ignored if surface == True
."
@hunse I fixed the rest of your comments and it's now passing all the tests. Thanks for being so throrough! Do you think it's ready to merge now? |
nengo/dists.py
Outdated
return "UniformHypersphere(%s)" % ( | ||
"surface=True" if self.surface else "") | ||
return "UniformHypersphere(min_magnitude=%s%r)" % ( | ||
", surface=True" if self.surface else "", self.min_magnitude,) |
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.
This is still not right. Also, min_magnitude should only appear if it's different from the default.
7344746
to
5176c6f
Compare
@hunse I did my best to fix your comments on this issue. Does it look okay now? |
224bf9a
to
17ee763
Compare
nengo/dists.py
Outdated
min_magnitude : Number, optional (Default: 0) | ||
Lower bound on the returned vector magnitudes (i.e. | ||
magnitude >= min_magnitude). Must be in the range [0, 1]; defaults | ||
to 0. Values outside this range will be clipped to this range. Ignored |
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 think this description is not entirely correct. If values outside of the range get clipped, I understand that values get sampled in the range [0, 1] and then everything below min_magnitude
will set to min_magnitude
(which will cluster vectors at min_magnitude
). But as I understand the code values are sampled from [min_magnitude, 1]
and thus are without clustering at min_magnitude
.
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 think all this docstring is saying is that values for min_magnitude
will be clipped to [0, 1]. I agree that we should have an exception instead of clipping. This is already done by the low
and high
in the parameter definition.
nengo/dists.py
Outdated
super(UniformHypersphere, self).__init__() | ||
self.min_magnitude = np.clip(min_magnitude, 0, 1) |
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 would prefer to raise an exception when min_magnitude
is outside of the range (which should happen by just removing the call to clip
because it should be checked by the NumberParam).
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 agree, and I think this is what caused @jgosmann's confusion with the docstring.
nengo/dists.py
Outdated
""" | ||
|
||
surface = BoolParam('surface') | ||
min_magnitude = NumberParam('min_magnitude', low=0, high=1) |
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.
Add high_open=True
so that we don't allow min_magnitude == 1
, which I think would cause problems because then we'd be sampling from an empty interval.
Ok, I've addressed @jgosmann's suggestions. |
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, @hunse!
Those changes look awesome. Thanks @hunse. I wasn't sure how much of the tests were redundant and how to fix 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.
This LGTM; I pushed a fixup to fix the changelog formatting (can't have spaces after / before the asterisks).
I share the concerns people have about the surface
and min_magnitude
parameters being slightly redundant... Unfortunately I think there's no way around this, since surface=True
is more clear than min_magntiude=1
. However, to at least be explicit when the two parameters are both set, I added warning when surface is True and min_magnitude > 0
in the fixup commit.
Will fix up history and merge when CI finishes, unless someone stops me in the next half hour or so!
1847d12
to
88ce22e
Compare
88ce22e
to
07c09ed
Compare
Added low and high options to UniformHypersphere distribution.