matlab中矩阵的det返回0

发布于 2024-12-09 01:23:54 字数 467 浏览 1 评论 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 

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

I have been give a very large matrix (I cannot change the values of the matrix) and I need to calculate the inverse of a (covariance) matrix.

Sometimes I get the error saying

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

In these situations I see that the value of the det returns 0.

Before calculating inverse (of a covariance matrix) I want to check the value of the det and perform something like this

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

Is there any way to use the new det and then use this to calculate the inverse of the covariance matrix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花想c 2024-12-16 01:23:54

叹。计算行列式来确定奇点是一件荒谬的事情,完全如此。对于大矩阵尤其如此。抱歉,但确实如此。为什么?是的,有些书告诉你这样做。也许甚至是你的导师。

分析奇点是一回事。但是奇点的数值确定又如何呢?除非您使用符号工具,否则 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 作为几乎所有使用浮点算术的计算的工具。这几乎总是一个糟糕的选择。

Sigh. Computation of the determinant to determine singularity is a ridiculous thing to do, utterly so. Especially so for a large matrix. Sorry, but it is. Why? Yes, some books tell you to do it. Maybe even your instructor.

Analytical singularity is one thing. But how about numerical determination of singularity? Unless you are using a symbolic tool, MATLAB uses floating point arithmetic. This means it stores numbers as floating point, double precision values. Those numbers cannot be smaller in magnitude than

>> realmin
ans =
  2.2251e-308

(Actually, MATLAB goes a bit lower than that, in terms of denormalized numbers, which can go down to approximately 1e-323.) See that when I try to store a number smaller than that, MATLAB thinks it is zero.

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

>> A = 1e-324
A =
     0

What happens with a large matrix? For example, is this matrix singular:

M = eye(1000);

Since M is an identity matrix, it is fairly clearly non-singular. In fact, det does suggest that it is non-singular.

>> det(M)
ans =
     1

But, multiply it by some constant. Does that make it non-singular? NO!!!!!!!!!!!!!!!!!!!!!!!! Of course not. But try it anyway.

>>     det(M*0.1)
ans =
     0

Hmm. Thats is odd. MATLAB tells me the determinant is zero. But we know that the determinant is 1e-1000. Oh, yes. Gosh, 1e-1000 is smaller, by a considerable amount than the smallest number that I just showed you that MATLAB can store as a double. So the determinant underflows, even though it is obviously non-zero. Is the matrix singular? Of course not. But does the use of det fail here? Of course it will, and this is completely expected.

Instead, use a good tool for the determination of singularity. Use a tool like cond, or rank. For example, can we fool rank?

>> rank(M)
ans =
        1000

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

See that rank knows this is a full rank matrix, regardless of whether we scale it or not. The same is true of cond, computing the condition number of M.

>> cond(M)
ans =
     1

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

Welcome to the world of floating point arithmetic. And oh, by the way, forget about det as a tool for almost any computation using floating point arithmetic. It is a poor choice almost always.

何止钟意 2024-12-16 01:23:54

Woodchips 已经给了你一个很好的解释为什么你不应该使用行列式。这似乎是一个常见的误解,您的问题与求逆矩阵的另一个问题非常相关: 在Matlab中是否有一种快速的方法来反转矩阵?,其中OP决定因为他的矩阵的行列式是1,所以它绝对是可逆的!这是我的回答的一个片段

它不是 det(A)=1,而是 矩阵的条件数决定了逆矩阵的精确度或稳定性。请注意,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

Woodchips has given you a very good explanation for why you shouldn't use the determinant. This seems to be a common misconception and your question is very related to another question on inverting matrices: Is there a fast way to invert a matrix in Matlab?, where the OP decided that because the determinant of his matrix was 1, it was definitely invertible! Here's a snippet from my answer

Rather than det(A)=1, it is the condition number of your matrix that dictates how accurate or stable the inverse will be. Note that det(A)=∏i=1:n λi. So just setting λ1=M, λn=1/M and λi≠1,n=1 will give you det(A)=1. However, as M → ∞, cond(A) = M2 → ∞ and λn → 0, meaning your matrix is approaching singularity and there will be large numerical errors in computing the inverse.

You can test this in MATLAB with the following simple example:

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

%# calculate determinant
det(A)
ans =

     1

%# calculate condition number
cond(A)
ans =

   1.0000e+30
花间憩 2024-12-16 01:23:54

在这种情况下,计算倒数并不是一个好主意。如果您必须这样做,我建议使用它来提高显示精度:

format long;

其他建议可能是尝试使用矩阵的 SVD 并在那里修改奇异值。

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

Σ 是一个对角矩阵,您将看到其中一个对角线条目接近 0。如果您想要某种近似值,请尝试使用这个数字。

In such a scenario, calculating an inverse is not a very good idea. If you just have to do it, I would suggest using this to increase display precision:

format long;

Other suggestion could be to try using an SVD of the matrix and tinker around with singular values there.

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

∑ is a diagonal matrix where you will see one of the diagonal entries close to 0. Try playing around with this number if you want some sort of an approximation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文