我一直在嘗試使用 Python 中的 Sympy/Numpy 來求解包含 100 個變數的 10,000 個非線性方程組。
到目前為止的嘗試:
我嘗試了 Sympy 中的 nsolve 和 solve,在 numpy.linalg 中解決,所有這些都在等待 5-6 小時后仍在運行(我最終在 RAM 用完時強制停止了它們)。
用 Sympy 本身生成方程組需要大約 1 小時。我切換到 SageMath(Windows 原生),它似乎可以更好地生成方程(約 3 分鐘),但仍然無法解決它們。
有沒有辦法使用 SageMath/Python 本身中的任何特定語言或技巧來優化運行,還是應該尋找更強大的系統來運行代碼?
我的系統是 i7-11300H/16GB RAM。
編輯: linalg.solve 是一個錯誤,因為我最初認為它是一個線性系統,后來意識到它不是。
編輯:
from sympy import *
x,t=symbols('x,t')
a11, a12, a13, a14, a15, a16, a17, a18, a19, a21, a22, a23, a24 = symbols('a11, a12, a13, a14, a15, a16, a17, a18, a19, a21, a22, a23, a24')
Coeffs = [a11, a12, a13, a14, a15, a16, a17, a18, a19, a21, a22, a23, a24]
#E = expression in x,t,aij, 0<i<11,0<j<11 (nonlinear in aij)
## Sample
E = 1/2*(9*(8*t 1)*a11 3*(t**2 2*t 1)*a21 4*(t**3 3*t**2 3*t 1)*a12 5*(t**4 4*t**3)*a13 6*(t**5 5*t**4)*a14 7*(t**6 6*t**5 1)*a15 8*(t**7 7*t)*a16 2*a17*(t 1) a18)*x**2 1/48*(13860*(252*(t**10 10*t)*a19 1260*(t**2 2*t)*a21 840*(t**3 3*t**2 3*t)*a22 630*(t**4)*a23 504*(t**5 10*t**2 5*t))*a24)
Eqs = [E.subs({x:1/k,t:1/m}) for k in range(1,100) for m in range(1,100)]
sol = solve(Eqs, Coeffs)
還嘗試使用 0 陣列作為初始值的 nsolve。
uj5u.com熱心網友回復:
在您更新問題后,我想我明白您在做什么,但我認為您沒有以正確的方式解決問題。
首先,您定義方程組的方式引入了浮點系數,并且帶有浮點數的多項式方程可能非常病態,因此請確保使用 egS(1)/2或Rational(1, 2)而不是1/2這樣:
from sympy import *
x,t=symbols('x,t')
Coeffs = symbols('a11, a12, a13, a14, a15, a16, a17, a18, a19, a21, a22, a23, a24')
a11, a12, a13, a14, a15, a16, a17, a18, a19, a21, a22, a23, a24 = Coeffs
#E = expression in x,t,aij, 0<i<11,0<j<11 (nonlinear in aij)
## Sample
E = (
S(1)/2*(9*(8*t 1)*a11
3*(t**2 2*t 1)*a21
4*(t**3 3*t**2 3*t 1)*a12
5*(t** 4 4*t**3)*a13
6*(t**5 5*t**4)*a14
7*(t**6 6*t**5 1)*a15
8*(t**7 7*t)*a16
2*a17*(t 1) a18)*x**2
S(1)/48*(13860*(
252*(t**10 10*t)*a19
1260*(t**2 2*t)*a21
840*(t**3 3*t**2 3*t)*a22
630*(t**4)*a23
504*(t**5 10*t**2 5*t) )*a24
)
)
所以你有E它看起來像這樣:
In [2]: E
Out[2]:
? ? 10 ? ? 2 ? ? 3 2
a????13860?a????252?t 2520?t? 13860?a????1260?t 2520?t? 13860?a????840?t 2520?t 25
───────────────────────────────────────────────────────────────────────────────────────────────────
48
? 4 5 2 ? ? ? 3
20?t? 8731800?a???t 6985440?t 69854400?t 34927200?t? 2 ?a???(72?t 9) a????4?t
─────────────────────────────────────────────────────────────── x ??────────────── ────────────
? 2
2 ? ? 4 3? ? 5 4? ? 6 5 ? ? 7
12?t 12?t 4? a????5?t 20?t ? a????6?t 30?t ? a????7?t 42?t 7? a????8?t
───────────────── ────────────────── ────────────────── ────────────────────── ────────────
2 2 2 2 2
? ? 2 ??
56?t? a?? a????3?t 6?t 3??
───── a???(t 1) ─── ────────────────────?
2 2 ?
Ewith的第一項a24使這種非線性但只是輕微的,因為它是二次和多項式,而不是說超越或其他(您之前只將您的方程描述為非線性,這可以意味著任何事情)。
您的每代100個不同的價值觀x和t,然后試圖解決10000個公式,使E對每一個值為零。幾乎可以肯定,這些方程的唯一可能解是使x,t多項式的所有系數為零的解。我猜你實際上想要做的是找到所有為零的ai符號的值,但我們不需要 10000 個方程來做到這一點。我們可以提取系數并將其求解為方程:Ex,t
In [3]: eqs = Poly(E, [x, t]).coeffs()
In [4]: eqs
Out[4]:
? 7?a?? 5?a?? 3?a??
?4?a??, ─────, 3?a?? 21?a??, ───── 15?a??, 2?a?? 10?a??, 6?a?? ─────, 36?a?? 6?a?? 28?a
? 2 2 2
9?a?? 7?a?? a?? 3?a?? 363825?a???
?? a?? 3?a??, ───── 2?a?? ───── a?? ─── ─────, 72765?a???a??, 145530?a??, ───────────
2 2 2 2 2
a??
───, 242550?a???a??, 363825?a???a?? 727650?a???a?? 1455300?a??, 727650?a???a?? 727650?a???a??
?
727650?a???a?? 727650?a???
?
In [5]: %time [sol] = solve(eqs, Coeffs, dict=True)
CPU times: user 236 ms, sys: 8 ms, total: 244 ms
Wall time: 244 ms
In [6]: sol
Out[6]:
? a?? -4?a?? ?
?a??: ───, a??: 0, a??: 0, a??: 0, a??: 0, a??: 0, a??: ───────, a??: 0, a??: 0?
? 63 7 ?
In [7]: checksol(eqs, sol)
Out[7]: True
這表明方程組是欠定的,因此例如a18可以是任意提供的a11 = a18/63等。如果未知數之一未列在解 dict 中,那么它可以取任何獨立于其他的任意值。
I added a %time in there to show that it takes 244 milliseconds to solve this on my not very fast computer (on the current sympy master branch -- it took ~0.5 seconds with sympy 1.8). Note that I do have gmpy2 installed which can make various things faster in SymPy. You might get a speed up from installing sympy 1.9rc1 and also gmpy2 (pip install --pre --upgrade sympy and pip install gmpy2). It's also worth noting that some bugs for systems of this type were recently fixed in sympy so for other examples 1.9 might give more accurate results:
https://github.com/sympy/sympy/pull/21883
uj5u.com熱心網友回復:
您可以將執行緒用于您的目的。
這是 Corey Sch?fer 的解釋 --> https://youtu.be/IEEhzQoKtQU
核心思想是并行運行代碼,這意味著您的代碼不會像“......計算第一個代碼塊......(完成......)......計算第二個代碼塊......完成”等等。通過執行緒,您的代碼將一次運行多個代碼塊。
一個好的 Python 庫是多處理庫。
但首先要確定您的機器可以使用多少處理器。
import multiprocessing as mp
print("Number of processors: ", mp.cpu_count())
--> Number of processors: 4
例如,我的電腦只有 4 個可用的處理器
,這里是 python 中的執行緒示例:
import requests
from multiprocessing.dummy import Pool as ThreadPool
urls = ['https://www.python.org',
'https://www.python.org/about/']
def get_status(url):
r = requests.get(url)
return r.status_code
if __name__ == "__main__":
pool = ThreadPool(4) # Make the Pool of workers
results = pool.map(get_status, urls) #Open the urls in their own threads
pool.close() #close the pool and wait for the work to finish
pool.join()
上面的代碼將遍歷 URL 串列并輸出 URL 的狀態代碼。如果沒有執行緒化,代碼將以迭代方式執行此操作。第一個 URL --> 狀態 200 ... NEXT ... 第二個 URL --> 狀態 200 ...NEXT ... 等等。
我希望我能幫到你一點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/316533.html
下一篇:pldebugger擴展在哪里?
