Repository navigation
BUG, API: np.random.multivariate_normal behavior with bad covariance matrix - #5726
Conversation
|
Just as a technical comment, is there a reason to use |
|
The was a discussion for switching to eigh, or cholesky. eigh seems better. here but that seemed out of scope of this PR, but it is on my todo list. In the code there is a comment that says |
|
OK, sorry for rehashing the old discussion. |
|
Needs to be discussed on the list. Another option is to add a |
|
@charris I'll ping the list. On Travis-CI a This doesn't happen on my local machine, what is different on Travis-CI? |
|
Try |
|
Note that symettry and almost positive semidefinite can be checked with the svd. Something like The tolerances for |
|
@charris It didn't generate much discussion on list (link), but I think @josef-pkt's comments were helpful. To summarize, instead of seperate kwargs for checking symmetry, and PSDness, just one kwarg |
|
@charris Rehashed this. Basically we now allow for small floating point errors in the covariance matrix. And I added a |
|
ping @josef-pkt |
There was a problem hiding this comment.
I would be the entire next part under
if check_valid != 'ignore':
no reason to check if we 'ignore'
In np.random.multivariate_normal allow the covariance matrix to have small floating point errors. And allow control over what to do if the PSD check fails.
Test that warnings are or are not raised when check_valid kwarg is used.
|
☔ The latest upstream changes (presumably #7082) made this pull request unmergeable. Please resolve the merge conflicts. |
You managed to confuse GitHub, haven't seen that before:) Have you taken over this PR, and is it ready to merge? |
|
Yes, I just took over this PR. It should be ready to commit (it was just a matter of cleaning up a bit the test). |
|
Okay thanks. I'll review it now then, before we forget about it again. |
| generated, and packed in an `m`-by-`n`-by-`k` arrangement. Because | ||
| each sample is `N`-dimensional, the output shape is ``(m,n,k,N)``. | ||
| If no shape is specified, a single (`N`-D) sample is returned. | ||
| check_valid : 'warn', 'raise', 'ignore' |
There was a problem hiding this comment.
formatting: change to {'warn', 'raise', 'ignore'}, optional
| each sample is `N`-dimensional, the output shape is ``(m,n,k,N)``. | ||
| If no shape is specified, a single (`N`-D) sample is returned. | ||
| check_valid : 'warn', 'raise', 'ignore' | ||
| Behavior when the covariance matrix is not Positive Semi-definite. |
There was a problem hiding this comment.
style nitpick: use lower case for positive semidefinite
| If no shape is specified, a single (`N`-D) sample is returned. | ||
| check_valid : 'warn', 'raise', 'ignore' | ||
| Behavior when the covariance matrix is not Positive Semi-definite. | ||
| tol : float |
| if mean.shape[0] != cov.shape[0]: | ||
| raise ValueError("mean and cov must have same length") | ||
| raise ValueError("mean and cov must have same length") | ||
|
|
There was a problem hiding this comment.
Can you add a check for check_valid being one of the 3 accepted strings?
There was a problem hiding this comment.
actually, move it from line 4511 up here. It's misplaced there; only checked for when not psd.
There was a problem hiding this comment.
note that the check is itself later in the code, when checking. However, it may go unchecked when the psd passes, so I have rearranged the logic so it is always checked.
| check_valid : 'warn', 'raise', 'ignore' | ||
| Behavior when the covariance matrix is not Positive Semi-definite. | ||
| tol : float | ||
| Tolerance of the singular values in covariance matrix. |
There was a problem hiding this comment.
absolute or relative tolerance?
| RuntimeWarning) | ||
|
|
||
| if check_valid != 'ignore': | ||
| psd = np.allclose(np.dot(v.T * s, v), cov) |
There was a problem hiding this comment.
tol should be used here. It's not used anywhere now.
There was a problem hiding this comment.
Can you add a test with non-default tol for good measure?
There was a problem hiding this comment.
I realize. I wonder if tol should be changed to atol and rtol and just forward them in here.
There was a problem hiding this comment.
You'll have to specify both atol and rtol (here, not in the signature), because the defaults are both nonzero: rtol=1e-05, atol=1e-08
There was a problem hiding this comment.
Sorry my comment wasn't a reply to yours, non-updating interface.
atol = rtol = tol seems okay. atol is the only one of interest near covariance values of 0, and rtol may do something useful for very large values.
|
Overall LGTM, let's get this merged once comments are addressed. |
|
Ok, just pushed the documentation changes. Also:
updated the docstring accordingly |
I wonder if that's better. Realistically no one will use |
|
Ok, I will change it back to the single tol and pass it as atol and rtol |
|
Needs a mention in |
|
reverted to a single tol argument. I also added a mention in the release notes under "changes" |
|
Okay, in it goes! Thanks @ovillellas, @cowlicks, all. |
Edit:
This now allows for PSD checking with a
check_validkeyword arg that can take the values'warn','raise', and'ignore'.It also allows the covariance matrix to be almost PSD up to some small errors.
There have been several old discussions about how
np.random.multivariate_normalshould behave when passed a "bad" covariance matrix. i.e. non-symmetric, or not Positive semi-definite (PSD). The reason people need this is because the covariance matrix might have roundoff error making it not strictly symmetric or PSD.In the discussions there was some consensus to fix things the way I do in this PR. I added a keyword arg for ignoring the PSD check and silencing the warning. I also added a keyword arg that ignores the new symmetry check and silences the warning. Previously symmetry was not checked at all.
I'd like to go one step further and
raise ValueErrorwhen the covariance matrix isn't symmetric or PSD, of course, with the keyword args there so this can be bypassed. What do y'all think about that?old discussions:
#1821
http://mail.scipy.org/pipermail/numpy-discussion/2009-September/045255.html