山田的金融日記(7)-LU分解,逆矩陣
繼續C#Project 記錄
Project的目的是做各種回歸,線性回歸需要逆矩陣,逆矩陣需要LU分解,所以就從LU分解開始。
什麼是LU分解:就是將一個方塊矩陣A分解為一個下三角和上三角矩陣的乘積,自然就是L和U的由來,Lower和Upper,即A=LU;
為什麼要用LU分解,是為了在求解Ax=b的線性方程組的時候分解為LUx=b計算。這樣先算L(Ux)=b得出Ux,然後再算x會降低演算法複雜度。
引用 @PseudoSuffix 的回答
LU 分解的意義在於,將矩陣的「分解」與方程的「求解」分離。有什麼好處?
在不少應用場景中,當需要求解 的時候,左邊的矩陣 很多時候是不變的,而右邊的 隨著輸入而變化。做 分解時,只會用到矩陣 ,所以可以預先準備好 與 ,當有求解 的需求時,直接拿來用就好了:(1)解方程 ,得到(2)再通過 ,得到
將 分解為 的時間複雜度是 ,而求解 只需要 。
LU分解無非就是將非三角矩陣A轉化為上三角矩陣U的過程的反向操作。
也就是將三角矩陣U還原回A的過程。
用2x2矩陣來簡單說明
按照我們平時消去的過程,用某一行消去下面的幾行的時候,原來那一行元素我們是不動的,立即就能得出L的對角元素為1,而U的第一行元素和A的第一行元素一樣。
而想把0變回原來的 只需要在0上面加上
顯而易見 就是上式的 。
如果是3x3矩陣或更多 ,可以確定U的第一行,以及L的對角線的1
和 用最上面的方式求出後,對整個U的第二第三行進行操作,變為
就變成了解
以此類推多階的矩陣的LU就可以求了。
在code上面LU放在一起計算就可以簡便很多。
以下C#代碼
double factor = 0; for (int k = 0; k < n-1; k++) { for (int i = k+1; i < n; i++) { factor =data[i, k] / data[k, k]; data[i, k] = factor; for (int j = k+1; j < n; j++) { data[i, j] =data[i, j] - factor * data[k, j]; } } }
裡面最開始data就是A,計算過後的data,上三角部分就是U,下三角部分把對角線換成1就是L。
而解矩陣「相除」就可以用到上面的LU矩陣。
對於Ax=b 我們可以先求LM=b求出M,而M又等於Ux就可以根據Ux=M來求出x
而逆矩陣就是一個特殊的Ax=b,即
我們可以一列一列的來求A的逆矩陣,那麼Ax=b中x就是逆矩陣第n列,b就是單位矩陣的第n列。
int n = Convert.ToInt32(Math.Sqrt(data.Length)); double[,] minverse = new double[n, n]; double[,] UX = new double[n, n]; var U = Lmatrix(data); var L = Umatrix(data); for (int i = 0; i < n; i++) { var temp1 = forward(L, i); var x = backward(U, temp1); for (int j = 0; j < n; j++) { minverse[j, i] = x[j]; } }
//常見的PA=LU中的P是用來給A進行換行的,以免第一行一大堆零無法消去後面的幾行。
參考文獻:
LU Decomposition
推薦閱讀:
※多層次蒙特卡洛(multilevel monte carlo) · 自適應多層次蒙特卡洛(adaptive MLMC) · 障礙期權
※山田的金融日記(8)-停時應用(1)
※Libor Market Model 簡介2 ——分離波動率函數和校準(一部分)
※山田的金融日記(4)-CVA(1)
※結構化產品概述 Structured Products(一)
TAG:金融數學 |