簡體   English   中英

在python上求解復雜的隱式方程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM