Python 解方程的三種方法
# 首發於我的博客 The North.
新年第一篇,搞起.
這回寫一個好久之前想做,一直擱著沒做的東西—— Python 解方程(其實是放假回家,趁著家裡電腦重裝 LOL 的時間過來寫一篇). 咱這回用三種不同的方法,來應對平常碰到的簡單方程.
Numpy 求解線性方程組
例如我們要解一個這樣的二元一次方程組:
x + 2y = 3n4x + 5y = 6n
當然我們可以手動寫出解析解,然後寫一個函數來求解,這實際上只是用 Python 來單純做「數值計算」. 但實際上,numpy.linalg.solve 可以直接求解線性方程組.
一般地,我們設解線性方程組形如 Ax=b,其中 A 是係數矩陣,b 是一維(n 維也可以,這個下面會提到),x 是未知變數. 再拿上面地最簡單的二元一次方程組為例,我們用 numpy.linalg.solve 可以這樣寫:
In [1]: import numpy as npn ...: A = np.mat(1,2; 4,5) # 構造係數矩陣 An ...: b = np.mat(3,6).T # 構造轉置矩陣 b (這裡必須為列向量)n ...: r = np.linalg.solve(A,b) # 調用 solve 函數求解n ...: print rn ...:nOut[1]: [[-1.]n [ 2.]]n
那麼前面提到的「 n 維」情形是什麼呢?實際上就是同時求解多組形式相同的二元一次方程組,例如我們想同時求解這樣兩組:
x + 2y = 3n4x + 5y = 6n
和
x + 2y = 7n4x + 5y = 8n
就可以這樣寫:
In [2]: import numpy as npn ...: A = np.mat(1,2; 4,5) # 構造係數矩陣 An ...: b = np.array([[3,6], [7,8]]).T # 構造轉置矩陣 b (這裡必須為列向量),n ...: 注意這裡用的是 arrayn ...: r = np.linalg.solve(A,b) # 調用 solve 函數求解n ...: print rn ...:nOut[2]: [[-1. -6.33333333]n [ 2. 6.66666667]]n
SciPy 求解非線性方程組
先看官方文檔的介紹:
scipy.optimize.fsolve(func, x0, args=(), fprime=None, full_output=0, col_deriv=0, xtol=1.49012e-08, maxfev=0, band=None, epsfcn=None, factor=100, diag=None)[source]n
一般來說,我們只需要用到 func 和 x0 就夠了. func 是自己構造的函數,也就是需要求解的方程組的左端(右端為 0),而 x0 則是給定的初值.
我們來看一個具體的例子,求解:
x + 2y + 3z - 6 = 0n5 * (x ** 2) + 6 * (y ** 2) + 7 * (z ** 2) - 18 = 0n9 * (x ** 3) + 10 * (y ** 3) + 11 * (z ** 3) - 30 = 0n
就可以這麼寫:
In [3]: from scipy.optimize import fsolven ...:n ...: def func(i):n ...: x, y, z = i[0], i[1], i[2]n ...: return [n ...: x + 2 * y + 3 * z - 6,n ...: 5 * (x ** 2) + 6 * (y ** 2) + 7 * (z ** 2) - 18,n ...: 9 * (x ** 3) + 10 * (y ** 3) + 11 * (z ** 3) - 30n ...: ]n ...:n ...: r = fsolve(func,[0, 0, 0])n ...: print rn ...:nOut[3]: [ 1.00000001 0.99999998 1.00000001]n
當然,SciPy 也可以用來求解線性方程組,這是因為 scipy.optimize.fsolve 本質上是最小二乘法來逼近真實結果.
SymPy 通吃一切
例如求解一個:
x + 2 * (x ** 2) + 3 * (x ** 3) - 6 = 0n
直接就是:
In [4]: from sympy import *n ...: x = symbols(x)n ...: solve(x + 2 * (x ** 2) + 3 * (x ** 3) - 6, x)nOut[4]: [1, -5/6 - sqrt(47)*I/6, -5/6 + sqrt(47)*I/6]n
另外,@Wayne Shi 的這篇 使用 Python 解數學方程 ,就重點講述了 SymPy 解線性方程組的方法,所以我也就不再贅述了。
其實 SymPy 能幹的太多了,有興趣的可以看一看 GitHub上的 Quick examples.
最後
安利自己一波,求一份關於 程序化投資 方向的寒假實習.
這是我的簡歷,歡迎騷擾.推薦閱讀:
※python中的時間處理大總結
※極光日報 第 163 期 | 2017 / 4 / 24
※Python從零開始系列連載(1)——安裝環境
※Python黑帽編程1.1虛擬機安裝和配置 Kali Linux 2016
※20170403Python控制流if、while、for語句學習