大型矩阵反演方法 我一直在做矩阵反演的研究,我想用C++模板编程来实现算法,我发现有很多方法:高斯-约当消除或LU分解,我发现函数LuyFultCube(C++ Boost Loover)

大型矩阵反演方法 我一直在做矩阵反演的研究,我想用C++模板编程来实现算法,我发现有很多方法:高斯-约当消除或LU分解,我发现函数LuyFultCube(C++ Boost Loover),c++,algorithm,math,linear-algebra,matrix-inverse,C++,Algorithm,Math,Linear Algebra,Matrix Inverse,我想知道是否还有其他方法,从程序员或数学家的角度来看,哪种方法更好(优点/缺点) 如果没有其他更快的方法,boost库中是否已经有(矩阵)反演函数,因为我找了很多,但一个也没找到 我建议您看看源代码。正如您所提到的,标准方法是执行LU分解,然后求解标识。这可以使用LAPACK库实现,例如,使用dgetrf(因子)和dgetri(计算逆)。大多数其他线性代数库具有大致相同的函数 有一些较慢的方法,当矩阵为奇异或近似奇异时,会更优雅地降级,因此使用这些方法。例如,如果矩阵是可逆的,则逆矩阵等于逆矩阵

我想知道是否还有其他方法,从程序员或数学家的角度来看,哪种方法更好(优点/缺点)

  • 如果没有其他更快的方法,boost库中是否已经有(矩阵)反演函数,因为我找了很多,但一个也没找到


  • 我建议您看看源代码。

    正如您所提到的,标准方法是执行LU分解,然后求解标识。这可以使用LAPACK库实现,例如,使用
    dgetrf
    (因子)和
    dgetri
    (计算逆)。大多数其他线性代数库具有大致相同的函数


    有一些较慢的方法,当矩阵为奇异或近似奇异时,会更优雅地降级,因此使用这些方法。例如,如果矩阵是可逆的,则逆矩阵等于逆矩阵,并且即使矩阵是不可逆的,通常也是有用的;它可以用奇异值分解来计算。

    你可能想在LAPACK周围使用C++包装。LAPACK是非常成熟的代码:经过良好测试、优化等


    一个这样的包装是。

    请谷歌或维基百科搜索下面的流行语

    首先,确保你真的想要相反的结果。求解一个系统不需要对矩阵求逆。矩阵求逆可以通过求解n个系统来实现,其中单位基向量为右侧。所以我将重点讨论求解系统,因为它通常是您想要的

    这取决于“大”是什么意思。基于分解的方法通常必须存储整个矩阵。一旦分解了矩阵,就可以一次求解多个右侧(从而可以轻松地反转矩阵)。我不会在这里讨论因式分解方法,因为您可能已经知道它们了

    请注意,当矩阵较大时,其条件数很可能接近于零,这意味着矩阵在数值上是“不可逆的”。补救方法:预处理。请查看维基百科。这篇文章写得很好

    如果矩阵很大,则不希望存储它。如果它有很多零,它就是一个稀疏矩阵。要么它有结构(如带对角矩阵、块矩阵等),你有专门的方法来解决涉及这些矩阵的系统,要么它没有

    当你面对一个没有明显结构的稀疏矩阵,或者一个你不想存储的矩阵时,你必须使用迭代方法。它们只涉及矩阵向量乘法,不需要特殊形式的存储:您可以在需要时计算系数,或者以您想要的方式存储非零系数,等等

    这些方法是:

    • 对称正定矩阵:共轭梯度法。简言之,求解Ax=b相当于最小化1/2 x^T A x-x^T b
    • 一般矩阵的双共轭梯度法。虽然不稳定
    • 最小残差法,或最佳GMRES法。有关详细信息,请查看维基百科文章。在重新启动算法之前,您可能需要尝试迭代次数
    最后,您可以使用稀疏矩阵执行某种因式分解,使用专门设计的算法来最小化要存储的非零元素的数量。

    根据矩阵的实际大小,在任何给定时间,您可能只需要在内存中保留一小部分列。这可能需要重写对矩阵元素的低级写和读操作,我不确定Eigen(一个相当不错的库)是否允许这样做

    对于矩阵非常大的这些非常狭窄的情况,有一个库专门用于访问主要存储在磁盘中的阵列的内存


    编辑更准确地说,如果您的矩阵没有固定在可用RAM中,首选的方法是这样做。矩阵被递归分割,直到每个矩阵都适合RAM(这当然是算法的一个调整参数)。这里最棘手的部分是避免在矩阵被拉入和拉出磁盘时,CPU因矩阵反转而耗尽。这可能需要在适当的并行文件系统中进行研究,因为即使使用StlXXL,这也可能是主要的瓶颈。不过,让我重复一遍咒语过早优化是所有编程邪恶的根源。这种邪恶只能通过编码、执行和配置文件

    的净化仪式才能消除。看看wolfram会说:Max.它是一个通用矩阵还是一个特殊结构(例如三角形、正交、稀疏/密集)?此外,Boost.ublas对任何东西都很慢,但对非常小的矩阵除外。正如Vitor Py所说,如果你想要一个快速的C++线性代数库,那么就去查一下Eigen。@斯塔班:不,它是通用矩阵,为什么你认为uBlas是慢的?什么样的方面应该被模板化?我在这里有数字类型的代码模板:IMKL是一个LAPACK实现(以及更多),而不是包装器。我不是有意贬低LAPACK。我的意思是它是一个C++接口,我假设它是用Fortran写的,除非英特尔重写了所有的东西。是的,LAPACK是用FORTRAN写成的,但是IMKL是399美元!D是开源的,非常好。据我所知,它是免费的,但如果您想分发它,则需要额外的再分配协议。感谢Staffan的帮助,我现在正在查看所有的LIB和learning@ismail:当然可以,但那其实并不重要。这是一个图书馆;不管它是用C、Fortran、Prolog还是Scheme实现的,您都可以