В чем разница между cholesky в numpy и scipy?

Я использую разложение Холески для выборки случайных величин из многомерного гаусса и вычисляет спектр мощности случайных величин. Результат, полученный из numpy.linalg.cholesky, всегда имеет более высокую мощность на высоких частотах, чем от scipy.linalg.cholesky.

Каковы различия между этими двумя функциями, которые могут вызвать этот результат? Какой из них более численно устойчив?

Вот код, который я использую:

n = 2000

m = 10000

c0 = np.exp(-.05*np.arange(n))

C = linalg.toeplitz(c0)

Xn = np.dot(np.random.randn(m,n),np.linalg.cholesky(C))

Xs = np.dot(np.random.randn(m,n),linalg.cholesky(C))

Xnf = np.fft.fft(Xn)

Xsf = np.fft.fft(Xs)

Xnp = np.mean(Xnf*Xnf.conj(),axis=0)

Xsp = np.mean(Xsf*Xsf.conj(),axis=0)

Ответы

Ответ 1

scipy.linalg.cholesky дает вам верхнетреугольное разложение по умолчанию, тогда как np.linalg.cholesky дает вам нижестоящую треугольную версию. Из документов для scipy.linalg.cholesky:

cholesky(a, lower=False, overwrite_a=False)
    Compute the Cholesky decomposition of a matrix.

    Returns the Cholesky decomposition, :math:`A = L L^*` or
    :math:`A = U^* U` of a Hermitian positive-definite matrix A.

    Parameters
    ----------
    a : ndarray, shape (M, M)
        Matrix to be decomposed
    lower : bool
        Whether to compute the upper or lower triangular Cholesky
        factorization.  Default is upper-triangular.
    overwrite_a : bool
        Whether to overwrite data in `a` (may improve performance).

Например:

>>> scipy.linalg.cholesky([[1,2], [1,9]])
array([[ 1.        ,  2.        ],
       [ 0.        ,  2.23606798]])
>>> scipy.linalg.cholesky([[1,2], [1,9]], lower=True)
array([[ 1.        ,  0.        ],
       [ 1.        ,  2.82842712]])
>>> np.linalg.cholesky([[1,2], [1,9]])
array([[ 1.        ,  0.        ],
       [ 1.        ,  2.82842712]])

Если я изменю свой код, чтобы использовать одну и ту же случайную матрицу как раз, так и вместо linalg.cholesky(C,lower=True), тогда получаю ответы вроде:

>>> Xnp
array([ 79621.02629287+0.j,  78060.96077912+0.j,  77110.92428806+0.j, ...,
        75526.55192199+0.j,  77110.92428806+0.j,  78060.96077912+0.j])
>>> Xsp
array([ 79621.02629287+0.j,  78060.96077912+0.j,  77110.92428806+0.j, ...,
        75526.55192199+0.j,  77110.92428806+0.j,  78060.96077912+0.j])
>>> np.allclose(Xnp, Xsp)
True