无法使用fsolve查找给定y值的scipy.ODR的x值

时间:2017-05-28 15:04:20

标签: python scipy

我试图利用Right根据我fsolve情节的已知y值找到x值:

scipy.ODR

我能够使用import matplotlib.pyplot as plt import numpy as np from scipy.odr import ODR, Model, RealData from scipy.optimize import fsolve def func(beta, x): y = beta[0]+beta[1]*x+beta[2]*x**3 return y sqx = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) sqy = sqx**2 host = np.linspace(0,100,100) modata = RealData(sqx, sqy) model = Model(func) sqc = np.array([sqy])[0] sqc.fill(0) sqm = np.transpose([sqy, sqc, sqc]) odr = ODR(modata, model, [1,1,1]) odr.set_job(fit_type=0) output = odr.run() yn = func(output.beta, host) xvals = np.array([[fsolve(func, [10,10,10], args=((output.beta - sqm[hi]))) for hi in range(len(sqm))]]).flatten() hosty = func(host, output.beta) [plt.axhline(sqy[hi]) for hi in range(len(sqy))] [plt.axvline(xvals[hi]) for hi in range(len(xvals))] plt.plot(host ,yn,'g-',label='odr') plt.legend(loc="best"); plt.axis([0,20,0,300]) plt.show() print(xvals) news = func(xvals, output.beta) print(news) print (sqy) 函数完成目标:

curve_fit

我可以整齐地绘制数值并确认我在这里解决了正确的数字。

但如果我想使用import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit, fsolve def sq(x, a, b, c): return a*x**(2) + b*x + c sqx = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) sqy = sqx**2 meme = 10 host = np.linspace(0,20,100) popt, pcov = curve_fit(sq, sqx, sqy) xvals = np.array([[fsolve(sq, 10, args=(popt[0], popt[1], (popt[2] - sqy[hi]))) for hi in range(len(sqy))]]).flatten() hosty = sq(host, *popt) [plt.axhline(sqy[hi]) for hi in range(len(sqy))] [plt.axvline(xvals[hi]) for hi in range(len(xvals))] plt.plot(sqx, sqy, 'bo') plt.plot(host, hosty, 'r-') plt.axis([0,6,0,20]) plt.show() print(xvals) news = sq(xvals, *popt) print(news) print (sqy) 函数,我似乎无法以同样的方式执行此操作。当我在ODR中解析x时,我对如何解释符号感到困惑。它会根据需要为我提供3倍的值,因为当func fsolve索引使用func时,我必须输入3个起始估算值。< / p>

我也无法确定编写实际参数的最佳方法是什么,因为将beta作为单个变量,但我想解决我的y值,所以我需要减法发生在某个地方。

我尝试转换output.beta以不同的方式接受输入,但是当我这样做时,我无法使func适合工作。有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

让我们关注相关代码:你有

def func(beta, x):
    y = beta[0]+beta[1]*x+beta[2]*x**3
    return y

fsolve(func, [10,10,10], args=((output.beta - sqm[hi]))) 

根据fsolve syntax,它解决了func的第一个变量(可能是一个向量)。这意味着您正在使用初始猜测beta求解向量[10,10,10]。但从上下文来看,很明显你想获得x,而beta已知。

所以你需要一个func的包装器来按顺序放置参数。一个简单的例子是

fsolve(lambda x: func([1, 2, 3], x), 10)

返回array([-0.40231994])。这里fsolve得到一个参数x的函数,并为它求解。以下是它如何在您的情况下工作:

[fsolve(lambda x: func(output.beta - s, x), 10)[0] for s in sqm]

我做了两个更改:

  • 使用x for x in xlist代替x[i] for i in range(len(xlist))
  • 立即使用[0]选择解决方案,而不是稍后应用flatten