Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用fsolve查找具有给定y值的scipy.ODR的x值时遇到问题_Python_Scipy - Fatal编程技术网

Python 使用fsolve查找具有给定y值的scipy.ODR的x值时遇到问题

Python 使用fsolve查找具有给定y值的scipy.ODR的x值时遇到问题,python,scipy,Python,Scipy,我正试图利用fsolve根据我的scipy.ODR绘图的已知y值查找x值: 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.ar

我正试图利用
fsolve
根据我的
scipy.ODR
绘图的已知y值查找x值:

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)
我能够通过
曲线拟合
功能实现我的目标:

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
函数,我似乎不能用同样的方法来实现这一点。当我在我的
func
中求解
x
时,我对符号的计算结果感到困惑。它给了我3倍于所需数量的值,因为当我使用
fsolve
时,由于
func
beta
指数,我必须输入3个初始估计值

我也不知道编写实际参数的最佳方法是什么,因为put
output.beta
充当单个变量,但我想求解y值,所以我需要在某个地方进行减法


我尝试过切换
func
以不同的方式接受输入,但这样做时,
ODR
装置无法工作。有什么方法可以做到这一点吗?

让我们关注一下相关的代码:您有

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

根据,它求解
func
的第一个变量(可以是向量)。这意味着您正在求解向量
beta
,初始猜测为
[10,10,10]
。但是从上下文来看,很明显你想要得到x,beta是已知的

因此,您需要一个围绕
func
的包装器,以便将参数按顺序排列。一个简单的例子是

fsolve(lambda x: func([1, 2, 3], x), 10)
它返回
数组([-0.40231994])
。这里
fsolve
获取一个参数x的函数,并为其求解。以下是它如何在您的情况下工作:

[fsolve(lambda x: func(output.beta - s, x), 10)[0] for s in sqm]
我还做了两个更改:

  • 使用
    x表示xlist中的x
    而不是
    x[i]表示范围内的i(len(xlist))
  • 立即使用
    [0]
    选择解决方案,而不是稍后应用
    展平

建议阅读:非常感谢!这解决了我的问题。我会接受你的建议,更多地了解这些事情:)
[fsolve(lambda x: func(output.beta - s, x), 10)[0] for s in sqm]