求三次函数的根
Find the root of a cubic function
事情是这样的。
我正在尝试使用 Python 中的 fsolve 函数来查找三次函数的根。这个三次函数有一个参数,deltaW
。我做的是把这个参数deltaW
从-50
改成50
,同时求三次函数的根。下面是我的脚本:
from scipy.optimize import fsolve
import matplotlib.pyplot as plt
import numpy as np
import pylab
g = 5.61
gamma = 6.45
kappa = 6.45
J = 6.45
rs = 1.0 #There are just parameters
m = 5.0*10**(-11)
wm = 2*3.14*23.4
X = []
X1 = []
def func(x): #Define the cubic function I need to solve
A = 1j*g**2*(kappa + 1j*deltaW)*x*x/(m*wm**2)
B = J**2 + (1j*deltaW - gamma)*(1j*deltaW + kappa)
C = A + B
D = abs(C)*x - J*np.sqrt(2*kappa)*rs
return D
for deltaW in np.linspace(-50, 50, 1000):
x0 = fsolve(func, 0.0001)
X.append(x0)
deltaW = np.linspace(-50, 50, 1000)
plt.plot(deltaW, X)
plt.show()
当我 运行 这个脚本时,我收到这两条消息:
RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last five Jacobian evaluations.
warnings.warn(msg, RuntimeWarning)
/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py:152: RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
warnings.warn(msg, RuntimeWarning)
抱歉,我没有足够的声誉将此脚本的情节放在这里。我的问题是为什么我会收到这条消息,为什么我的情节在左边看起来很奇怪。
是不是我的代码错了?
与几乎所有求根的情况一样,良好的初始猜测势在必行。有时最好的初始猜测实际上是错误的。这里就是这种情况。您的脚本的行为在答案中显示出意想不到的 'spikes' ,可以通过绘制函数和绘制围绕这些尖峰找到的根来更深入地观察(嘿,你有一个 Python 控制台 - 这真的很简单)。
你会发现求解器返回的解是跳来跳去的,尽管这个函数看起来并没有什么不同。问题是您最初猜测的 0.0001 接近于函数的极小值,求解器无法弄清楚如何摆脱那里。将初始猜测值设置为 1.0(距离很远,但在函数的一个漂亮、简单的下降部分将直接指向根),结果是:
所以,三件事:
1. 求解器需要关爱和关注——他们很少是自动的。
有时 'right' 最初的猜测可能与您所知道的正确答案相去甚远,但以这样一种方式,求解器可以轻松解决。
交互式 Python 控制台让您可以快速查看正在发生的事情。使用它的力量!
事情是这样的。
我正在尝试使用 Python 中的 fsolve 函数来查找三次函数的根。这个三次函数有一个参数,deltaW
。我做的是把这个参数deltaW
从-50
改成50
,同时求三次函数的根。下面是我的脚本:
from scipy.optimize import fsolve
import matplotlib.pyplot as plt
import numpy as np
import pylab
g = 5.61
gamma = 6.45
kappa = 6.45
J = 6.45
rs = 1.0 #There are just parameters
m = 5.0*10**(-11)
wm = 2*3.14*23.4
X = []
X1 = []
def func(x): #Define the cubic function I need to solve
A = 1j*g**2*(kappa + 1j*deltaW)*x*x/(m*wm**2)
B = J**2 + (1j*deltaW - gamma)*(1j*deltaW + kappa)
C = A + B
D = abs(C)*x - J*np.sqrt(2*kappa)*rs
return D
for deltaW in np.linspace(-50, 50, 1000):
x0 = fsolve(func, 0.0001)
X.append(x0)
deltaW = np.linspace(-50, 50, 1000)
plt.plot(deltaW, X)
plt.show()
当我 运行 这个脚本时,我收到这两条消息:
RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last five Jacobian evaluations.
warnings.warn(msg, RuntimeWarning)
/usr/lib/python2.7/dist-packages/scipy/optimize/minpack.py:152: RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
warnings.warn(msg, RuntimeWarning)
抱歉,我没有足够的声誉将此脚本的情节放在这里。我的问题是为什么我会收到这条消息,为什么我的情节在左边看起来很奇怪。
是不是我的代码错了?
与几乎所有求根的情况一样,良好的初始猜测势在必行。有时最好的初始猜测实际上是错误的。这里就是这种情况。您的脚本的行为在答案中显示出意想不到的 'spikes' ,可以通过绘制函数和绘制围绕这些尖峰找到的根来更深入地观察(嘿,你有一个 Python 控制台 - 这真的很简单)。
你会发现求解器返回的解是跳来跳去的,尽管这个函数看起来并没有什么不同。问题是您最初猜测的 0.0001 接近于函数的极小值,求解器无法弄清楚如何摆脱那里。将初始猜测值设置为 1.0(距离很远,但在函数的一个漂亮、简单的下降部分将直接指向根),结果是:
所以,三件事: 1. 求解器需要关爱和关注——他们很少是自动的。
有时 'right' 最初的猜测可能与您所知道的正确答案相去甚远,但以这样一种方式,求解器可以轻松解决。
交互式 Python 控制台让您可以快速查看正在发生的事情。使用它的力量!