Skip to content

np.linalg.cholesky error on symmetric positive-definite well-conditioned matrix? #8385

Closed

Description

@srmcc

I can feed np.linalg.cholesky a symmetric, positive-definite, reasonably conditioned matrix (Sigma_true below) and numpy returns an error message: matrix is not positive definite... Any ideas, folks? I'm a newbie to contributing so helpful suggestions are welcome. If this is indeed expected behavior, then the error message could be more informative. Thanks everyone!

## steps to reproduce issue (Sigma_true does not cholesky decompose)
from __future__ import division
import numpy as np
import scipy.stats

def create_kappa_delta_matrices(kappa_mean, delta_mean, num_samp, random_state1, random_state2):
	## normal distribution
	assert 1/2*(1 + delta_mean) > kappa_mean
	assert kappa_mean> delta_mean 
	kappas=scipy.stats.norm.rvs(loc= kappa_mean, scale=np.sqrt(kappa_mean*(1-kappa_mean )), size=np.int((num_samp**2 -num_samp)/2 ), random_state=random_state1)
	deltas=scipy.stats.norm.rvs(loc= delta_mean, scale=np.sqrt(delta_mean*(1-delta_mean )), size=np.int((num_samp**2 -num_samp)/2 ), random_state=random_state2)
	iu1 = np.triu_indices(num_samp, 1) ## indices for upper triangular
	Kappa=np.zeros((num_samp,num_samp))
	Delta=np.zeros((num_samp,num_samp))
	Kappa[iu1]= kappas
	Delta[iu1]=deltas
	Kappa = Kappa + Kappa.T
	Delta = Delta + Delta.T
	for i in range(num_samp):
		Kappa[i, i]=1 
		Delta[i, i]=1 
	Kappa=Kappa.reshape(1, num_samp, num_samp)
	Delta=Delta.reshape(1, num_samp, num_samp)
	return(Kappa, Delta)

## this is the code that creates the positive-definite well-conditioned matrix (apologies that it is a bit involved):
num_samp=200
kappa_mean=.02
delta_mean= kappa_mean**2 +.001
(Kappa, Delta) = create_kappa_delta_matrices(kappa_mean, delta_mean, num_samp, 1239812, 23425)
Iden = np.diag(np.ones(num_samp)).reshape(1, num_samp, num_samp)
theta = np.concatenate((Kappa, Delta,  Iden), axis=0)
sigma2 = np.array((.2, .6, .2)).reshape(3, 1)
Sigma_true = np.sum([theta[i] * sigma2[i] for i in range(theta.shape[0])], axis=0)

## checking that Sigma_true is symmetric positive-definite and well-conditioned:
assert num_samp==np.sum(np.linalg.svd(Sigma_true)[1]>0)
assert (Sigma_true==Sigma_true.T).all()
print(np.linalg.cond(Sigma_true))

## trying to Cholesky-decompose:
chol=np.linalg.cholesky(Sigma_true)
## The expected output is a cholesky decomposition of Sigma_true. 
## The actual output is:
>>> print(np.linalg.cond(Sigma_true))
43.769107972
>>>chol=np.linalg.cholesky(Sigma_true)
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/*****/anaconda3/envs/reml/lib/python3.5/site-packages/numpy/linalg/linalg.py", line 612, in cholesky
    r = gufunc(a, signature=signature, extobj=extobj)
  File "/home/*****/anaconda3/envs/reml/lib/python3.5/site-packages/numpy/linalg/linalg.py", line 93, in _raise_linalgerror_nonposdef
    raise LinAlgError("Matrix is not positive definite")
numpy.linalg.linalg.LinAlgError: Matrix is not positive definite

Here is the version history:

>>> import platform; print(platform.platform())
Linux-3.13.0-92-generic-x86_64-with-debian-jessie-sid
>>> import sys; print("Python", sys.version)
Python 3.5.2 |Continuum Analytics, Inc.| (default, Jul  2 2016, 17:53:06) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
>>> import numpy; print("NumPy", numpy.__version__)
NumPy 1.11.2

