import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
# generating a parabola with noise
np.random.seed(42)
x = np.linspace(-10, 10, 100)
y = 10 -(x-2)**2 + np.random.normal(0, 5, x.shape)
# function to fit
def func(x, a, c):
return a*x**2 + c
# desired x peak value
x_peak = 2
popt, pcov = curve_fit(func, x - x_peak, y)
y_fit = func(x - x_peak, *popt)
# plotting
plt.plot(x, y, 'k.')
plt.plot(x, y_fit)
plt.axvline(x_peak)
plt.show()
唯一的区别是因为 B 是一个常数,你没有 x - B 在方程中,你需要自己设置最小二乘问题。给定数组 x , y 不变的 B ,问题如下所示:
m = np.stack((x - B, np.ones_like(x)), axis=-1)
(A, C), *_ = np.linalg.lstsq(m, y, rcond=None)
然后,可以从以下公式中提取法向系数: a , b , c 在上面 这是一个完整的示例,就像另一个答案中的示例一样:
B = 2
np.random.seed(42)
x = np.linspace(-10, 10, 100)
y = 10 -(x - B)**2 + np.random.normal(0, 5, x.shape)
m = np.stack(((x - B)**2, np.ones_like(x)), axis=-1)
(A, C), *_ = np.linalg.lstsq(m, y, rcond=None)
a = A
b = -2 * A * B
c = A * B**2 + C
y_fit = a * x**2 + b * x + c
3条答案
按热度按时间z5btuh9x1#
我认为这是一个相当困难的问题,因为二阶多项式(ax^2+bx+c)峰值的x坐标总是在x=-b/2a。
您可以做的一件事是删除b项,并在拟合多项式时将其偏移所需的峰值x,如下面的代码所示。注意,我使用了
scipy.optimize.curve_fit
以适合自定义函数func
.输出图像:
wmtdaxz32#
在抛物线上固定一个点可以简化问题,因为现在可以用常数稍微重写方程:
给定系数
a
,b
,c
在您最初的无约束贴合中,您拥有唯一的区别是因为
B
是一个常数,你没有x - B
在方程中,你需要自己设置最小二乘问题。给定数组x
,y
不变的B
,问题如下所示:然后,可以从以下公式中提取法向系数:
a
,b
,c
在上面这是一个完整的示例,就像另一个答案中的示例一样:
你可以放弃
a
,b
,c
全力以赴结果将是相同的。
qpgpyjmq3#
在没有峰值位置的情况下,拟安装的功能应为:
y=a x^2+b x+c
当峰值位置为x=p时,给定p:
-b/(2a)=p
b=-2 a p
y=ax^2-2x+c
y=a(x^2-2px)+c
知道p,变量的一个变化:
x=x^2-2px
因此,首先从数据(x,y)计算新的数据(x,y)
然后通过线性回归计算a和c
y=a x+c