一旦确定勒让德系数,就获得勒让德多项式形式

时间:2015-06-10 20:19:16

标签: python numpy

我已经获得了最符合我数据的勒让德多项式的系数。现在我需要在数据的每个时间步确定该多项式的值。我需要这样做,以便我可以从我的数据中减去拟合。我查看了勒让德模块的文档,我不确定我是否只是不了解我的选项,或者是否没有为我想要的原生工具。如果我的数据点间隔均匀,那么linspace将是一个不错的选择,但这不是这里的情况。有没有人建议尝试什么?

对于那些想要求最小工作代码示例的人,只需使用随机数组,获取系数,并告诉我如何继续。价值观本身并不重要。这是我在这里问的技巧。感谢。

3 个答案:

答案 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,legfitlegval中使用了两个函数,这使得无需调用Horner规则就可以拟合和评估勒让德多项式,也可以自己进行簿记。 。 (虽然我确实使用Horner的规则来生成一些示例数据。)

这是一个完整的例子,我从已知多项式生成一些稀疏数据,拟合勒让德多项式,在密集网格上评估该多项式,并绘图。请注意,由于numpy库执行所有繁重的工作,拟合和评估部分需要三行

它产生下图: Legendre fitting and evaluation

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.")