主頁 > 軟體設計 > 【動手學MVG】矩陣分解與線性方程組的關系,求解線性方程組實戰代碼

【動手學MVG】矩陣分解與線性方程組的關系,求解線性方程組實戰代碼

2020-09-25 19:09:22 軟體設計

文章目錄

    • 本文解決的問題
    • QR分解
      • 投影矩陣分解得到內外參
    • SVD分解
    • 最小二乘問題
      • 最小二乘問題的求解方法
        • (列)滿秩最小二乘問題
          • 正規化方法
          • QR分解方法
          • SVD 分解方法
        • 虧秩最小二乘問題
        • 齊次最小二乘問題
    • 數值穩定性問題
    • Ax=0與Ax=b的選擇
    • 代碼實作
      • 利用SVD求解非齊次線性方程組Ax=b
      • 利用SVD求解齊次線性方程組Ax=0
    • 附錄——一些概念
    • 參考資料

在MVG(多視圖幾何)和機器學習領域,求解線性方程組幾乎是所有演算法的根本,本文旨在幫助讀者搞懂矩陣分解與線性方程組的關系,并給出利用SVD求解線性方程組的實戰代碼,


本文解決的問題

看完本文后,應解決以下問題:

  • 投影矩陣怎么通過QR分解得到相機內外參?

  • 求解非齊次線性方程組Ax=b的方法有哪些?

    • 其他一些方法通用性不大,比如克萊姆法則只用于方陣,這里不考慮,
    • 高斯消元法 | 常規方法,主要思路是講矩陣通過初等行變換,轉變為行階矩形,然后后向代入(或者稱為回代演算法)可以很容易求解,
      • 根據增系數矩陣A和廣矩陣B = (A, b) 的秩可判斷解的個數,
      • 對于齊次線性方程組Ax=0,用初等行變換將A變為行最簡形矩陣A’,即可得到同解方程組A’x=0,然后計算
      • 對于非齊次線性方程組Ax=0,用初等行變換將增廣矩陣B = (A, b)變為行最簡形矩陣A’,即可得到同解方程組A’x=0,然后計算
    • 方程Ax=b ,其中 A 為mxn,
      • 當m >n時,對于這樣的方程不能直接利用高斯或者其他的分解法進行求解 , 往往需要把方程轉換為另外一種更容易求解的模式,也就是我們常常說的各種分解,
      • 當m<n時,有無窮解,高斯消元等常規方法能解,但是如果我們要求使得二范數最小的最小二乘解,還是需要用SVD分解,
      • 當m=n時,一般可以用高斯消元等方法解,但是如果秩小于n,此時有無窮解,如果我們要求使得二范數最小的最小二乘解,還是需要用SVD分解,
    • 通過分解,將矩陣分解為特殊的形式,這些形式求逆或者對方程求解比較簡單,比如上三角矩陣、下三角矩陣、對角矩陣、正交矩陣(求逆簡單,就是其轉職),分解完后,方程可以轉換為比較好求解的形式,用常規方法求解即可,常用方法有:LU分解、QR分解、Cholesky分解
    • 通過分解,求出矩陣廣義逆矩陣 A + A^+ A+ ,則解為 x = A + b x = A^+b x=A+b ,常用方法:正規方程( x = ( A T A ) ? 1 A T b x = (A^TA)^{-1}A^Tb x=(ATA)?1ATb)、SVD分解

    總結:

    參考:知呼

    • LU需要矩陣A可逆,Cholesky是其特殊情況,Cholesky分解的時間復雜度是 m n 2 + ( 1 / 3 ) n 3 mn^2+(1/3)n^3 mn2+(1/3)n3

    • QR分解的時間復雜度是 2 m n 2 2 mn^2 2mn2 ,因為m>n,所以QR往往比Cholesky慢

    • 在實際應用中,因為數值穩定性的要求 ,稠密矩陣往往用QR求解 ,對于大型的稀疏矩陣則多用Cholesky分解,

    • SVD分解,比QR分解慢,但是比QR分解穩定,

  • 非齊次線性方程組Ax=b,什么時候有精確解,什么時候只有最小二乘解?

    • 若矩陣A為列滿秩矩陣,
      • 當A為方陣時,有精確解
      • 當A為mxn的矩陣(m>n)時,方程個數大于未知數個數;這時候多出來的方程可能會與前面的方程矛盾,這時候沒有精確解,只有最小二乘解,所以不能直接用高斯消元等方法,只能用分解的方法找其主要特征,然后再正常求解,若多出來的方程與前面方程不矛盾,即多出來的方程都可以由前面的方程線性組合得到,這時候還是有精確解的,
    • 若矩陣A為虧秩矩陣 | 即矩陣A獨立方程個數小于未知變數個數,這時候有無窮多個解,
      • 此時也只有最小二乘解
  • TODO: 為什么要用QR分解來求解非齊次線性方程組Ax=b?

    • A x = b ? Q R x = b ? R x = Q T b Ax=b \Rightarrow QRx=b \Rightarrow Rx=Q^Tb Ax=b?QRx=b?Rx=QTb 因為R是上三角矩陣,因此很容易求得方程組的解, Q T Q^T QT表示Q的轉置,由于R是三角形,因此方程組通過右側的簡單矩陣矢量乘法和向后替換來求解,
    • QR分解數值穩定性較好,
  • TODO: 為什么要用SVD分解來求解非齊次線性方程組Ax=b?

  • 為什么大多數解線性方程組用LU分解,而不用QR分解?因為QR分解時間復雜度較高,且LU分解容易并行,注意:SVD分解不容易并行看這里

  • TODO: 求解線性方程組Ax=b時,什么時候用QR分解,什么時候用SVD分解?

  • 齊次線性方程組Ax=0的最小二乘解怎么求?

    • 對 A 進行SVD分解后, A 的最小奇異值的右奇異向量就是方程組的一個解,

