行列式显示无穷大而不是零!为什么



这是我为家庭作业遇到的问题编写的matlab代码。 在 A 乘法及其转置后,根据所有同学,得到的方阵应该具有行列式零,因为他们的代码(不同的一个)给了他们。为什么我的代码没有给出 c 和 d 的行列式是无穷大

A = rand(500,1500);
b = rand(500,1);
c = (A.')*A;
detc = det(c);
cinv = inv((A.')*A);
d = A*(A.');
detd = det(d);
dinv = inv(A*(A.'));
x1 = (inv((A.')*A))*((A.')*b);
x2 = A.'*((inv(A*(A.')))*b);

这种行为在det文档的"限制"部分中进行了解释,并在"查找奇异矩阵的行列式"小节中举例说明:

尽管A是单数的,但A的决定因素还是相当大的。事实上,A的行列式应该正好为零!d的不准确性是由于 LU 分解的 MATLAB® 实现中舍入误差的聚合,det使用该误差来计算行列式。

也就是说,在这种情况下,您可以使用同一页面上给出的 m 代码实现来产生所需的结果,但以升序对U的对角线元素进行排序。 请考虑示例脚本:

clc();
clear();
A = rand(500,1500);
b = rand(500,1);
c = (A.')*A;
[L,U] = lu(c);
% Since det(L) is always (+/-)1, it doesn't impact anything
diagU = diag(U);
detU1 = prod(diagU);
detU2 = prod(sort(diagU,'descend'));
detU3 = prod(sort(diagU,'ascend'));
fprintf('Minimum: %+9.5en',min(abs(diagU)));
fprintf('Maximum: %+9.5en',max(abs(diagU)));
fprintf('Determinant:n');
fprintf('tNo Sort:          %gn'  ,detU1);
fprintf('tDescending Sort:  %gn'  ,detU2);
fprintf('tAscending Sort:   %gnn',detU3);

这将产生输出:

Minimum: +1.53111e-13
Maximum: +1.72592e+02
Determinant:
    No Sort:          Inf
    Descending Sort:  Inf
    Ascending Sort:   0
请注意,排序

的方向很重要,并且无排序会给出Inf,因为对角线上不存在真正的0。 降序排序看到最大值首先乘以,显然,它们超过 realmax 并且永远不会乘以真正的0,这将产生一个NaN。 升序排序将所有接近零的对角线值聚集在一起,这些值很少有大的负值(事实上,更健壮的方法会根据幅度进行排序,但这里没有这样做),它们的乘法会产生一个真正的0(意味着该值低于 IEEE-754 算术中可用的最小非规范化数字),产生"正确"的结果。

所有这些所写的,

以及其他人所暗示的,我将引用原始的Matlab开发人员和Mathworks联合创始人Cleve Moler的话:

[行列式]在理论考虑和手工计算中很有用,但不能为稳健的数值软件提供坚实的基础。

好的。因此,det(A'*A) 不为零的事实并不能很好地指示 A'*A 的(非)奇点。行列式取决于缩放,矩阵显然非奇异可以具有非常小的行列式。例如,矩阵1/2 * I_n其中I_n是 nxn 恒等式的行列式为 (1/2)^n,当 n 走向无穷大时,它(快速)收敛到 0。但是 1/2 * I_n根本不是单数。

因此,检查矩阵奇点的最佳方法是条件数。

在您的情况下,在进行一些测试后

>> A = rand(500, 1500) ;
>> det(A'*A)
ans =
   Inf

您可以看到(计算的)行列式显然不为零。但这实际上并不奇怪,也不应该真正困扰你。行列式相当难以计算,所以是的,它只是舍入误差。如果你想要一个更好的近似值,你可以执行以下操作

>> s = eig(A'*A) ;
>> prod(s)
ans =
     0

在那里,你看到它更接近于零。

另一方面,条件数是矩阵(非)奇点的更好估计器。在这里

>> cond(A'*A)
ans =
   1.4853e+20

而且,由于它比 1e+16 大得多,矩阵显然是奇异的。1e+16的原因有点乏味,但主要是由于进行浮点计算时的计算机精度。

我认为这几乎只是一个四舍五入的问题,Inf 并不意味着你得到无穷大作为答案,只是你的行列式真的很大并且超过了realmax。正如Adiel所说,A*A.生成一个对称矩阵,并且应该有一个行列式的数值。例如,设置:

A=rand(5,15)

你应该发现 A*A." 的 det 只是一个数值。

那么,

你的朋友是如何得到零的,那么对于det个大矩阵来说,很容易得到 0 或 inf(你为什么要这样做,我不知道)。所以我认为他们只是得到了相同/类似的舍入问题。

最新更新