Activity

  1. charris commented on Dec 16, 2016

    @charris
    Member

    It's not positive definite.

    In [6]: eigvalsh(Sigma_true)
    Out[6]: 
    array([-0.05127828,  0.05274922,  0.06065544,  0.08330586,  0.11171002,
            0.11721078,  0.12119689,  0.15321077,  0.17379047,  0.19043536,
            0.19403204,  0.21367971,  0.22054305,  0.22526719,  0.23716421,
            0.24564771,  0.25532348,  0.26753322,  0.28389666,  0.28938601,
            0.29785662,  0.32116448,  0.32991338,  0.33795234,  0.34390424,
            0.3551256 ,  0.36371704,  0.36957058,  0.39030835,  0.39911722,
            0.40712851,  0.42022895,  0.42577333,  0.44017277,  0.44939997,
            0.45867234,  0.46528464,  0.47778902,  0.48687172,  0.5001272 ,
            0.51898225,  0.5203862 ,  0.53434974,  0.54963632,  0.55407595,
            0.557009  ,  0.57466166,  0.58458222,  0.59150849,  0.59313978,
            0.60477843,  0.6145549 ,  0.62030642,  0.62368144,  0.63550357,
            0.63712818,  0.64417861,  0.64936758,  0.66013125,  0.67825285,
            0.68095326,  0.68462835,  0.69716007,  0.71032664,  0.71112354,
            0.71968288,  0.72990078,  0.74272577,  0.74693239,  0.75125434,
            0.7572988 ,  0.76695275,  0.7756605 ,  0.78212398,  0.78914701,
            0.80353877,  0.81278694,  0.81763441,  0.82895422,  0.83361981,
            0.84258532,  0.85359045,  0.85801058,  0.86309402,  0.86814684,
            0.87690451,  0.89231717,  0.89675007,  0.89885578,  0.9150584 ,
            0.91938341,  0.92745686,  0.93133379,  0.94510191,  0.95260427,
            0.95783272,  0.96727666,  0.9770844 ,  0.98387727,  0.99556894,
            1.00135802,  1.00569207,  1.01472711,  1.02392209,  1.0296447 ,
            1.032501  ,  1.0469128 ,  1.06238152,  1.0657244 ,  1.06936616,
            1.07487797,  1.08625145,  1.10655451,  1.11592175,  1.11943258,
            1.126595  ,  1.1323013 ,  1.14151475,  1.14193887,  1.15440306,
            1.1634526 ,  1.1687323 ,  1.17286769,  1.17841984,  1.18726644,
            1.19051182,  1.20087023,  1.21326302,  1.2197965 ,  1.24392451,
            1.25077414,  1.25731336,  1.25854024,  1.269382  ,  1.27471087,
            1.28397003,  1.30048074,  1.30914426,  1.31160056,  1.32028312,
            1.32703862,  1.33853775,  1.3488319 ,  1.35923145,  1.36104221,
            1.36890838,  1.37706883,  1.38745721,  1.39137251,  1.40659426,
            1.4122151 ,  1.41845739,  1.4269273 ,  1.43778279,  1.43956578,
            1.45716739,  1.4674123 ,  1.47578599,  1.48036225,  1.48848927,
            1.49745254,  1.50330357,  1.52326474,  1.53601062,  1.54332138,
            1.55524854,  1.56236986,  1.57157196,  1.58339686,  1.58784703,
            1.59900905,  1.61216131,  1.61973261,  1.63939886,  1.64330641,
            1.64783568,  1.66370183,  1.66878329,  1.67959585,  1.6865237 ,
            1.6903007 ,  1.71669801,  1.71897565,  1.72486731,  1.7526067 ,
            1.758081  ,  1.76848673,  1.7726744 ,  1.79572124,  1.81415732,
            1.81759358,  1.82678794,  1.85030107,  1.85826296,  1.88025386,
            1.89816624,  1.90081865,  1.93789628,  1.95454455,  2.24440451])
    
  2. srmcc commented on Dec 16, 2016

    @srmcc
    Author

    That's interesting @charris. Unless I missed something silly, the plot thickens. Sigma_true is a real symmetric matrix, therefore it is normal (https://en.wikipedia.org/wiki/Normal_matrix#Special_cases). For normal matrices, the singular values of the SVD are the eigenvalues (https://en.wikipedia.org/wiki/Normal_matrix#Consequences, 2nd proposition). According to the SVD, Sigma_true is positive definite.

    >>> np.isreal(Sigma_true).all()
    True
    >>> (Sigma_true==Sigma_true.T).all()
    True
    >>> np.linalg.svd(Sigma_true)[1]
    array([ 2.24440451,  1.95454455,  1.93789628,  1.90081865,  1.89816624,
            1.88025386,  1.85826296,  1.85030107,  1.82678794,  1.81759358,
            1.81415732,  1.79572124,  1.7726744 ,  1.76848673,  1.758081  ,
            1.7526067 ,  1.72486731,  1.71897565,  1.71669801,  1.6903007 ,
            1.6865237 ,  1.67959585,  1.66878329,  1.66370183,  1.64783568,
            1.64330641,  1.63939886,  1.61973261,  1.61216131,  1.59900905,
            1.58784703,  1.58339686,  1.57157196,  1.56236986,  1.55524854,
            1.54332138,  1.53601062,  1.52326474,  1.50330357,  1.49745254,
            1.48848927,  1.48036225,  1.47578599,  1.4674123 ,  1.45716739,
            1.43956578,  1.43778279,  1.4269273 ,  1.41845739,  1.4122151 ,
            1.40659426,  1.39137251,  1.38745721,  1.37706883,  1.36890838,
            1.36104221,  1.35923145,  1.3488319 ,  1.33853775,  1.32703862,
            1.32028312,  1.31160056,  1.30914426,  1.30048074,  1.28397003,
            1.27471087,  1.269382  ,  1.25854024,  1.25731336,  1.25077414,
            1.24392451,  1.2197965 ,  1.21326302,  1.20087023,  1.19051182,
            1.18726644,  1.17841984,  1.17286769,  1.1687323 ,  1.1634526 ,
            1.15440306,  1.14193887,  1.14151475,  1.1323013 ,  1.126595  ,
            1.11943258,  1.11592175,  1.10655451,  1.08625145,  1.07487797,
            1.06936616,  1.0657244 ,  1.06238152,  1.0469128 ,  1.032501  ,
            1.0296447 ,  1.02392209,  1.01472711,  1.00569207,  1.00135802,
            0.99556894,  0.98387727,  0.9770844 ,  0.96727666,  0.95783272,
            0.95260427,  0.94510191,  0.93133379,  0.92745686,  0.91938341,
            0.9150584 ,  0.89885578,  0.89675007,  0.89231717,  0.87690451,
            0.86814684,  0.86309402,  0.85801058,  0.85359045,  0.84258532,
            0.83361981,  0.82895422,  0.81763441,  0.81278694,  0.80353877,
            0.78914701,  0.78212398,  0.7756605 ,  0.76695275,  0.7572988 ,
            0.75125434,  0.74693239,  0.74272577,  0.72990078,  0.71968288,
            0.71112354,  0.71032664,  0.69716007,  0.68462835,  0.68095326,
            0.67825285,  0.66013125,  0.64936758,  0.64417861,  0.63712818,
            0.63550357,  0.62368144,  0.62030642,  0.6145549 ,  0.60477843,
            0.59313978,  0.59150849,  0.58458222,  0.57466166,  0.557009  ,
            0.55407595,  0.54963632,  0.53434974,  0.5203862 ,  0.51898225,
            0.5001272 ,  0.48687172,  0.47778902,  0.46528464,  0.45867234,
            0.44939997,  0.44017277,  0.42577333,  0.42022895,  0.40712851,
            0.39911722,  0.39030835,  0.36957058,  0.36371704,  0.3551256 ,
            0.34390424,  0.33795234,  0.32991338,  0.32116448,  0.29785662,
            0.28938601,  0.28389666,  0.26753322,  0.25532348,  0.24564771,
            0.23716421,  0.22526719,  0.22054305,  0.21367971,  0.19403204,
            0.19043536,  0.17379047,  0.15321077,  0.12119689,  0.11721078,
            0.11171002,  0.08330586,  0.06065544,  0.05274922,  0.05127828])

    I had checked that above with this assertion:

    >>>assert num_samp==np.sum(np.linalg.svd(Sigma_true)[1]>0)
  3. charris commented on Dec 16, 2016

    @charris
    Member

    Singular values are always positive by definition, they are the absolute value of the eigenvalues. All the Hermitean symmetry guarantees is real eigenvalues.

  4. charris commented on Dec 16, 2016

    @charris
    Member

    For instance:

    In [1]: a = array([[1., 0.], [0., -1.]])
    
    In [2]: a
    Out[2]: 
    array([[ 1.,  0.],
           [ 0., -1.]])
    
    In [3]: svd(a)
    Out[3]: 
    (array([[ 1.,  0.],
            [ 0.,  1.]]), array([ 1.,  1.]), array([[ 1.,  0.],
            [-0., -1.]]))
    

    Note that a is Hermitean with eigenvalues [1, -1], but the singular values are [1, 1].

  5. srmcc commented on Dec 16, 2016

    @srmcc
    Author

    Indeed-- many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions