diff options
author | RedRuM <44142765+zoj613@users.noreply.github.com> | 2019-08-18 16:29:45 +0200 |
---|---|---|
committer | RedRuM <44142765+zoj613@users.noreply.github.com> | 2019-08-18 16:29:45 +0200 |
commit | b665d761b98a176d0df13ee6d7da8037d007c0f7 (patch) | |
tree | c57f595f52d511abaa459a025f36ebf95ccb9512 | |
parent | b0c7b22122a121c1d2b9f8895c8b78362e666678 (diff) | |
download | numpy-b665d761b98a176d0df13ee6d7da8037d007c0f7.tar.gz |
MNT: simplify the API by requiring the user to ensure the correct factor is supplied.
-rw-r--r-- | changelog/14197.improvement.rst | 5 | ||||
-rw-r--r-- | numpy/random/generator.pyx | 23 | ||||
-rw-r--r-- | numpy/random/tests/test_generator_mt19937.py | 2 |
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) |