我有这个函数:
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)值,我需要它返回一个y值(作为一个浮点数)。我必须尝试使用times 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。我确实在这个网站上搜索了其他类似的问题,但我仍然无法解决这个问题。
发布于 2019-11-30 21:23:12
同级答案显示了向f
传递额外参数t
的方法。但是,然后你遇到了另一个问题。等式似乎很复杂,而fsolve
只适用于实数函数。
解决这些问题的一种方法是mpmath
,它是Python的多精度库。mpmath
有一个函数findroot
,它也适用于复数。请注意,由于multiprecision,它可能比其他库慢得多。我没有直接看到传递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()
https://stackoverflow.com/questions/59115841
复制相似问题