2011-10-09 90 views
5

我已经给了一个非常大的矩阵(我不能改变矩阵的值),我需要计算(协方差)矩阵的逆。det的矩阵在matlab中返回0

有时我得到的错误说

Matrix is close to singular or badly scaled. 
    Results may be inaccurate 

在这种情况下,我看到DET的值返回0

计算(的协方差矩阵)的逆之前,我想检查值在DET并执行这样的事情

covarianceFea=cov(fea_class); 
covdet=det(covarianceFea); 
if(covdet ==0) 
    covdet=covdet+.00001; 
    %calculate the covariance using this new det 
end 

有没有办法使用新DET,然后用它来计算的协方差矩阵的逆?

回答

1

在这种情况下,计算倒数并不是一个好主意。如果你只需要做到这一点,我会建议使用这种增加显示精度:

format long; 

其他建议可能是尝试使用矩阵的SVD和鼓捣周围存在奇异值。

A = U∑V' 
inv(A) = V*inv(∑)*U' 

Σ是对角矩阵,你会看到对角的一个条目接近0试试,如果你需要某种近似的这一数字玩弄。

+0

有一个为伪逆的PINV功能 – Amro

16

感叹。计算行列式以确定奇点是一件荒谬的事情,完全如此。对于大型矩阵尤其如此。对不起,但是。为什么?是的,有些书告诉你这样做。甚至可能是你的导师。

分析奇点是一回事。但是如何确定奇点的数值呢?除非您使用符号工具,否则MATLAB使用浮点运算。这意味着它将数字存储为浮点数,双精度值。这些数字不能超过在幅度较小

>> realmin 
ans = 
    2.2251e-308 

(实际上,MATLAB比这低一点,在非规范化的数值,它可以深入到大约1E-323的条款。)看到,当我尝试存储比它小的数字,MATLAB认为它是零。

>> A = 1e-323 
A = 
    9.8813e-324 

>> A = 1e-324 
A = 
    0 

大矩阵会发生什么?例如,这是矩阵单数:

M = eye(1000); 

由于M是一个单位矩阵,它是相当明显的非奇异的。事实上,det确实表明它是非单一的。

>> det(M) 
ans = 
    1 

但是,它乘以一些常数。这是否使它非单一?没有!!!!!!!!!!!!!!!!!!!!!!!!当然不是。但无论如何都要尝试。

>>  det(M*0.1) 
ans = 
    0 

嗯。那很奇怪。 MATLAB告诉我这个行列式是零。但我们知道行列式是1e-1000。哦,是的。天哪,1e-1000更小,比我刚才告诉你的MATLAB可以存储的最小数量要多一倍。因此,行列式下溢,尽管显然非零。矩阵是单数吗?当然不是。但是det的使用在这里失败了吗?当然,这是完全可以预料的。

相反,使用一个很好的工具来确定奇点。使用像cond或rank这样的工具。例如,我们可以欺骗排名吗?

>> rank(M) 
ans = 
     1000 

>> rank(M*.1) 
ans = 
     1000 

见秩知道这是一个满秩矩阵,不管我们是否扩大与否。 cond也是如此,计算M的条件数。

>> cond(M) 
ans = 
    1 

>> cond(M*.1) 
ans = 
    1 

欢迎来到浮点运算的世界。噢,顺便说一下,忘记使用浮点运算几乎所有计算的工具。这几乎总是一个糟糕的选择。

5

木片给了你一个很好的解释,为什么你不应该使用行列式。这似乎是一个常见的误解,你的问题与反转矩阵上的另一个问题非常相关:Is there a fast way to invert a matrix in Matlab?,其中OP决定因为他的矩阵的行列式为1,所以它绝对是可逆的!下面是我的回答片段

不是det(A)=1,它是决定如何准确或稳定的逆将是condition number of your matrix。请注意,det(A)=∏i=1:n λi。所以只需设置λ1=M,λn=1/Mλi≠1,n=1就会给你det(A)=1。然而,由于M → ∞,cond(A) = M2 → ∞λn → 0,这意味着你的矩阵正在接近奇点,并且在计算逆矩阵时会出现大的数值误差。

可以在MATLAB用下面简单的例子测试:

A = eye(10); 
A([1 2]) = [1e15 1e-15]; 

%# calculate determinant 
det(A) 
ans = 

    1 

%# calculate condition number 
cond(A) 
ans = 

    1.0000e+30