1. 程式人生 > >PYTHON替代MATLAB線上性代數學習中的應用(使用Python輔助MIT 18.06 Linear Algebra學習)

PYTHON替代MATLAB線上性代數學習中的應用(使用Python輔助MIT 18.06 Linear Algebra學習)

![](http://115.182.41.123/files/202008/linearAlgerbra1.jpeg) #### 前言 MATLAB一向是理工科學生的必備神器,但隨著中美貿易衝突的一再升級,禁售與禁用的陰雲也持續籠罩在高等學院的頭頂。也許我們都應當考慮更多的途徑,來輔助我們的學習和研究工作。 雖然PYTHON和眾多模組也屬於美國技術的範圍,但開源軟體的自由度畢竟不是商業軟體可比擬的。 本文是一篇入門性文章,以麻省理工學院(MIT) 18.06版本線性代數課程為例,按照學習順序介紹PYTHON在代數運算中的基本應用。 介紹PYTHON代數計算的文章非常多,但通常都是按照模組作為劃分順序,在實際應用中仍然有較多困擾。 而按照代數課程學習的順序,循序漸進,集註在最常用和最實用的功能上,比較符合典型的應用邏輯。可以用較低的門檻逐步完成PYTHON線上性代數中各項功能的學習和應用。 MIT 2020版本的線性代數課程也已釋出,但基本是在18.06版本上的修正。Gilbert教授的年齡已經很大,只錄制了一個5節課的串講。所以系統性還是18.06版本更為完整。 很諷刺是吧,課程本身也是美國的-_-#。阿Q一下吧,就當是“師夷長技以制夷”。 首先給出幾個相關連結: [MIT 18.06 Linear Algebra課程主頁](https://mitmath.github.io/1806/) [B站完整版34講Gilbert教授課程視訊](https://www.bilibili.com/video/BV1ix411f7Yp) [配套第三版線性代數教材(百度網盤)](https://pan.baidu.com/s/1S7Glgli2JywSz5EQXgmzCw) 提取碼:uhvc 最新發行的教材是第5版,建議聽課時使用配套的第3版教材。課程完成後,把第5版教材作為輔助讀物。不然在章節、內容方面會碰到很多困惑。 #### 版本選擇 PYTHON版本的選擇現在已經沒有什麼困惑了,PYTHON2停止了支援,PYTHON3現在是必選項。我是用Mac電腦,通常使用brew安裝PYTHON3,每次有新版本的時候執行brew upgrade會自動升級。不使用內建的PYTHON3是為了防止安裝很多擴充套件庫的時候會有系統完整性檢查導致的不相容,不過只是跑一跑數學運算的話倒也不用擔心這些。 Linux各發行版各發行版是Python的開發環境,所以內建的PYTHON3就很好用。使用apt/yum等包管理工具升級的時候會自動完成版本維護。 PYTHON在Windows/Linux/Mac等各平臺上相容性非常好,特別是在數學計算方面基本不用擔心互相之間的通用問題。 計算模組方面則有了很多的選擇,常見的有NumPy/SciPy/SymPy。 其中在數值計算方面,NumPy應用非常廣泛,特別是TensorFlow/PyTorch等機器學習平臺也把NumPy當做預設支援之後。所以本文會把NumPy當做一個選擇。 在課程學習和理論研究方面,符號計算更為重要。SymPy在這方面有比較多的優勢,所以本文會把SymPy當做另外一個選擇。 SciPy以及還有一些小眾計算模組同樣非常優秀,但限於篇幅,本文中只好做一些取捨。 在PYTHON3環境下安裝NumPy/SymPy模組的方法很簡單: ```bash pip3 install numpy sympy ``` 如果碰到麻煩,一般是因為網路速度造成的。特別是預設的國外軟體源。修改軟體源到國內的伺服器會提高不少下載速度,方法是修改檔案~/.pip/pip.conf,預設是沒有這個檔案的,要自己建立~/.pip目錄和新建對應的文字檔案,內容為: ```bash [global] timeout = 6000 index-url = https://pypi.tuna.tsinghua.edu.cn/simple trusted-host = pypi.tuna.tsinghua.edu.cn ``` 這裡使用了清華大學的映象伺服器。 以上是在Linux/Mac之上的操作方法。Windows使用者,雖然PYTHON3本身沒有相容問題,但還是建議你使用Windows10內建的Linux子系統來學習。因為Mac/Linux下Python的資料更為豐富,能讓你節省很多時間。 #### 矩陣的表達 在Pyhton中使用擴充套件庫,首先要做引用,比如引入NumPy庫: ```python import numpy as np ``` 意思是引用numpy計算庫,並重新命名為np。使用numpy中的方法時,首先要以“np.”開頭。 SymPy庫的引用,通常會直接從中將所有資源直接引用到當前作用域,像使用原生方法一樣使用SymPy中定義的方法,這也是SymPy官方推薦的: ```python from sympy import * ``` 出於個人習慣,我還是更喜歡同使用NumPy一樣使用SymPy: ```python import sympy as sp ``` 雖然因此所有的SymPy的方法都要冠以“sp.”字首,但這樣不容易造成混淆從而導致錯誤。 以下內容大致對應課程(MIT 18.06 Linear Algebra課程,以下簡稱課程)第一、二講的內容。 線上性代數中,主要涉及3種資料型別,常量、標量(Scalar)、向量(Vector)、矩陣(Matrix)。 無論NumPy還是SymPy,都直接使用了基本Python型別作為標量,比如: ```python c1 = 5 ``` 而對於向量和矩陣,處理方法則有很大區別,下面先講述NumPy中的方法。 假設我們有v1、v2兩個向量,及A、B兩個矩陣: $$v1 = \left[\begin{matrix}1\\2\\\end{matrix}\right]$$ $$v2 = \left[\begin{matrix}3\\4\\\end{matrix}\right]$$ $$A = \left[\begin{matrix}1&2\\3&4\\\end{matrix}\right]$$ $$B = \left[\begin{matrix}5&6\\7&8\\\end{matrix}\right]$$ 1. 首先,NumPy接受Python原生的陣列當做向量和矩陣 ```python # 除非特別註明,我們的示例都在互動方式使用Python # 每一行開始的“>>>”就是互動方式下Python給出的提示符 >>> v1c = [1,2] >>> v2c = [3,4] >>> Ac = [[1,2],[3,4]] >>> Bc = [[5,6],[7,8]] >>> v1c #互動方式直接給出變數名是顯示變數內容的意思 [1, 2] >>> v2c [3, 4] >>> Ac [[1, 2], [3, 4]] >>> Bc [[5, 6], [7, 8]] ``` 2. 其次,NumPy內建的陣列型別(Array)也可以用來表示向量和矩陣 ```python >>> import numpy as np #別忘記引用numpy,以後不再特別註明 >>> v1n=np.array([1,2]) >>> v2n=np.array(v2c) #直接使用前面定義好的內部陣列型別初始化向量是一樣的 >>> An=np.array([[1,2],[3,4]]) >>> Bn=np.array(Bc) #直接使用前面定義好的內部陣列型別初始化矩陣 >>> v1n array([1, 2]) >>> v2n array([3, 4]) >>> An array([[1, 2], [3, 4]]) >>> Bn array([[5, 6], [7, 8]]) ``` 3. 正式的矩陣表示方法,使用NumPy內建的Matrix型別 ```python >>> v1 = np.mat([[1],[2]]) >>> v2 = np.mat([[3],[4]]) >>> A = np.mat([[1,2],[3,4]]) >>> B = np.mat(Bc) #使用以前定義過的內部陣列型別來定義矩陣 >>> v1 matrix([[1], [2]]) >>> v2 matrix([[3], [4]]) >>> A matrix([[1, 2], [3, 4]]) >>> B matrix([[5, 6], [7, 8]]) ``` 第1、2種方法,雖然在很多情況下都能正常的使用,但都算不上規範化的矩陣表示方法。特別是對於向量的表示,向量本來是縱向的,代表矩陣中的一列。但在方法1、2中,都成為了橫向的。這很容易造成概念的混淆,和計算中的錯誤。 當然Python內建的列表型別以及NumPy內建的列表型別並非不能使用,實際上它們在計算速度上有非常明顯的優勢。簡單說就是功能少的型別,往往有高的速度。所以漸漸的我們能看到很多需要速度的運算,還是會使用np.array型別操作。實際上對各種型別熟悉了之後,有了自己的習慣和原則,什麼時候用什麼型別,你自然會有自己的標準。 為了讓大家對這種差異有更清晰的認識,這裡舉幾個例子,也順便看一看最基本的矩陣計算: ```python # 計算 矩陣*常量 >>> Ac*3 #Python內部列表型別得到完全錯誤的結果,不可用 [[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]] >>> An*3 array([[ 3, 6], [ 9, 12]]) >>> A*3 matrix([[ 3, 6], [ 9, 12]]) # 計算 向量*常量 >>> v1c*3 #Python內部列表型別得到完全錯誤的結果,不可用 [1, 2, 1, 2, 1, 2] >>> v1n*3 array([3, 6]) >>> v1*3 matrix([[3], [6]]) # 計算向量加法 >>> v1c+v2c #Python內部列表型別得到完全錯誤的結果,不可用 [1, 2, 3, 4] >>> v1n+v2n array([4, 6]) >>> v1+v2 matrix([[4], [6]]) # 計算矩陣乘法 >>> Ac*Bc #Python內部沒有定義對應操作,不可用 Traceback (most recent call last):