summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2019-10-16 12:47:40 +0100
committerEric Wieser <wieser.eric@gmail.com>2019-10-16 13:07:00 +0100
commit418a85eb738c76109779d1a70ba7da6c3a3f1603 (patch)
tree3a8d63cfea36efb17fe464d50c903b67bbf4598f
parent033907bae4ee39eeb27234eda1c80e60009dd5ed (diff)
downloadnumpy-418a85eb738c76109779d1a70ba7da6c3a3f1603.tar.gz
Back out use_factor changes, to be restored in a separate PR
-rw-r--r--doc/release/upcoming_changes/14197.improvement.rst16
-rw-r--r--numpy/random/generator.pyx37
-rw-r--r--numpy/random/tests/test_generator_mt19937.py40
3 files changed, 11 insertions, 82 deletions
diff --git a/doc/release/upcoming_changes/14197.improvement.rst b/doc/release/upcoming_changes/14197.improvement.rst
index d460fdab5..c0c52580a 100644
--- a/doc/release/upcoming_changes/14197.improvement.rst
+++ b/doc/release/upcoming_changes/14197.improvement.rst
@@ -1,9 +1,7 @@
-``method`` and ``use_factor`` options for `np.random.multivariate_normal`
-----------------------------------------------------
-A ``method`` option is now available for `np.random.multivariate_normal` with
-possible values {'svd', 'eigh', 'cholesky'}. To use it, write
-``np.random.multivariate_normal(..., method=<method>)``. Another option
-``use_factor`` is now available which allows the user to pass a precomputed
-factor of a covariance matrix in order to speed up computation. To use it,
-write ``np.random.multivariate_normal(..., use_factor=True)``. The ``method``
-option is ignored when ``use_factor=True``
+``method`` keyword argument for `np.random.multivariate_normal`
+---------------------------------------------------------------
+A ``method`` keyword argument is now available for
+`np.random.multivariate_normal` with possible values
+``{'svd', 'eigh', 'cholesky'}``. To use it, write
+``np.random.multivariate_normal(..., method=<method>)``.
+
diff --git a/numpy/random/generator.pyx b/numpy/random/generator.pyx
index 13099c524..9d0d1e267 100644
--- a/numpy/random/generator.pyx
+++ b/numpy/random/generator.pyx
@@ -3331,7 +3331,7 @@ cdef class Generator:
# Multivariate distributions:
def multivariate_normal(self, mean, cov, size=None, check_valid='warn',
- tol=1e-8, *, method='svd', use_factor=False):
+ tol=1e-8, *, method='svd'):
"""
multivariate_normal(mean, cov, size=None, check_valid='warn', tol=1e-8)
@@ -3371,14 +3371,6 @@ cdef class Generator:
.. versionadded:: 1.18.0
- use_factor : bool, optional
- If set to True then cov argument is treated as a precomputed factor
- matrix A such that `A @ A.T = cov`` holds true. This provides
- significant speedups because the factorization of cov is avoided.
- Note that when this argument is set to True, ``method`` is ignored.
-
- .. versionadded:: 1.18.0
-
Returns
-------
out : ndarray
@@ -3425,11 +3417,7 @@ cdef class Generator:
Note that the covariance matrix must be positive semidefinite (a.k.a.
nonnegative-definite). Otherwise, the behavior of this method is
- undefined and backwards compatibility is not guaranteed. When supplying
- a factor `F` in place of the full covariance matrix the user is expected
- to ensure that ``F @ F.T`` recovers the covariance matrix. This
- also implies that a factor input computed using the Cholesky method
- must be a lower-triangular matrix.
+ undefined and backwards compatibility is not guaranteed.
References
----------
@@ -3452,15 +3440,6 @@ cdef class Generator:
>>> y.shape
(3, 3, 2)
- We can also use a precomputed factor matrix of cov to speed up the
- computation. This is very useful when one needs to generate random
- values using the sample covariance matrix but different means.
- >>> s, u = np.linalg.eigh(cov)
- >>> A = u * np.sqrt(s) # factor matrix of cov using Eigendecomposition.
- >>> z = rng.multivariate_normal(mean, A, (3, 3), use_factor=True)
- >>> z.shape
- (3, 3, 2)
-
The following is probably true, given that 0.6 is roughly twice the
standard deviation:
@@ -3484,13 +3463,10 @@ cdef class Generator:
if len(mean.shape) != 1:
raise ValueError("mean must be 1 dimensional")
- matrix_type = "factor" if use_factor else "cov"
if (len(cov.shape) != 2) or (cov.shape[0] != cov.shape[1]):
- raise ValueError("{} must be 2 dimensional and square"
- .format(matrix_type))
+ raise ValueError("cov must be 2 dimensional and square")
if mean.shape[0] != cov.shape[0]:
- raise ValueError("mean and {} must have same length"
- .format(matrix_type))
+ raise ValueError("mean and cov must have same length")
# Compute shape of output and create a matrix of independent
# standard normally distributed random numbers. The matrix has rows
@@ -3500,11 +3476,6 @@ cdef class Generator:
final_shape.append(mean.shape[0])
x = self.standard_normal(final_shape).reshape(-1, mean.shape[0])
- if use_factor:
- x = mean + np.dot(x, cov)
- x.shape = tuple(final_shape)
- return x
-
# Transform matrix of standard normals into matrix where each row
# contains multivariate normals with the desired covariance.
# Compute A such that dot(transpose(A),A) == cov.
diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py
index 3b92f17f0..70c8851fc 100644
--- a/numpy/random/tests/test_generator_mt19937.py
+++ b/numpy/random/tests/test_generator_mt19937.py
@@ -992,10 +992,6 @@ class TestRandomDist(object):
random = Generator(MT19937(self.seed))
actual_chol = random.multivariate_normal(mean, cov, size,
method='cholesky')
- # the factor matrix is the same for all methods
- random = Generator(MT19937(self.seed))
- actual_factor = random.multivariate_normal(mean, cov, size,
- use_factor=True)
desired = np.array([[[-1.747478062846581, 11.25613495182354 ],
[-0.9967333370066214, 10.342002097029821 ]],
[[ 0.7850019631242964, 11.181113712443013 ],
@@ -1006,7 +1002,6 @@ class TestRandomDist(object):
assert_array_almost_equal(actual_svd, desired, decimal=15)
assert_array_almost_equal(actual_eigh, desired, decimal=15)
assert_array_almost_equal(actual_chol, desired, decimal=15)
- assert_array_almost_equal(actual_factor, desired, decimal=15)
# Check for default size, was raising deprecation warning
random = Generator(MT19937(self.seed))
@@ -1017,18 +1012,10 @@ class TestRandomDist(object):
actual_chol = random.multivariate_normal(mean, cov, method='cholesky')
# the factor matrix is the same for all methods
random = Generator(MT19937(self.seed))
- actual_factor = random.multivariate_normal(mean, cov, use_factor=True)
desired = np.array([-1.747478062846581, 11.25613495182354])
assert_array_almost_equal(actual_svd, desired, decimal=15)
assert_array_almost_equal(actual_eigh, desired, decimal=15)
assert_array_almost_equal(actual_chol, desired, decimal=15)
- assert_array_almost_equal(actual_factor, desired, decimal=15)
-
- # test if raises ValueError when non-square factor is used
- non_square_factor = [[1, 0], [0, 1], [1, 0]]
- assert_raises(ValueError, random.multivariate_normal, mean,
- non_square_factor, use_factor=True)
-
# Check that non symmetric covariance input raises exception when
# check_valid='raises' if using default svd method.
mean = [0, 0]
@@ -1036,33 +1023,6 @@ class TestRandomDist(object):
assert_raises(ValueError, random.multivariate_normal, mean, cov,
check_valid='raise')
- # Check if each method used with use_factor=False returns the same
- # output when used with use_factor=True
- cov = [[2, 1], [1, 2]]
- random = Generator(MT19937(self.seed))
- desired_svd = random.multivariate_normal(mean, cov)
- u, s, vh = svd(cov)
- svd_factor = np.sqrt(s)[:, None] * vh
- random = Generator(MT19937(self.seed))
- actual_svd = random.multivariate_normal(mean, svd_factor.T,
- use_factor=True)
- random = Generator(MT19937(self.seed))
- desired_eigh = random.multivariate_normal(mean, cov, method='eigh')
- s, u = eigh(cov)
- eigh_factor = u * np.sqrt(s)
- random = Generator(MT19937(self.seed))
- actual_eigh = random.multivariate_normal(mean, eigh_factor,
- use_factor=True)
- random = Generator(MT19937(self.seed))
- desired_chol = random.multivariate_normal(mean, cov, method='cholesky')
- chol_factor = cholesky(cov)
- random = Generator(MT19937(self.seed))
- actual_chol = random.multivariate_normal(mean, chol_factor,
- use_factor=True)
- assert_array_almost_equal(actual_svd, desired_svd, decimal=15)
- assert_array_almost_equal(actual_eigh, desired_eigh, decimal=15)
- assert_array_almost_equal(actual_chol, desired_chol, decimal=15)
-
# Check that non positive-semidefinite covariance warns with
# RuntimeWarning
cov = [[1, 2], [2, 1]]