QR分解

注意:除特殊說明外,討論的矩陣均為實矩陣,

QR分解是一種正交三角分解,

  • 定義 8.1.1 如果非奇異實矩陣 A 能夠表示為正交矩陣 Q 與上三角矩陣 R 的積,即
    A = Q R (8.1.1) A=QR \tag{8.1.1} AQR(8.1.1)
    與 QR 分解類似,還有 RQ、QL, LQ 分解,其中 L 表示下三角矩陣,R表示上三角矩陣,矩陣的 QR 分解、 RQ 分解、 QL 分解、LQ 分解統稱為矩陣的正交三角分解,其它型別分解可通過類似 QR 分解的方法獲得,

  • 定理 8.1.1 對任意非奇異實矩陣 A 總可以分解為正交矩陣 Q 與上三角矩陣 R 的積,如果要求上三角陣 R 的對角元素均為正數,則分解是唯一的,

    非奇異矩陣是行列式不為 0 的矩陣,也就是可逆矩陣,意思是n 階方陣 A 是非奇異方陣的充要條件是 A 為可逆矩陣,也即A的行列式不為零, 即矩陣(方陣)A可逆與矩陣A非奇異是等價的概念,——參考360百科

    反之則是非奇異矩陣,

    注意:只有方陣才有奇異矩陣和非奇異矩陣的說法,

  • 定理 8.1.2 定理 8.1.1 可以推廣到非方陣的情形,對任意列滿秩的實矩陣 A 總可以分解為列正交的矩陣 Q 與上三角矩陣 R 的積, 如果
    要求上三角陣 R 的對角元素均為正數,則這種分解是唯一的,

  • 上面用 Schmidt 正交化方法構造性地證明了非奇異矩陣總可以進行 QR 分解,但是在實踐中并不使用 Schmidt 正交化方法對矩陣作 QR 分解,而是利用實用的方法: Givens 方法或 Houesholder方法,

    • Givens 旋轉方法,對于 n 階矩陣需要作 n(n-1)/2 個 Givens 旋轉矩陣的積,計算量較大,對于高階矩陣而言,用下述 Householder(反射)矩陣變換進行 QR 分解更有效,它只需要作(n-1)個 Householder 矩陣的積,其計算量大約是 Givens 旋轉方法的一半,

投影矩陣分解得到內外參

參考:《計算機視覺中的數學方法》——吳朝福 P182、知乎、Camera Calibration

RQ 分解是實作攝像機內引數、外引數求解的最為簡便的方法,令攝像機內引數矩陣為 K,外引數矩陣為 (R, t) ,由于此時的攝像機矩陣是歐氏的,所以可寫成下述形式:
P = α K [ R , t ] = [ α K R , α K t ] P = αK[R, t] = [αKR, αKt] P=αK[R,t]=[αKR,αKt]
將 P 表示成 P = [ H , p 4 ] P = [H, p_4] P=[H,p4?] ,則有
H = α K R p 4 = α K t H = αKR\\ p_4 = αKt H=αKRp4?=αKt
其中, p 4 p_4 p4? 表示P矩陣的第4列,對 H 作 RQ 分解: H = K ^ R ^ H = \hat{K}\hat{R} H=K^R^ ,其中 K ^ \hat{K} K^ 是對角元均為正數的上三角矩陣, R ^ \hat{R} R^ 為正交矩陣,并且種分解是唯一的,三角矩陣 K ^ \hat{K} K^ 與攝像機引數矩陣相差一個正常數倍,由于內引數矩陣最后一個元素為1,所以內引數矩陣必為: K = K ^ 33 ? 1 K ^ K = \hat{K}_{33}^{-1}\hat{K} K=K^33?1?K^ ,其中 K ^ 33 \hat{K}_{33} K^33? 是矩陣 K ^ \hat{K} K^ 的第(3, 3)元素,最后得到的K有如下形式:
K = [ f x k c x f y c y 1 ] K = \begin{bmatrix} f_x & k & c_x \\ & f_y & c_y \\ & & 1 \end{bmatrix} K=???fx??kfy??cx?cy?1????
其中 k = t a n θ k = tan\theta k=tanθ θ \theta θ 是影像軸之間的夾角,

