如何找到近乎奇异矩阵的逆矩阵?
How to find an inverse of a nearly singular matrix?
我正在使用C++和CUDA实现一种算法。但是当我试图找到一个特殊矩阵的逆矩阵时,我遇到了麻烦。 此矩阵具有以下功能:
- 它是一个方阵(假设:(m+3)x(m+3),m>0); 它的
- 转置矩阵是它的自我;
- 它的主要对角线必须是零;
- 它的右下角必须有一个 3x3 零矩阵;
- 你可以以这种形式考虑这个矩阵:H = [A ,B ;B' ,0];
我尝试了一些方法,但都失败了:
-
伪逆矩阵:
我最初使用 matlab,当我尝试使用 inv(H'*H) 时收到错误或警告:警告:矩阵对工作精度是单数,或者矩阵接近单数或缩放不良
-
一些近似方法:
参考资料在这里:近似 我发现了两种方法:高斯-乔丹消除和乔列斯基分解.当我在 matlab 中尝试 chol 时,我得到以下错误:矩阵必须是正定的
有人可以给我一些建议吗?
最好了解有关您的特定问题的更多信息,特别是如果您需要逆本身或只需要反转线性方程组。我会尽量给你指导这两种情况。
让我从你的矩阵几乎是奇异的,所以你的系统状况不佳的考虑开始。
确定近奇异矩阵的逆
矩阵正如在上面的评论和回答中已经澄清的那样,寻求近乎奇异矩阵的逆矩阵是没有意义的。有意义的是构造矩阵的正则化逆。您可以通过诉诸矩阵的光谱分解(奇异值分解或 SVD)来做到这一点。更详细地说,您可以构造奇异系统,删除作为矩阵近奇异行为的来源的最不重要的奇异值,然后使用奇异值和向量形成近似逆。当然,在这种情况下,A*A_inv
只会给出单位矩阵的近似值。
如何在 GPU 上完成此操作?首先,我要说的是,在C++或 CUDA 中实现 SVD 算法绝非易事。您应该根据所需的精度选择几种技术,例如,确定奇异值。无论如何,Matlab 有一组在 GPU 上运行的线性代数函数。此外,CULA 和 Magma 是两个提供 SVD 计算例程的库。此外,您可以考虑使用Arrayfire,它也提供线性代数例程,包括SVD。
反转一个近乎奇异的系统
在这种情况下,您应该考虑使用某种 Tikhonov 正则化,其中包括将线性系统的反演表述为优化问题并添加一个正则化项,这可能取决于您已经了解的关于您的 uknowns 的特征。
对于上述两种情况,我建议阅读一些理论。本书
M. Bertero, P. Boccacci, 成像中的逆问题简介
如果您必须找到近似逆,或者如果您具有显式反转线性系统,这将很有用。
伪逆矩阵是inv(H'*H)*H'
的,因为H
的条件数非常高(试试cond(H)
),你可能需要正则化因子来得到伪逆矩阵:inv(H'*H + lambda*eye(size(H)))*H'
。lambda
越小,这种估计将达到的偏差越低。但是lambda
值太小会导致高方差(条件不佳)。您可以尝试最适合的值。
您当然可以直接使用pinv(H)
。之所以pinv(H)*H ~= eye(size(H))
是因为pinv(H)
只是秩低于size(H,1)
的矩阵H
的倒数的近似值。换句话说,H
中的列不是完全独立的。
我想给你看一个非常简单的例子:
>>a =
0 1 0
0 0 1
0 1 0
pinv(a) * a
>>
ans =
0 0 0
0 1.0000 0
0 0 1.0000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>>a =
1 0
0 1
1 0
pinv(a) * a
>>
ans =
1.0000 0
0 1.0000
注意a * pinv(a)
不是单位矩阵,因为a
列是线性独立的,而不是a
行。查看此页面以获取更多详细信息。
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 如何找出GDB的SIGTRAP核心转储的根本原因
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 找不到QtResource文件中的文件
- Python中的for循环与C++有何不同
- VC++本机单元测试,找不到调试符号
- RegGetValue在当前用户下找不到名称
- 带有 -stdlib=libc++ 的 clang++ 9.0.1 找不到<optional>
- c++找不到具有相同哈希的无序集合元素
- 找不到以下加速库:boost_fiber
- 找不到 FLTK(缺少:FLTK_INCLUDE_DIR)
- 设置 Visual Studio for MPI: 找不到标识符错误
- "assimp/config.h"找不到,但它在文件夹中
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- C++系统找不到指定的文件错误
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",