R中使用poly.calc和自定义实现的拉格朗日插值之间的差异

mccptt67  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(59)

我试图将一个拉格朗日插值多项式拟合到一组点:

x0 <- c(576020169, 576020229, 576020296, 576020366)
y0 <- c(4816.391, 4908.896, 5011.254, 5116.875)

字符串
我尝试了两种不同的方法。第一种是通过polynom的poly.calc:

library(polynom)
lagrangeInterpolation1 <- as.function(poly.calc(x0, y0))


第二个是通过我在this answer上找到的一些代码,它使用了一个函数工厂:

lagrange <- function(x0, y0) {
    f <- function (x) {
        sum(y0 * sapply(seq_along(x0), function(j) {
            prod(x - x0[-j])/prod(x0[j] - x0[-j])
        }))
    }
    return(Vectorize(f, "x"))
}
lagrangeInterpolation2 <- lagrange(x0, y0)


应用这两个结果会产生非常不同的结果,通过自定义代码获得的结果是正确的。例如,对于x=576020225的值(在插值区间内):

lagrangeInterpolation1(576020225) # 2.486671e+18
lagrangeInterpolation2(576020225) # 4902.472 , reasonable and correct


你知道这是怎么回事吗?

hsvhsicv

hsvhsicv1#

我猜失败的多项式拟合器有点头脑简单,由于X值中的大DC偏移,已经建立了一个具有可怕条件数的天真多项式拟合矩阵。任何旨在精确的合理拟合算法都会预先将X数据范围重新缩放到-1,1(或至少减去Xn的平均值)。
从所有的X值中减去576020300,然后再次尝试拟合可能会解决这个问题。它适用于Excel(尽管我承认我曾期望Excel图表实际上得到正确的结果!)。
用一个大的加法常数A来计算(A+x)^N可能是一场灾难。
顺便说一句,你的点集看起来几乎是完全线性的,这不是一个特别好的拉格朗日插值功能测试。
FWIW我用Excel得到线性方程,

y = 1.51927651798024x - 8.7512909703529400E+08
R² = 9.9997709635592700E-01

字符串
但是如果我试着在那里拟合一个二次方程,我会得到一个完全荒谬的“答案”,一个看似合理但毫无意义的R²值-我有点惊讶,因为我认为它比这更好。
Excel使用具有较大偏移的原始X值进行二次拟合失败:

y = -1.2529309982056700E-04x2 + 1.4434425517145300E+05x - 4.1573047570104200E+13
R² = 9.9999994440119700E-01


Excel成功二次拟合,修改X' = X-567020300:

y = -1.2529309982056700E-04x2 + 1.5172783075004900E+00x + 5.0172911254711800E+03
R² = 9.9999994440119700E-01


在我看来,polynom图书馆需要一些关注!

相关问题