我已经给出了一个非常大的矩阵(我不能改变矩阵的值),我需要计算(协方差)矩阵的逆。
有时我会收到错误
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
有没有办法使用new det然后用它来计算协方差矩阵的逆?
答案 0 :(得分: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
欢迎来到浮点运算世界。哦,顺便说一句,忘记det作为几乎所有使用浮点运算的计算的工具。这几乎总是一个糟糕的选择。
答案 1 :(得分:5)
Woodchips为您提供了一个非常好的解释,说明为什么不应该使用行列式。这似乎是一个常见的误解,你的问题与另一个关于反转矩阵的问题非常相关: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
答案 2 :(得分:1)
在这种情况下,计算逆是不是一个好主意。如果您必须这样做,我建议使用它来提高显示精度:
format long;
其他建议可能是尝试使用矩阵的SVD并在那里修改奇异值。
A = U∑V'
inv(A) = V*inv(∑)*U'
Σ是一个对角矩阵,你会看到其中一个对角线条目接近于0.如果你想要某种近似值,请尝试使用这个数字。