我已经获得了最符合我数据的勒让德多项式的系数。现在我需要在数据的每个时间步确定该多项式的值。我需要这样做,以便我可以从我的数据中减去拟合。我查看了勒让德模块的文档,我不确定我是否只是不了解我的选项,或者是否没有为我想要的原生工具。如果我的数据点间隔均匀,那么linspace将是一个不错的选择,但这不是这里的情况。有没有人建议尝试什么?
对于那些想要求最小工作代码示例的人,只需使用随机数组,获取系数,并告诉我如何继续。价值观本身并不重要。这是我在这里问的技巧。感谢。
答案 0 :(得分:2)
简化艾哈迈德的例子
In [1]: from numpy.polynomial import Polynomial, Legendre
In [2]: p = Polynomial([0.5, 0.3, 0.1])
In [3]: x = np.random.rand(10) * 10
In [4]: y = p(x)
In [5]: pfit = Legendre.fit(x, y, 2)
In [6]: plot(*pfit.linspace())
Out[6]: [<matplotlib.lines.Line2D at 0x7f815364f310>]
In [7]: plot(x, y, 'o')
Out[7]: [<matplotlib.lines.Line2D at 0x7f81535d8bd0>]
勒让德函数被缩放和偏移,因为数据应限制在区间[-1,1]内,以获得超出通常功率的任何优势。如果你想要普通旧勒让德函数的系数
In [8]: pfit.convert()
Out[8]: Legendre([ 0.53333333, 0.3 , 0.06666667], [-1., 1.], [-1., 1.])
但不建议这样做。
答案 1 :(得分:1)
一旦有了函数,就可以为时间点生成一个numpy数组:
>>> import numpy as np
>>> timepoints = [1,3,7,15,16,17,19]
>>> myarray = np.array(timepoints)
>>> def mypolynomial(bins, pfinal): #pfinal is just the estimate of the final array (i'll do quadratic)
... a,b,c = pfinal # obviously, for a*x^2 + b*x + c
... return (a*bins**2) + b*bins + c
>>> mypolynomial(myarray, (1,1,0))
array([ 2, 12, 56, 240, 272, 306, 380])
它会自动评估每个时间点是否在numpy数组中。
现在你需要做的就是重写mypolynomial,从一个简单的二次曲线示例到一个适用于勒让德多项式的曲面。将函数看作是评估float以返回值,并且当在numpy数组上调用时,它将自动为每个值计算它。
编辑: 让我们说我想将其概括为所有标准多项式:
>>> import numpy as np
>>> timepoints = [1,3,7,15,16,17,19]
>>> myarray = np.array(timepoints)
>>> def mypolynomial(bins, pfinal): #pfinal is just the estimate of the final array (i'll do quadratic)
>>> hist = np.zeros((1, len(myarray))) # define blank return
... for i in range(len(pfinal)):
... # fixed a typo here, was pfinal[-i] which would give -0 rather than -1, since negative indexing starts at -1, not -0
... const = pfinal[-i-1] # negative index to go from 0 exponent to highest exponent
... hist += const*(bins**i)
... return hist
>>> mypolynomial(myarray, (1,1,0))
array([ 2, 12, 56, 240, 272, 306, 380])
EDIT2:错字修复
EDIT3:
当他说荷马的统治有利于数值稳定时,@ Ahhthe是完美的。这里的实现如下:>>> def horner(coeffs, x):
... acc = 0
... for c in coeffs:
... acc = acc * x + c
... return acc
>>> horner((1,1,0), myarray)
array([ 2, 12, 56, 240, 272, 306, 380])
稍微修改以保持与以前相同的参数顺序,从这里的代码: http://rosettacode.org/wiki/Horner%27s_rule_for_polynomial_evaluation#Python
答案 2 :(得分:1)
当你使用一个漂亮的库来拟合多项式时,根据我的经验,该库通常会有一个评估它们的函数。所以我认为 对于了解如何生成这些系数非常有用。
在下面的例子中,我在numpy,legfit
和legval
中使用了两个函数,这使得无需调用Horner规则就可以拟合和评估勒让德多项式,也可以自己进行簿记。 。 (虽然我确实使用Horner的规则来生成一些示例数据。)
这是一个完整的例子,我从已知多项式生成一些稀疏数据,拟合勒让德多项式,在密集网格上评估该多项式,并绘图。请注意,由于numpy库执行所有繁重的工作,拟合和评估部分需要三行。
它产生下图:
import numpy as np
### Setup code
def horner(coeffs, x):
"""Evaluate a polynomial at a point or array"""
acc = 0.0
for c in reversed(coeffs):
acc = acc * x + c
return acc
x = np.random.rand(10) * 10
true_coefs = [0.1, 0.3, 0.5]
y = horner(true_coefs, x)
### Fit and evaluate
legendre_coefs = np.polynomial.legendre.legfit(x, y, 2)
new_x = np.linspace(0, 10)
new_y = np.polynomial.legendre.legval(new_x, legendre_coefs)
### Plotting only
try:
import pylab
pylab.ion() # turn on interactive plotting
pylab.figure()
pylab.plot(x, y, 'o', new_x, new_y, '-')
pylab.xlabel('x')
pylab.ylabel('y')
pylab.title('Fitting Legendre polynomials and evaluating them')
pylab.legend(['original sparse data', 'fit'])
except:
print("Can't start plots.")