summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRedRuM <44142765+zoj613@users.noreply.github.com>2019-08-18 16:29:45 +0200
committerRedRuM <44142765+zoj613@users.noreply.github.com>2019-08-18 16:29:45 +0200
commitb665d761b98a176d0df13ee6d7da8037d007c0f7 (patch)
treec57f595f52d511abaa459a025f36ebf95ccb9512
parentb0c7b22122a121c1d2b9f8895c8b78362e666678 (diff)
downloadnumpy-b665d761b98a176d0df13ee6d7da8037d007c0f7.tar.gz
MNT: simplify the API by requiring the user to ensure the correct factor is supplied.
-rw-r--r--changelog/14197.improvement.rst5
-rw-r--r--numpy/random/generator.pyx23
-rw-r--r--numpy/random/tests/test_generator_mt19937.py2
3 files changed, 14 insertions, 16 deletions
diff --git a/changelog/14197.improvement.rst b/changelog/14197.improvement.rst
index b822d1645..b9ce45a81 100644
--- a/changelog/14197.improvement.rst
+++ b/changelog/14197.improvement.rst
@@ -4,5 +4,6 @@ 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 for any given
-``method``. To use it, write ``np.random.multivariate_normal(..., use_factor=True)``. \ No newline at end of file
+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`` \ No newline at end of file
diff --git a/numpy/random/generator.pyx b/numpy/random/generator.pyx
index 95c61a6c8..e0fd14c0d 100644
--- a/numpy/random/generator.pyx
+++ b/numpy/random/generator.pyx
@@ -3370,10 +3370,10 @@ cdef class Generator:
compute A and is faster than svd but slower than cholesky.
use_factor : bool, optional
If set to True then cov argument is treated as a precomputed factor
- matrix A such that A.dot(transpose(A)) = cov. with the
- assumption that A was computed with the method specified in the
- ``method`` argument. This provides significant speedups because
- the factorization of cov is avoided.
+ matrix A such that A.dot(transpose(A)) = 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.
Returns
-------
@@ -3421,7 +3421,11 @@ 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.
+ 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.dot(transpose(F)) recovers the covariance matrix. This
+ also implies that a factor input computed using the Cholesky method
+ must be a lower-triangular matrix.
References
----------
@@ -3449,7 +3453,7 @@ cdef class Generator:
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), method='eigh', use_factor=True)
+ >>> z = rng.multivariate_normal(mean, A, (3, 3), use_factor=True)
>>> z.shape
(3, 3, 2)
@@ -3493,12 +3497,7 @@ cdef class Generator:
x = self.standard_normal(final_shape).reshape(-1, mean.shape[0])
if use_factor:
- # check if the factor supplied is a cholesky upper triangular
- # matrix and calculate random values accordingly.
- if method == 'cholesky' and not np.any(np.tril(cov, k=-1)):
- x = mean + np.dot(x, cov.T)
- else:
- x = mean + np.dot(x, cov)
+ x = mean + np.dot(x, cov)
x.shape = tuple(final_shape)
return x
diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py
index 2677b04fa..3b92f17f0 100644
--- a/numpy/random/tests/test_generator_mt19937.py
+++ b/numpy/random/tests/test_generator_mt19937.py
@@ -1052,14 +1052,12 @@ class TestRandomDist(object):
eigh_factor = u * np.sqrt(s)
random = Generator(MT19937(self.seed))
actual_eigh = random.multivariate_normal(mean, eigh_factor,
- method='eigh',
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,
- method='cholesky',
use_factor=True)
assert_array_almost_equal(actual_svd, desired_svd, decimal=15)
assert_array_almost_equal(actual_eigh, desired_eigh, decimal=15)