--- title: 數學軟體實作 - Solving linear system tags: 2020 Fall - 數學軟體實作 GA: G-77TT93X4N1 --- # Lecture - Jacobi method to solve linear system ## 解線性聯立方程 ### Reading: * [張智星 - MATLAB程式設計:進階篇 -6-4 聯立線性方程式](http://mirlab.org/jang/books/matlabProgramming4guru/06-4_linear_algebra.asp?title=6-4%20%C1p%A5%DF%BDu%A9%CA%A4%E8%B5{%A6%A1) ### Rules 1. 解線性聯立方程 $Ax=b$, 使用 `A\b` 2. 求某反矩陣乘以某向量 $A^{-1}b$, 使用 `A\b` 3. **絕對禁止**求反矩陣 * **絕對禁止**`inv(A)*b` 這樣的做法 * 即使數學公式看起來需要求反矩陣, 也**絕對禁止**求反矩陣 * 例如將某向量 $b$ 投影到某平面, 公式為 $A(A^TA)^{-1}A^Tb$, 也**絕對不可以**這樣寫 ``` p = A*inv(A^T*A)*A^T*b ``` 正確寫法是 ``` x = (A^T*A)\(A^T*b) p = A*x ``` --- ## sequence of vectors 之前我們討論過數列, $\{a_n\}$, 不過這裡的 $a_n\in R$ 也就是一個數字. 現在我們要推廣一點看看如果 $a_n\in R^N$ 的時候要怎樣來看這數列, 具體來說就是我們想知道這數列會不會"收斂". > 要談收斂之前需要先談"距離", 我們這邊直接討論更高級一點的 "norm". ### Vector norm 假設 $v = (v_1, v_2, \cdots, v_N)\in R^N$, 我們可以定義以下三種 norm: $$ \| v\|_1 = |v_1| + |v_2| + \cdots + |v_N| $$ $$ \| v\|_2 = \sqrt{v^2_1+v^2_2 + \cdots v^2_N} $$ $$ \| v\|_{\infty} = \max_{1\le i\le N} |v_i| $$ 在 `matlab` 裡面, 一個向量的 norm 可以用 `norm` 這個指令來計算, 分別是 ``` norm(V,2), norm(V,1), norm(V,Inf) ``` 此外, 更廣義一點我們可以定義 p-norm: $$ \| v\|_p = \left(|v_1|^p+|v_2|^p + \cdots |v_N|^p \right)^{1/p} $$ 這也可以用 `norm` 這個指令來算. ### Exercise 我想要知道 $\| x\|_p = 1$ 這個集合在二維長什麼樣子, 也就是以下這個集合: $$ \{x \quad |\quad x\in R^2, \quad \| x\|_p = 1\} $$ #### 想法: 我們知道 1. $\| x\|_2 = 1$ 是個單位圓, 所以 $p=1$ 的圖形是知道的 2. 單位向量就是長度等於 $1$ 的向量, 而任何一個向量只要把它除以自己的長度, 就變成單位向量了. #### 做法: * Input: 一個正數 p * Output: p-norm 等於一的圖 * Step 1: 隨機找 N 個二維的點 * Step 2: 把每個點投影到 p-norm=1 的圖上 * Step 3: 畫出這些點 #### pseudo code ``` Input: 一個正數 p Output: p-norm 等於一的圖 x= 隨機找 N 個二維的點 for ii=1:N x(ii) = x(ii)/norm(x(ii), p); end plot(x, '.') ``` --- ### Limit of vector sequence 有了 norm 我們就可量距離, 那就把之前一模一樣的想法套用進來: **已知 $\{a_n\}$ 是個收斂數列**, 欲判斷數列極限 $$ \lim_{n\to\infty} a_n = L. $$ 想法就是看 $n$ 很大的時候 $a_n$ 的值是多少, 如果沒有變動太多我們就覺得他收斂了! 也就是說, 我們會設定一個容許值(tolerance), 如果 $\|a_{n+1}-a_{n}\|$ 小於這個數字, 我們就覺得差不多了, 並且覺得 $L \approx a_{n+1}$. --- ### [Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method) 給定一個方陣 $A$ 以及一個向量 $b$, 我們想要解出一個向量 $x$ 滿足 $Ax=b$. #### 想法 將矩陣 $A$ 改寫成 $A=D+L+U$, 其中 $D$ 是對角線矩陣, 它保留 $A$ 的對角線部分並將其他非對角線部分都變成 $0$. 而 $L+U$ 則是把 $A$ 對角線部分變 $0$ 其他不變. 因此我們就可將原問題改寫成: $$ Ax = b \quad\to\quad (D+L+U)x=b \quad\to\quad Dx= -(L+U)x+b. $$ 然後我們可以定義一個數列 $$ Dx_{n+1}= -(L+U)x_{n}+b, $$ 或是 $$ x_{n+1}= D^{-1}\left(-(L+U)x_{n}+b\right), $$ 並且知道如果 $x_n$ 這個數列收斂了, 令他收斂到 $x$, 那 $x$ 就會滿足 $Ax=b$. #### 做法 (example): * Input: square matrix A and a vector b * Output: a vector x satisfying Ax=b * Step 1: split A into A = D + R, where D is the diagonal part (a vector), R is the rest * Step 2: choose a random initial condition x_0 * Step 3: iterate until converge * step 3.1: Evaluate y = -R*x_0 +b * step 3.2: Solve Dx = y directly #### pseudo code ``` Input: square matrix A and a vector b Output: a vector x satisfying Ax=b Step 1: obtain the diagonal vector d and the rest (also store as A) for ii=1:N d(ii) = A(ii,ii) A(ii,ii)=0 end Step 2: random initial condition x0 = rand(N,1); x1 = x0: ite = 0; while dif > Tol y = -A*x0 + b for ii=1:N x1(ii) = y(ii)/d(ii) end dif = distance between x0 and x1 x0 = x1 ite = ite+1 if(ite > ite_max) warning('too many iteration') break end end x = x1 ```