我试图利用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
适合工作。有没有办法实现这个目标?
答案 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
。