首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python上求解复杂的隐式方程

在python上求解复杂的隐式方程
EN

Stack Overflow用户
提问于 2019-11-30 19:45:18
回答 1查看 1.3K关注 0票数 1

我有这个函数:

代码语言:javascript
运行
复制
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函数,但得到了一个错误消息。这是我所做的:

代码语言:javascript
运行
复制
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)

我得到了这个错误:

代码语言:javascript
运行
复制
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。我确实在这个网站上搜索了其他类似的问题,但我仍然无法解决这个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-30 21:23:12

同级答案显示了向f传递额外参数t的方法。但是,然后你遇到了另一个问题。等式似乎很复杂,而fsolve只适用于实数函数。

解决这些问题的一种方法是mpmath,它是Python的多精度库。mpmath有一个函数findroot,它也适用于复数。请注意,由于multiprecision,它可能比其他库慢得多。我没有直接看到传递t参数的简单方法,所以我使用了lambda函数:

代码语言:javascript
运行
复制
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}')

输出:

代码语言:javascript
运行
复制
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的公差和可用解算器。

下面是代码和图:

代码语言:javascript
运行
复制
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()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59115841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档