1. 程式人生 > >Eigen解線性方程組

Eigen解線性方程組

res tps n) matrix pos 三角形 語法 lar ast

一. 矩陣分解:
矩陣分解 (decomposition, factorization)是將矩陣拆解為數個矩陣的乘積,可分為三角分解、滿秩分解、QR分解、Jordan分解和SVD(奇異值)分解等,常見的有三種:1)三角分解法 (Triangular Factorization),2)QR 分解法 (QR Factorization),3)奇異值分解法 (Singular Value Decompostion)。

  1. LU三角分解:
    三角分解法是將原正方 (square) 矩陣分解成一個上三角形矩陣 或是排列(permuted) 的上三角形矩陣和一個 下三角形矩陣,這樣的分解法又稱為LU分解法。它的用途主要在簡化一個大矩陣的行列式值的計算過程,求 反矩陣,和求解聯立方程組。不過要註意這種分解法所得到的上下三角形矩陣並非唯一,還可找到數個不同 的一對上下三角形矩陣,此兩三角形矩陣相乘也會得到原矩陣。
    MATLAB以lu函數來執行lu分解法, 其語法為[L,U]=lu(A)。
  2. QR分解:
    QR分解法是將矩陣分解成一個正規正交矩陣與上三角形矩陣,所以稱為QR分解法,與此正規正交矩陣的通用符號Q有關。
    MATLAB以qr函數來執行QR分解法, 其語法為[Q,R]=qr(A)。
    3. 奇異值分解:
    奇異值分解 (singular value decomposition,SVD) 是另一種正交矩陣分解法;SVD是最可靠的分解法,但是它比QR 分解法要花上近十倍的計算時間。[U,S,V]=svd(A),其中U和V分別代表兩個正交矩陣,而S代表一對角矩陣。 和QR分解法相同, 原矩陣A不必為正方矩陣。使用SVD分解法的用途是解最小平方誤差法和數據壓縮。
    MATLAB以svd函數來執行svd分解法, 其語法為[S,V,D]=svd(A)。
  3. LLT分解:
    A=LL^T
    Cholesky 分解是把一個對稱正定的矩陣表示成一個下三角矩陣L和其轉置的乘積的分解。它要求矩陣的所有特征值必須大於零,故分解的下三角的對角元也是大於零的(LU三角分解法的變形)。
    5. LDLT分解法:
    若A為一對稱矩陣且其任意一k階主子陣均不為零,則A有如下惟一的分解形式:
    A=LDL^T
    其中L為一下三角形單位矩陣(即主對角線元素皆為1),D為一對角矩陣(只在主對角線上有元素,其余皆為零),L^T為L的轉置矩陣。
    LDLT分解法實際上是Cholesky分解法的改進,因為Cholesky分解法雖然不需要選主元,但其運算過程中涉及到開方問題,而LDLT分解法則避免了這一問題,可用於求解線性方程組。
    二. 代碼使用:
<span style="font-size:18px;">
#include <iostream>
#include <Eigen/Dense>
 using namespace std;
using namespace Eigen; 
int main()
{       
//線性方程求解 Ax =B;   
    Matrix4d A;   
    A << 2,-1,-1,1,              1,1,-2,1,               4,-6,2,-2,              3,6,-9,7;      
Vector4d B(2,4,4,9);    
    Vector4d x = A.colPivHouseholderQr().solve(B);    
    Vector4d x2 = A.llt().solve(B);    
    Vector4d x3 = A.ldlt().solve(B);     
    std::cout << "The solution is:\n" << x <<"\n\n"<<x2<<"\n\n"<<x3 <<std::endl;
}
</span>

註意:

我用上面代碼計算出來,只有A.colPivHouseholderQr().sole(B),算出來的是正常。其他都是錯誤,我就先使用這個公式運算吧,等我忙完這一陣子,在來研究一下。

運行結果:

colPivHouseholderQr:
0
-1
-4
-3
llt:
-289.143
448.714
29.9082
3.97959
ldlt:
1.52903
0.1758
-0.340206
0.0423223

除了colPivHouseholderQr、LLT、LDLT,還有以下的函數可以求解線性方程組,請註意精度和速度:解小矩陣(4*4)基本沒有速度差別

技術分享圖片

// Solve Ax = b. Result stored in x. Matlab: x = A \ b.
x = A.ldlt().solve(b));  // A sym. p.s.d.    #include <Eigen/Cholesky>
x = A.llt().solve(b));  // A sym. p.d.      #include <Eigen/Cholesky>
x = A.lu().solve(b));  // Stable and fast. #include <Eigen/LU>
x = A.qr().solve(b));  // No pivoting.     #include <Eigen/QR>
x = A.svd().solve(b));  // Stable, slowest. #include <Eigen/SVD>
// .ldlt() -> .matrixL() and .matrixD()
// .llt()  -> .matrixL()
// .lu()   -> .matrixL() and .matrixU()
// .qr()   -> .matrixQ() and .matrixR()
// .svd()  -> .matrixU(), .singularValues(), and .matrixV()

本文轉自 ChenYuanshen 的CSDN 博客 :https://blog.csdn.net/u013354805/article/details/48250547?utm_source=copy

Eigen解線性方程組