Pun*_*Roy 2 math matlab matrix determinants
这是我为作业中的一个问题编写的 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);
Run Code Online (Sandbox Code Playgroud)
此行为在文档的限制部分中进行了解释,并在查找奇异矩阵的行列式小节中进行了举例说明,其中指出:det
\n\n\n\n
A尽管的行列式是A奇异的,但它仍然很大。事实上, 的行列式A应该恰好为零!的不准确是由于用于计算行列式的dLU 分解的 MATLAB\xc2\xae 实现中舍入误差的聚合造成的。det
也就是说,在这种情况下,您可以通过使用同一页面上给出的m 代码实现U来生成所需的结果,但按升序对 的对角线元素进行排序。考虑示例脚本:
clc();\nclear();\n\nA = rand(500,1500);\nb = rand(500,1);\nc = (A.\')*A;\n\n[L,U] = lu(c);\n% Since det(L) is always (+/-)1, it doesn\'t impact anything\ndiagU = diag(U);\ndetU1 = prod(diagU);\ndetU2 = prod(sort(diagU,\'descend\'));\ndetU3 = prod(sort(diagU,\'ascend\'));\n\nfprintf(\'Minimum: %+9.5e\\n\',min(abs(diagU)));\nfprintf(\'Maximum: %+9.5e\\n\',max(abs(diagU)));\nfprintf(\'Determinant:\\n\');\nfprintf(\'\\tNo Sort: %g\\n\' ,detU1);\nfprintf(\'\\tDescending Sort: %g\\n\' ,detU2);\nfprintf(\'\\tAscending Sort: %g\\n\\n\',detU3);\nRun Code Online (Sandbox Code Playgroud)\n\n这会产生输出:
\n\nMinimum: +1.53111e-13\nMaximum: +1.72592e+02\nDeterminant:\n No Sort: Inf\n Descending Sort: Inf\n Ascending Sort: 0\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,排序的方向很重要,并且由于对角线上不存在Inftrue ,因此不排序会给出结果。0降序排序会看到最大值首先相乘,显然,它们超出了realmax并且永远不会与 true 相乘0,这会生成NaN. 升序排序将所有接近零的对角线值与很少的大负值聚集在一起(事实上,更稳健的方法会根据大小进行排序,但这里没有这样做),并且它们的乘法生成一个 true (0这意味着该值低于 IEEE-754 算术中可用的最小非规范化数),从而产生“正确”结果。
正如其他人所暗示的那样,我将引用原始 Matlab 开发人员和 Mathworks 联合创始人 Cleve Moler 的话:
\n\n\n\n[行列式]在理论考虑和手工计算中很有用,但并没有为稳健的数值软件提供坚实的基础。
\n