scipy fsolve给出了奇怪的答案

js5cn81o  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(130)

我想用fsolve来求一个非线性超越方程的根。
下面的代码可以完成这项工作。

import numpy as np
from scipy.optimize import fsolve
import matplotlib.pyplot as plt

kappa = 0.1
tau = 90

def equation(x, * parameters):
    kappa,tau = parameters
    return -x + kappa * np.sin(-tau*x)

x = np.linspace(-0.5,0.5, 35)
roots = fsolve(equation,x, (kappa,tau))

x_2 = np.linspace(-1.5,1.5,1500)
plt.plot(x_2 ,x_2 )
plt.plot(x_2 , kappa*np.sin(-x_2 *tau))
plt.scatter(x, roots)
plt.show()

我可以通过绘制两个图f1(x) = xf2(x) = k*sin(-x*tau)(我也将其包含在代码中),以图形方式仔细检查解决方案。fsolve给了我一些错误的答案,没有抛出任何错误或收敛问题。
问题是,我想自动化改变kappatau的过程,而不需要检查哪些答案是错误的,哪些答案是正确的。但是如果输出的是错误的答案,我就不能使用这个方法了。为了安全起见,还有其他方法或选择吗?

bvn4nwqk

bvn4nwqk1#

我不能运行你的代码,有错误,无论如何,根据scipy.fsolve的文档,你应该添加一个初始猜测作为第二个输入参数,而不是像你在fsolve(equation, x0, (kappa,tau))中所做的那样添加一个范围。
当然,你也可以在循环中传递它,对数组np.linspace(0.5, 0.5, 25)中的每个值进行循环。虽然我不明白你试图通过改变kappa和tau来实现什么,但如果我认为对于这些给定的参数,你有兴趣寻找根,这里是我如何做的。

import numpy as np
from scipy.optimize import fsolve
import matplotlib.pyplot as plt

# Take it as it is
kappa   = 0.1
tau     = 90

def equation(x, parameters):
    kappa,tau = parameters
    return -x + kappa * np.sin(-tau*x)

# Initial guess of x = -0.1
SolutionStack   = []
x0              = -kappa
y               = fsolve(equation, x0, [kappa, tau])
SolutionStack.append(y[0])

y               = fsolve(equation, SolutionStack[-1], [kappa, tau])
SolutionStack.append(y[0])
deltaY = SolutionStack[-1] - SolutionStack[0]

# Define tolerance
tol = 5e-4
while ((SolutionStack[-1] <= kappa) and (deltaY <= tol)):
    y = fsolve(equation, SolutionStack[-1], [kappa, tau])
    SolutionStack.append(y[0])
    deltaY = SolutionStack[-1] - SolutionStack[-2]
    # Obviously a little guesswork is involved here, as it pertains to 0.07
    if deltaY <= tol:
        SolutionStack[-1] = SolutionStack[-1] + 0.07

# Obtaining the roots
Roots = []
Roots.append(SolutionStack[0])
for i in range(len(SolutionStack)-1):
    if (SolutionStack[i+1] - SolutionStack[i]) <= tol:
        continue
    else:
        Roots.append(SolutionStack[i+1]

可能不是最聪明的方法(假设我理解正确),但也许你现在有了主意。

相关问题