MatLab : chol Matrix must be positive definite

2k views Asked by At

I am trying to fit t copula in MatLab to my data and my function is:

u = ksdensity(range_1,  range_1,'function','cdf');
v = ksdensity(range_2,  range_2,'function','cdf');
%fit a t-copula to returns
rng default ; % For reproducibility
[Rho,nu] = copulafit('t',[u v],'Method','ApproximateML');

And I get an error that says:

Error using chol
Matrix must be positive definite.
Error in copulafit/approxProfileNLL_t (line 314)
nll = negloglike_t(nu,chol(Rho),t_);
Error in copulafit>bracket1D (line 494)
oldnll = nllFun(bound);
Error in copulafit (line 126)
[lowerBnd,upperBnd] = bracket1D(profileFun,lowerBnd,5); % 'upper', search ascending from 5

I understood that it happens due to chol() decomposition, but I don't know which parameters should be changed to overcome this problem. Any help would be appreciated.

Data that I use has been looks like:

 range_1         range_2
-0.639388612    -0.639388612
1.029603565     1.029603565
1.273883288     1.273883288
0.754717135     0.754717135
1.747817835     1.747817835
1.717787291     1.717787291
-0.120625114    -0.120625114
2.173913469     2.173913469
2.836879977     2.836879977
-0.804601995    -0.804601995
       0         0 
1

There are 1 answers

0
Tommaso Belluzzo On

Actually, your range1 and range2 variables are absolutely identical. A simple check in the command window confirms it:

eq = (range1 == range2)

eq =

  11×1 logical array

   1
   1
   1
   1
   1
   1
   1
   1
   1
   1
   1

Since the goal of copulafit function is to calculate the estimate of the matrix of linear correlation parameters for a Gaussian Copula, the entire process fails il the input variables are too correlated:

c = corr(range1,range2); % 1

Actually, we are facing a perfect positive correlation between range1 and range2. The function that throws the exception, chol (reference here), is just a part of the process producing a Gaussian Copula fit and it's being internally called by the copulafit function.

The only solutions you have are:

  1. changing your variables
  2. adding a random noise to your variables (if you are allowed to)

Let's make an example using the second option:

range1 = [
    -0.639388612
    1.029603565
    1.273883288
    0.754717135
    1.747817835
    1.717787291
    -0.120625114
    2.173913469
    2.836879977
    -0.804601995
    0
];

% just an example, I'm tired of using rand function xD
range2 = awgn(range1,1,'measured');

u = ksdensity(range1,  range1,'function','cdf');
v = ksdensity(range2,  range2,'function','cdf');
rng default ;
[Rho,nu] = copulafit('t',[u v],'Method','ApproximateML');

This will work without errors.