如果正交矩陣 R ^ \hat{R} R^ 是一個旋轉矩陣,則它就是攝像機關于世界坐標系的姿態,如果 R ^ \hat{R} R^ 是不是旋轉矩陣,則表明所估計的攝像機矩陣與實際的(歐氏)攝像機矩陣反號,即 P 中的齊次子的符號 s g n α = ? 1 sgnα = ?1 sgnα=?1 ,于是 R = ? R ^ R = ?\hat{R} R=?R^ 就是所要求解旋轉矩陣,對于平移引數 t,可通過下式來確定:
{ t = K ? 1 P 4 , 若 R ^ 是 旋 轉 矩 陣 t = ? K ? 1 P 4 , 若 R ^ 不 是 旋 轉 矩 陣 \left\{\begin{array}{l} t = K^{-1}P_4,若\hat{R}是旋轉矩陣\\ t = -K^{-1}P_4,若\hat{R}不是旋轉矩陣 \end{array}\right. {t=K?1P4?,R^t=?K?1P4?,R^?
這樣,就得到了攝像機內、外引數,

SVD分解

  • 定理 8.3.2(奇異值分解, SVD) A ∈ R r m × n A \in R_{r}^{m \times n} ARrm×n? ,則存在 m 階正交矩陣 U 和 n 階正交矩陣 V 使
    A = U [ Σ 0 0 0 ] V T A = U\begin{bmatrix} \Sigma & \mathbf{0} \\ \mathbf{0} & 0 \end{bmatrix}V^T A=U[Σ0?00?]VT

其中 Σ = d i a g ( σ 1 , σ 2 , . . . , σ r ) Σ = diag(σ_1,σ_2 ,...,σ_r) Σ=diag(σ1?,σ2?,...,σr?) ,即 σ 1 , σ 2 , . . . , σ r σ_1,σ_2 ,...,σ_r σ1?,σ2?,...,σr? 是 A 的非零奇異值,式(8.3.2)通常記為
A = U D V T A = UDV^T A=UDVT
注意:奇異值分解既不要求矩陣 A 是可逆的方陣,也不要求它是方陣,

  • 定理 8.3.4 A ∈ R r m × r A ∈ R_{r}^{m \times r} ARrm×r? 的奇異值為 σ 1 ≥ σ 2 ≥ . . . ≥ σ r > σ r + 1 = . . . = σ n = 0 σ_1 ≥ σ_2 ≥ ... ≥ σ_r > σ_{r+1} = ... = σ_n = 0 σ1?σ2?...σr?>σr+1?=...=σn?=0 ( A + Q ) ∈ R r m × r (A+Q) ∈ R_{r}^{m \times r} (A+Q)Rrm×r? 的奇異值為 τ 1 ≥ τ 2 ≥ . . . ≥ τ r > τ r + 1 = . . . = τ n = 0 τ_1 ≥ τ_2 ≥ ... ≥ τ_r > τ_{r+1} = ... = τ_n = 0 τ1?τ2?...τr?>τr+1?=...=τn?=0 ,則必有
    ∣ σ j ? τ j ∣ ≤ ∣ ∣ Q ∣ ∣ 2 ( j = 1 , 2 , . . . , n ) |σ_j ? τ_j| ≤ || Q ||_2 ( j = 1,2,...,n) σj??τj?Q2?(j=1,2,...,n)
    定理表明,矩陣 A 在攝動 Q 下,奇異值的變化量不超過 ∣ ∣ Q ∣ ∣ 2 || Q ||_2 Q2? ,因此,矩陣奇異值的計算具有良好的數值穩定性質,

  • 奇異值分解還可以表示為

    A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + . . . + σ r u r v r T (8.3.8) A = σ_1u_1v_1^T + σ_2u_2v_2^T + ... + σ_ru_rv_r^T \tag{8.3.8} A=σ1?u1?v1T?+σ2?u2?v2T?+...+σr?ur?vrT?(8.3.8)
    并且稱 u i u_i ui? 為奇異值 σ i σ_i σi? 的左奇異向量, v i v_i vi? 為奇異值 $σ_i $的右奇異向量,

順便一提:SVD的代碼實作中,可以選擇只計算U,也可以U和V一起計算,他們的時間復雜度是不一樣的,所以你可以根據自己的需求,選擇合適的方法,

最小二乘問題

考慮線性系統:
A x = b ( A ∈ R m × n ( m > n ) , b ∈ R m , x ∈ R n ) (8.4.1) Ax = b (A ∈ R^{m \times n} (m > n),b ∈ R^m, x ∈ R^n ) \tag{8.4.1} Ax=b(ARm×n(m>n),bRm,xRn)(8.4.1)
正常來看,這個方程是沒有解的的,但在數值計算領域,我們通常的是其最小二乘解,即求 x ∈ R n x ∈ R^n xRn 使得
∣ ∣ A x ? b ∣ ∣ 2 = m i n { ∣ ∣ A v ? b ∣ ∣ 2 : v ∈ R n } (8.4.2) || Ax-b ||_2 = min\{|| Av-b ||^2 : v \in R^n\} \tag{8.4.2} Ax?b2?=min{Av?b2:vRn}(8.4.2)

X L S = { x ∈ R n : x 是 ( 8.4.1 ) 的 解 } X_{LS} = \{ x \in R^n : x 是(8.4.1)的解\} XLS?={xRn:x(8.4.1)}
則稱 X L S X_{LS} XLS? 是最小二乘問題(8.4.1)的解集; X L S X_{LS} XLS?中范數最小者稱為最小范數解,并記作 X L S X_{LS} XLS? ,即
∣ ∣ x L S ∣ ∣ 2 = m i n { ∣ ∣ x ∣ ∣ 2 : x ∈ X L S } || x_{LS} ||_2 = min\{|| x ||_2 : x \in X_{LS}\} xLS?2?=min{x2?:xXLS?}

  • 命題 8.4.1 x ∈ X L S ? A T ( A x ? b ) = 0 x \in X_{LS} ? A^T (Ax ? b) = 0 xXLS??AT(Ax?b)=0 ,其中,方程 A T ( A x ? b ) = 0 A^T (Ax ? b) = 0 AT(Ax?b)=0 稱為 A x ? b = 0 Ax ? b = 0 Ax?b=0 的正規方程,

根據命題 8.4.1,有下述推論:

  • 推論 8.4.1: (1) X L S X_{LS} XLS? 是凸集; (2) x L S x_{LS} xLS? 是唯一的; (3) X L S = { x L S } X_{LS} = \{x_{LS}\} XLS?={xLS?} 的充分必要條件是 r a n k ( A ) = n rank(A) = n rank(A)=n

最小二乘問題的求解方法

(列)滿秩最小二乘問題

如果(8.4.1)中的矩陣 A 是列滿秩的,即 rank(A) = n ,則稱它為滿秩最小二乘問題,下面考慮滿秩最小二乘問題的數值演算法,

正規化方法

將求解問題(8.4.1)轉化為求解正規化方程組
A T A x = A T b (8.4.8) A^TAx = A^Tb \tag{8.4.8} ATAx=ATb(8.4.8)
由于 rank(A) = n ,所以 A T A A^TA ATA對稱正定矩陣,正定矩陣可逆,所以 x L S = ( A T A ) ? 1 A T b x_{LS} = (A^TA)^{-1}A^Tb xLS?=(ATA)?1ATb 但由于逆矩陣 ( A T A ) ? 1 (A^TA)^{-1} (ATA)?1 不是特殊的矩陣,求解逆矩陣復雜度會很高,所以一般用其他方法,

因為 A T A A^TA ATA對稱正定矩陣,所以(8.4.8)的唯一解 x L S x_{LS} xLS? 還可以用 **Cholesky 分解法(它是LU分解的特殊情況)**求得,基本步驟為:

  1. 計算 C = A T A , d = A T b C = A^TA, d = A^Tb C=ATA,d=ATb
  2. 對 C 進行 Cholesky 分解 C = G G T C = GG^T C=GGT ;其中 G 為對角元素均大于零的上三角矩陣;
  3. 求解三角方程 G y = d Gy = d Gy=d 以及 G T x = y G^Tx = y GTx=y ,由于是上三角矩陣,后向迭代的高斯消元即可,

Cholesky 分解是LU分解的特殊情況,這種演算法的缺點很明顯:首先, A T A A^TA ATA有時候不可逆,不能得出結果,其次,即便可逆, A T A A^TA ATA數值穩定性不好,會造成誤差,

QR分解方法

正規化方法通常比較低效,下面介紹QR分解法,

設 A 有 QR 分解:
A = Q m × m [ R n × n 0 ] m × n = Q 1 R A = Q_{m \times m}\begin{bmatrix} R_{n \times n} \\ \mathbf{0} \end{bmatrix}_{m \times n} = Q_1R A=Qm×m?[Rn×n?0?]m×n?=Q1?R
其中 Q ∈ R m × m Q \in R^{m×m} QRm×m 是正交矩陣, [ R 0 ] ∈ R m × n \begin{bmatrix} R \\ \mathbf{0}\end{bmatrix} \in R^{m×n} [R0?]Rm×n, Q1 是 Q 的前 n 列組成的矩陣,即 Q = ( Q 1 n ∣ Q 2 m ? n ) Q = ( \underset{n}{Q_1} | \underset{m-n}{Q_2} ) Q=(nQ1??m?nQ2??) R ∈ R n × n R \in R^{n×n} RRn×n 是對角線上元素均為正數的上三角矩陣,

由于正交矩陣保持范數不變,所以問題 (8.4.1) 等價于
∣ ∣ Q T ( A x ? b ) ∣ ∣ 2 = m i n { ∣ ∣ Q T ( A v ? b ) ∣ ∣ 2 : v ∈ R n } ||Q^T(Ax-b)||_2 = min\{||Q^T(Av-b)||_2:v\in R^n\} QT(Ax?b)2?=min{QT(Av?b)2?:vRn}

d = Q T b = [ Q 1 T Q 2 T ] b = [ d 1 d 2 ] d = Q^Tb = \begin{bmatrix} Q_1^T \\ Q_2^T \end{bmatrix}b = \begin{bmatrix} d_1 \\ d_2 \end{bmatrix} d=QTb=[Q1T?Q2T??]b=[d1?d2??]
則有
∣ ∣ Q T ( A x ? b ) ∣ ∣ 2 2 = ∣ ∣ [ R 0 ] x ? [ d 1 d 2 ] ∣ ∣ 2 2 = ∣ ∣ R x ? d 1 ∣ ∣ 2 2 + ∣ ∣ d 2 ∣ ∣ 2 2 ||Q^T(Ax-b)||_2^2 = || \begin{bmatrix} R \\ 0 \end{bmatrix} x- \begin{bmatrix} d_1 \\ d_2 \end{bmatrix} ||_2^2 = ||Rx-d_1||_2^2 + ||d_2||_2^2 QT(Ax?b)22?=[R0?]x?[d1?d2??]22?=Rx?d1?22?+d2?22?
因此, x 是 (8.4.1) 的解當且僅當 x 是方程 R x = d 1 Rx=d_1 Rx=d1? 的解,這樣 (8.4.1) 的解可由上三角方程組 R x = d 1 Rx=d_1 Rx=d1? 求得,

而上三角方程組用后向迭代的高斯消元是很好求的,

QR 分解方法的基本步驟如下:

  1. 求 A 的 QR 分解;
  2. 計算 d 1 = Q 1 T b d_1 = Q_{1}^{T}b d1?=Q1T?b
  3. 解方程組 R x = d 1 Rx = d_1 Rx=d1?

注意: QR 分解方法比正規化方法有較好的數值穩定性,并且計算結果比正規化方法要精確,當然, QR 方法比正規化方法會付出更大的計算代價,

SVD 分解方法

由于 rank(A) = n ,所以 A 必有下述形式的 SVD 分解
A = U [ Σ n 0 ] V T A = U\begin{bmatrix} \Sigma_n \\ \mathbf{0} \end{bmatrix}V^T A=U[Σn?0?]VT

于是,A的廣義逆矩陣 A + = V [ Σ n ? 1 , 0 ] U T A^+ = V[\Sigma_n^{-1}, \mathbf{0}]U^T A+=V[Σn?1?,0]UT ,所以,問題(8.4.1)的解為
x = A + b = V ( Σ n ? 1 , 0 ) U T b = u 1 T b σ 1 v 1 + u 2 T b σ 2 v 2 + ? + u n T b σ n v n = ∑ j = 1 n u j T b σ j v j (8.4.9) x = A^+b = V(\Sigma_n^{-1}, 0)U^Tb = \frac{u_1^Tb}{\sigma_1}v_1 + \frac{u_2^Tb}{\sigma_2}v_2 + \dots + \frac{u_n^Tb}{\sigma_n}v_n = \sum_{j=1}^{n}\frac{u_j^Tb}{\sigma_j}v_j \tag{8.4.9} x=A+b=V(Σn?1?,0)UTb=σ1?u1T?b?v1?+σ2?u2T?b?v2?+?+σn?unT?b?vn?=j=1n?σj?ujT?b?vj?(8.4.9)
上式給出了 SVD 分解方法關于最小二乘解的計算公式,

虧秩最小二乘問題

如果在最小二乘問題(8.4.1)中,矩陣 A 是虧秩的,即 r = rank(A) < n ,此時(8.4.1)有無窮多解在上面介紹的處理滿秩問題(8.4.1)的正規化方法, QR 分解方法都將失敗,不能給出最小范數解 x L S x_{LS} xLS? ,但是 SVD 分解方法仍然有效,具體地說,若 rank(A) = r ,則 A 有 SVD 分解:
A = U [ Σ r 0 0 0 ( m ? r ) × ( n ? r ) ] V T A = U\begin{bmatrix} \Sigma_r & \mathbf{0} \\ \mathbf{0} & \mathbf{0}_{(m-r)\times(n-r)} \end{bmatrix}V^T A=U[Σr?0?00(m?r)×(n?r)??]VT

因此,
x = A + b = V [ Σ r ? 1 0 0 0 ] U T b = ∑ j = 1 r u j T b σ j v j (8.4.10) x = A^+b = V\begin{bmatrix} \Sigma_r^{-1} & \mathbf{0} \\ \mathbf{0} & 0 \end{bmatrix}U^Tb = \sum_{j=1}^{r}\frac{u_j^Tb}{\sigma_j}v_j \tag{8.4.10} x=A+b=V[Σr?1?0?00?]UTb=j=1r?σj?ujT?b?vj?(8.4.10)
在這里, 可以看到 SVD 分解在數值計算中的作用,不論是滿秩的還是虧秩的最小二乘問題, SVD分解方法總能給出它們的求解計算公式,并且有統一的形式,

齊次最小二乘問題

對于齊次線性方程組 A x = 0 Ax=0 Ax=0 的最小二乘解,有一點不同,

考慮齊次線性方程組:
A x = 0 ( A ∈ R m × n ( m > n ) , x ∈ R n , m > n ) Ax = 0 (A ∈ R^{m×n} (m > n), x ∈ R^n ,m > n) Ax=0(ARm×n(m>n),xRn,m>n)
對應的最小二乘問題是
∣ ∣ A x ∣ ∣ 2 = m i n { ∣ ∣ A v ∣ ∣ 2 : v ∈ R n } (8.4.13) || Ax ||_2 =min\{||Av||_2 : v \in R^n\} \tag{8.4.13} Ax2?=min{Av2?:vRn}(8.4.13)

顯然, x = 0 總是上述最小二乘問題的最小范數解,在實際中,人們所關心的并非是齊次最小二乘問題的零解,而是它的非零解因此,我們總是考慮相應的約束最小二乘問題:(之所以取單位特征向量v,是因為若v是一個解,那乘以任意一個尺度s后還是方程的解)
∣ ∣ A x ∣ ∣ 2 = m i n { ∣ ∣ A v ∣ ∣ 2 : v ∈ R n , ∣ ∣ v ∣ ∣ 2 = 1 } (8.4.13) || Ax ||_2 =min\{||Av||_2 : v \in R^n, ||v||_2=1\} \tag{8.4.13} Ax2?=min{Av2?:vRn,v2?=1}(8.4.13)
或者等價地寫成:
{ m i n ?? ∣ ∣ A x ∣ ∣ 2 2 s u b j e c t ?? t o ?? ∣ ∣ x ∣ ∣ 2 = 1 (8.4.15) \left\{ \begin{aligned} & min \; ||Ax||_2^2 \\ & subject \; to \; ||x||_2 = 1 \end{aligned} \right. \tag{8.4.15} {?minAx22?subjecttox2?=1?(8.4.15)

  • 推論 8.4.6 若 rank(A) = n ?1 時, (8.4.15)有唯一解(rank(A)=n時齊次線性方程組只有零解),這個唯一解是 A T A A^TA ATA零特征值的單位特征向量,或者說是 A 的零奇異值的右奇異向量,當資料有誤差時, A T A A^TA ATA最小特征值的單位特征向量(或者說是 A 的最小奇異值的右奇異向量)是(8.4.15)的一個解(當資料無誤差時,最小特征值就是零),

    個人證明一下,可能不嚴謹:

    矩陣 A ∈ R r m × n ( m > n ) , x ∈ R n , m > n A ∈ R_r^{m×n} (m > n), x ∈ R^n ,m > n ARrm×n?(m>n),xRn,m>n .

    一、若矩陣A的秩rank(A) = r ( r<n),對矩陣A進行SVD分解
    A = U [ Σ r 0 0 0 ( m ? r ) × ( n ? r ) ] V T A = U\begin{bmatrix} \Sigma_r & \mathbf{0} \\ \mathbf{0} & \mathbf{0}_{(m-r)\times(n-r)} \end{bmatrix}V^T A=U[Σr?0?00(m?r)×(n?r)??]VT
    其中正交矩陣 U m × m U_{m \times m} Um×m? V n × n V_{n \times n} Vn×n? 的列向量分別為 u 1 , u 2 , . . . , u m u_1,u_2,...,u_m u1?,u2?,...,um? v 1 , v 2 , . . . , v m v_1,v_2,...,v_m v1?,v2?,...,vm? ,則將SVD分解寫成向量的形式:
    A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + . . . + σ r u r v r T A = \sigma_1u_1v_1^T + \sigma_2u_2v_2^T + ... + \sigma_ru_rv_r^T A=σ1?u1?v1T?+σ2?u2?v2T?+...+σr?ur?vrT?
    其中 σ i \sigma_i σi? 是矩陣A的奇異值,也是 Σ r \Sigma_r Σr? 對角線上元素,并且 σ 1 ≥ σ 2 ≥ . . . ≥ σ r ≥ 0 \sigma_1 \ge \sigma_2 \ge ... \ge \sigma_r \ge 0 σ1?σ2?...σr?0 ,則
    ∣ ∣ A x ∣ ∣ 2 2 = ∣ ∣ σ 1 u 1 v 1 T x + σ 2 u 2 v 2 T x + . . . + σ r u r v r T x ∣ ∣ 2 2 ||Ax||_2^2 = ||\sigma_1u_1v_1^Tx + \sigma_2u_2v_2^Tx + ... + \sigma_ru_rv_r^Tx||_2^2 Ax22?=σ1?u1?v1T?x+σ2?u2?v2T?x+...+σr?ur?vrT?x22?
    由于 V n × n V_{n \times n} Vn×n? 是正交矩陣,它的列向量都為單位向量并且相互正交(向量積為0),所以當取 x = v i , i > r , 滿 足 ∣ ∣ x ∣ ∣ 2 = 1 x = v_i, i \gt r, 滿足||x||_2 = 1 x=vi?,i>r,滿x2?=1 時, v i v_i vi? v 1 , v 2 , . . . , v r v_1,v_2,...,v_r v1?,v2?,...,vr? 都正交,向量積為0,所以 ∣ ∣ A x ∣ ∣ 2 2 = 0 ||Ax||_2^2 = 0 Ax22?=0 x = v i , i > r x = v_i, i \gt r x=vi?,i>r 是(8.4.15)的解(若rank(A)=n-1則這個解是唯一解,否則若rank(A)<n-1,則這個解只是其中的一個解,事實上,在帶約束的條件下,它所有的解就是所有0奇異值對應的右奇異向量),

    二、若矩陣A的秩rank(A) = n (列滿秩),對矩陣A進行SVD分解
    A = U [ Σ n 0 ( m ? n ) × 1 ] V T A = U\begin{bmatrix} \Sigma_n \\ \mathbf{0}_{(m-n)\times1} \end{bmatrix}V^T A=U[Σn?0(m?n)×1??]VT
    寫成向量的形式:
    A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + . . . + σ n u n v n T A = \sigma_1u_1v_1^T + \sigma_2u_2v_2^T + ... + \sigma_nu_nv_n^T A=σ1?u1?v1T?+σ2?u2?v2T?+...+σn?un?vnT?
    當取 x = v n , 滿 足 ∣ ∣ x ∣ ∣ 2 = 1 x = v_n, 滿足||x||_2 = 1 x=vn?,滿x2?=1 時, v n v_n vn? v 1 , v 2 , . . . , v n ? 1 v_1,v_2,...,v_{n-1} v1?,v2?,...,vn?1? 都正交,向量積為0,而 v n , u n v_n,u_n vn?,un? 都是單位正交向量,有 v n T v n = 1 , ∣ ∣ u n ∣ ∣ 2 2 = 1 v_n^Tv_n = 1, ||u_n||_2^2 = 1 vnT?vn?=1,un?22?=1 ,所以 ∣ ∣ A x ∣ ∣ 2 2 = ∣ ∣ σ n u n ∣ ∣ 2 2 = σ n 2 ∣ ∣ u n ∣ ∣ 2 2 = σ n 2 ||Ax||_2^2 = ||\sigma_nu_n||_2^2 = \sigma_n^2||u_n||_2^2 = \sigma_n^2 Ax22?=σn?un?22?=σn2?un?22?=σn2? ,而 σ n \sigma_n σn? 是所有奇異值中最小的,

    注意:這里沒有證明為什么 x = v n x = v_n x=vn? 是此時最小二乘解,只是說明了當取這個值時,似乎它能使得(8.4.15)在約束條件下最小,

    第二種情況還可以參考《計算機視覺中的數學方法》:

    在這里插入圖片描述

    另外,看一下《計算機視覺中的多視圖幾何 第一版》,講得特別好,言簡意賅且容易理解:

    在這里插入圖片描述

數值穩定性問題

參考:視覺SLAM常見的QR分解SVD分解等矩陣分解方式求解滿秩和虧秩最小二乘問題(最全的方法分析總結)

為什么需要矩陣分解?

  • 一方面,由于一些超定方程或欠定方程,沒有精確解,只能通過分解矩陣的方式求其最小二乘解;
  • 另一方面,當資料量很大時,將一個矩陣分解為若干個矩陣的乘積可以大大降低存盤空間;
  • 其次,可以減少真正進行問題處理時的計算量,畢竟演算法掃描的元素越少完成任務的速度越快,這個時候矩陣的分解是對資料的一個預處理;
  • 再次,矩陣分解可以高效和有效的解決某些問題;
  • 最后,矩陣分解可以提高演算法數值穩定性,關于這一點下面有進一步的說明,

當資料不存在誤差時,用一般的方法求解線性方程組即可;但是當我們得到的資料有誤差,或者由于計算機精度問題導致誤差時,一般的方法求解線性方程組往往會產生很大誤差,這里舉例說明,例如方程:
{ 5 x 1 + 7 x 2 = 0.7 7 x 1 + 10 x 2 = 1 ? A x = b A = [ 5 7 7 10 ] , x = [ x 1 x 2 ] , b = [ 0.7 1 ] . \left\{ \begin{aligned} & 5x_1 + 7x_2 = 0.7 \\ & 7x_1 + 10x_2 = 1 \end{aligned} \right. \Rightarrow Ax=b \\ A = \begin{bmatrix} 5 & 7 \\ 7 & 10 \end{bmatrix}, x = \begin{bmatrix} x_1 \\ x_2 \end{bmatrix}, b = \begin{bmatrix} 0.7 \\ 1 \end{bmatrix}. {?5x1?+7x2?=0.77x1?+10x2?=1??Ax=bA=[57?710?],x=[x1?x2??],b=[0.71?].
直接對方程組求解可以得到:
x = [ 0.0 0.1 ] x = \begin{bmatrix} 0.0 \\ 0.1 \end{bmatrix} x=[0.00.1?]
現在對方程中的 b 進行一個微小擾動:
b = [ 0.69 1.01 ] , 其 中 擾 動 項 為 [ ? 0.01 0.01 ] b = \begin{bmatrix} 0.69 \\ 1.01 \end{bmatrix}, 其中擾動項為 \begin{bmatrix} -0.01 \\ 0.01 \end{bmatrix} b=[0.691.01?],[?0.010.01?]
擾動后,直接對方程組求解可以得到:
x = [ ? 0.17 0.22 ] x = \begin{bmatrix} -0.17 \\ 0.22 \end{bmatrix} x=[?0.170.22?]
結果變成了上式,可以看出當方程組中的常數矩陣發生微小的擾動時,會導致最終的結果發生較大的變化,這種結果的不穩定不是因為方程求解的方法,而是方程組矩陣本身的問題,這回給我們帶來很大的危害,例如像上面的情況,計算機求解出現舍入誤差,矩陣本身不好的話會直接導致結果失敗,
當對矩陣A或者b進行小擾動的時候,最后影響結果的是 ∣ ∣ A ∣ ∣ ? ∣ ∣ A ? 1 ∣ ∣ ||A|| \cdot ||A^{-1}|| A?A?1,與矩陣病態性成正相關,定義矩陣的條件數 c o n d ( A ) = ∣ ∣ A ∣ ∣ ? ∣ ∣ A ? 1 ∣ ∣ cond(A)= ||A|| \cdot ||A^{-1}|| cond(A)=A?A?1 來描述矩陣的病態程度,一般認為小于100的為良態,條件數在100到1000之間為中等程度的病態,條件數超過1000存在嚴重病態,以上面的矩陣A為例,采用2范數的條件數 c o n d ( A ) = 222.9955 cond(A)=222.9955 cond(A)=222.9955 矩陣處于中等病態程度,
矩陣其實就是一個給定的線性變換,特征向量描述了這個線性變換的主要方向,而特征值描述了一個特征向量的長度在該線性變換下縮放的比例,對開篇的例子進一步觀察發現,A是個對稱正定矩陣,A的特征值分別為 λ 1 = 14.93303437 λ1=14.93303437 λ1=14.93303437 λ 2 = 0.06696563 λ2=0.06696563 λ2=0.06696563 ,兩個特征值在數量級上相差很大,這意味著b發生擾動時,向量x在這兩個特征向量方向上的移動距離是相差很大的——對于λ1對應的特征向量只需要微小的移動就可到達b的新值,而對于λ2,由于它比起λ1太小了,因此需要x做大幅度移動才能到達b的新值,于是悲劇就發生了.

Ax=0與Ax=b的選擇

對于有些問題比較靈活,既可以構建出Ax=0的方程組,也可以構建出Ax=b的方程組,那么該如何選擇呢?

根據我看到的,好像大都選擇構建成Ax=0的形式去解,我也不知道為什么,這里說一下我個人的看法,

解Ax=b需要求解A的SVD分解 A = U D V T A=UDV^T A=UDVT ,解Ax=0的最小二乘解,只需要用V的最后一列向量作為解即可,而SVD分解是可以講U、D和V分開求的,可以只求部分,只求部分時,時間復雜度會大大降低,所以Ax=0的一個優勢就是:不用求解完整的SVD,從而減少時間復雜度,(具體SVD的求法,可以自行搜索)

代碼實作

為了更好地理解本章的內容,下面給出兩個求解線性方程組的實戰代碼,

如果你不知道怎么運行下面代碼,可以點擊這里下載完整的工程,工程采用VS2015構建,

利用SVD求解非齊次線性方程組Ax=b

下面代碼僅依賴于eigen庫,在VS2015上除錯通過,

#include <iostream>
#include <ctime>
#include "Eigen/Dense"

using namespace std;
using namespace Eigen;

const int MOD = 100;
int main() {

	// 構造輸入資料
	uint32_t seed = time(0);
	srand(seed); // 隨機初始化種子
	MatrixXd A(3, 3);
	// 當 A 是一個正常的可逆矩陣時,x的解應該是唯一的
	A << rand() % MOD, rand() % MOD, rand() % MOD,
		rand() % MOD, rand() % MOD, rand() % MOD, 
		rand() % MOD, rand() % MOD, rand() % MOD;

	 當 A 的秩為2時,Ax=b是一個欠定方程組,x的解有無數個,求解出來的可能與真值不同,但是Ax的結果仍然為b
	 注釋這一行去查看一下結果
	//A << rand() % MOD, rand() % MOD, rand() % MOD,
	//	rand() % MOD, rand() % MOD, rand() % MOD,
	//	0, 0, 0;

	// TODO:當 A 為4x3矩陣時,Ax=b是一個超定方程組,只能求其最小二乘解

	cout << "A: \n" << A << "\n\n";

	MatrixXd x(3, 1);
	x << rand() % MOD, rand() % MOD, rand() % MOD;

	MatrixXd b = A*x;

	// 求解方程 Ax=b,未知量為x
	// 對系數矩陣A進行SVD,A = U*D*V^t
	JacobiSVD<MatrixXd> svd(A, ComputeFullU | ComputeFullV); // SVD時不僅計算奇異值,還計算完整的U和V

	MatrixXd U_inv = svd.matrixU().transpose(); //正交矩陣的逆就是它的轉置
	MatrixXd V = svd.matrixV(); 
	cout << "U_inv: \n" << U_inv << "\n\n";
	cout << "V: \n" << V << "\n\n";

	// 求對角矩陣的逆,注意由于有0奇異值,對角陣只對左上角非0子矩陣求逆,其他部分為0
	MatrixXd d = svd.singularValues();
	MatrixXd D_inv(3, 3);
	for (int i = 0; i < d.size(); ++i) {
		// 若奇異值大于0
		if (d(i) > 1e-6)
			D_inv(i, i) = 1.0/d(i);
		else
			break;
	}
	cout << "D_inv: \n" << D_inv << "\n\n";

	// 求A的偽逆,A_inv = V*D_inv*U^t
	MatrixXd A_inv = V * D_inv * U_inv;

	// 求解x,并對比與真值是否相同,
	// 當 A 的秩為2時,Ax=b是一個欠定方程組,x的解有無數個,求解出來的可能與真值不同,但是Ax的結果仍然為b
	MatrixXd x_solve = A_inv * b;
	cout << "x: \n" << x << "\n\n";
	cout << "x_solve: \n" << x_solve << "\n\n";

	// 對比b,b應該總是相同的
	cout << "b: \n" << b << "\n\n";
	cout << "A*x_solve: \n" << A*x_solve << "\n\n";

	return 0;
}

利用SVD求解齊次線性方程組Ax=0

下面代碼僅依賴于eigen庫,在VS2015上除錯通過,

#include <iostream>
#include <ctime>
#include "Eigen/Dense"

using namespace std;
using namespace Eigen;

const int MOD = 100;
int main() {

	// 構造輸入資料
	uint32_t seed = time(0);
	srand(seed); // 隨機初始化種子
	MatrixXd A(3, 3);
	 當 A 是滿秩矩陣時,只有零解
	//A << rand() % MOD, rand() % MOD, rand() % MOD,
	//	rand() % MOD, rand() % MOD, rand() % MOD, 
	//	rand() % MOD, rand() % MOD, rand() % MOD;

	// 當 A 是虧秩矩陣時,有非零解
	// 注釋這一行去查看一下結果
	A << rand() % MOD, rand() % MOD, rand() % MOD,
		rand() % MOD, rand() % MOD, rand() % MOD,
		0, 0, 0;


	cout << "A: \n" << A << "\n\n";

	// 求解方程 Ax=b,未知量為x
	// 對系數矩陣A進行SVD,A = U*D*V^t
	JacobiSVD<MatrixXd> svd(A, ComputeFullV); // SVD時不僅計算奇異值,還計算完整的V,不需要計算U,可以減少SVD的計算量
	MatrixXd V = svd.matrixV(); 
	cout << "V: \n" << V << "\n\n";

	// 求解x,Ax=0方程組有無窮多解,V的最后一列列向量是一個非零解,且|x|=1
	MatrixXd x_solve = V.col(V.cols()-1);
	cout << "x_solve: \n" << x_solve << "\n\n";

	// 當 A 是滿秩矩陣時,只有零解,沒有非零解,則A*x_solve 與 0 相差比較大
	// 當 A 是虧秩矩陣時,有非零解,則 A*x_solve = 0
	cout << "A*x_solve: \n" << A*x_solve << "\n\n";

	return 0;
}

附錄——一些概念

  • 齊次線性方程組:Ax=0
  • 非齊次線性方程組:Ax=b
  • 超定方程 | 超定方程組是指方程個數大于未知量個數的方程組,對于方程組Ra=y,R為n×m矩陣,如果R列滿秩,且n>m,則方程組沒有精確解,此時稱方程組為超定方程組,超定方程一般是不存在解的矛盾方程,解超定方程組非常普遍,比較常用的方法是最小二乘法,
  • 欠定方程 | 方程個數小于未知量個數的方程組,
  • 正交矩陣一定是方陣

參考資料

  • 《計算機視覺中的數學方法》——吳朝福 | 本文主要參考資料
  • 線性方程組的幾種求解方法
  • 求解線性方程組解的方法?
  • Solving linear equation systems | 列舉了用各種方法解線性方程組
  • 百度百科——超定方程組
  • 線性方程組求解 | 介紹了哪些線性方程組好解,后續的各種方法都是想辦法把方程組轉化為這些形式
  • SVD分解為什么是最好的?QR分解和SVD比較?LU呢?SVD并行演算法可行么? - 知乎 | QR分解為什么能拿來求最小二乘,LU分解、QR分解、SVD分解的數值穩定性和時間復雜度

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/127605.html

標籤:其他

上一篇:計算機組成原理 干貨嘿嘿

下一篇:資料庫—查詢陳述句中left join怎么用?以及right join怎么用?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more