[英]Solving a complex implicit equation on python
我有這個功能:
atanh((y/10^3)-3)-((10^(3)*y^(3)-11*10^(6)*y**2 + 3.93*10^(10)*y - 4.47*10^13)/((y - 2 * 10^3)*(y -4 * 10^3)^3))=3.49875*10^(-4)*t-atanh(3) + 0.3489583
(如圖所示)。
我需要它返回給定時間 (t) 值的 ay 值(作為浮點數)。 我必須嘗試時間 t=0.1; t=2; t= 0,2。
我嘗試了 fsolve 函數,但收到一條錯誤消息。 這就是我所做的:
from cmath import atanh
from scipy.optimize import fsolve
t=1
def f(y,t):
return atanh((y/10**3)-3)-((10**(3)*y**(3)-11*10**(6)*y**2 + 3.93*10**(10)*y - 4.47*10**13)/((y - 2 * 10**3)*(y -4 * 10**3)**3))-3.49875*10**(-4)*t+atanh(3) - 0.3489583
fsolve(f(y,t),1.9)
為此我得到了這個錯誤:
TypeError Traceback (most recent call last)
<ipython-input-12-a340e1c537e4> in <module>
6 return atanh((y/10**3)-3)-((10**(3)*y**(3)-11*10**(6)*y**2 + 3.93*10**(10)*y - 4.47*10**13)/((y - 2 * 10**3)*(y -4 * 10**3)**3))-3.49875*10**(-4)*t+atanh(3) - 0.3489583
7
----> 8 fsolve(f(y,t),1.9)
<ipython-input-12-a340e1c537e4> in f(y, t)
4 t=1
5 def f(y,t):
----> 6 return cmath.atanh((y/10**3)-3)-((10**(3)*y**(3)-11*10**(6)*y**2 + 3.93*10**(10)*y - 4.47*10**13)/((y - 2 * 10**3)*(y -4 * 10**3)**3))-3.49875*10**(-4)*t+cmath.atanh(3) - 0.3489583
7
8 fsolve(f(y,t),1.9)
~\Anaconda3\lib\site-packages\sympy\core\expr.py in __complex__(self)
283 result = self.evalf()
284 re, im = result.as_real_imag()
--> 285 return complex(float(re), float(im))
286
287 def __ge__(self, other):
~\Anaconda3\lib\site-packages\sympy\core\expr.py in __float__(self)
278 if result.is_number and result.as_real_imag()[1]:
279 raise TypeError("can't convert complex to float")
--> 280 raise TypeError("can't convert expression to float")
281
282 def __complex__(self):
TypeError: can't convert expression to float
我希望在輸出中得到的是 y 作為實數。 我確實在這個網站上搜索了其他類似的問題,但我仍然無法解決這個問題。
兄弟答案顯示了將額外參數t
傳遞給f
的方法。 但是,然后你遇到了另一個問題。 方程似乎很復雜,而fsolve
僅適用於實函數。
解決這些問題的一種方法是mpmath
,Python 的多精度庫。 mpmath
有一個findroot
函數,它也適用於復數。 請注意,由於多精度,它可能比其他庫慢得多。 我沒有直接看到傳遞t
參數的簡單方法,所以我使用了lambda
函數:
from mpmath import findroot, atanh
def f(y,t):
return atanh((y/10**3)-3)-((10**(3)*y**(3)-11*10**(6)*y**2 + 3.93*10**(10)*y - 4.47*10**13)/((y - 2 * 10**3)*(y -4 * 10**3)**3))-3.49875*10**(-4)*t+atanh(3) - 0.3489583
y0 = 1.9
for t in (0.1, 2, 0.2):
ans = findroot(lambda y: f(y,t), y0)
print(f'f({ans}, {t}) = {y0}')
輸出:
f((-52.8736406772712 + 1.4361714816895e-17j), 0.1) = 1.9
f((89.2356161023805 + 1.85315086887834e-19j), 2) = 1.9
f((-44.2974817249413 + 5.70332910817907e-18j), 0.2) = 1.9
我還嘗試可視化該功能。 看起來實部幾乎與 t 線性相關,而虛部非常小。 對於某些 t 值, findroot
無法在其默認容差范圍內找到解。 我只是跳過了這些 t 值。 您可能想要試驗findroot
的公差和可用求解器。
這是代碼和情節:
import numpy as np
import matplotlib.pyplot as plt
N = 10000
ts = np.linspace(0, 3, N)
real = np.zeros(N)
imag = np.zeros(N)
for i, t in enumerate(ts):
try:
ans = findroot(lambda y: f(y, t), y0)
except:
print("no solution at", t)
pass # just use the previous value of ans
real[i], imag[i] = ans.real, ans.imag
#plt.plot(real, imag, 'b', lw=1)
scat = plt.scatter(real, imag, c=ts, s=5)
plt.ylim((min(imag), max(imag)))
plt.xlabel('real axis')
plt.ylabel('imaginary axis')
plt.title('y values for f(y,t)=1.9, t=[0, 3]', fontsize=13)
plt.colorbar(scat, label='t values')
plt.show()
您可以嘗試像這樣調用fsolve
函數
t=1
fsolve(f, 1.9, args=(t))
args:元組,可選func的任何其他參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.