【发布时间】:2015-01-07 18:16:18
【问题描述】:
我需要从 n+1 个数据点得到一个 n 次函数。通过使用以下 gnuplot 脚本,我得到了正确的拟合:
f(x) = a + b*x + c*x**2 + d*x**3 + e*x**4 + f*x**5 + g*x**6 + h*x**7 + i*x**8 + j*x**9 + k*x**10 + l*x**11 + m*x**12
# Initial values for parameters
a = 0.1
b = 0.1
c = 0.1
d = 0.1
e = 0.1
f = 0.1
g = 0.1
h = 0.1
i = 0.1
j = 0.1
k = 0.1
l = 0.1
m = 0.1
# Fit f to the following data by modifying the variables a, b, c
fit f(x) '-' via a, b, c, d, e, f, g, h, i, j, k, l, m
4.877263 45.036000
4.794907 44.421000
4.703827 43.808000
4.618065 43.251000
4.530520 42.634000
4.443111 42.070000
4.357077 41.485000
4.274298 40.913000
4.188404 40.335000
4.109381 39.795000
4.027594 39.201000
3.946413 38.650000
3.874360 38.085000
e
拟合后得到如下系数:
a = -781956
b = -2.52463e+06
c = 2.75682e+06
d = -553791
e = 693880
f = -1.51285e+06
g = 1.21157e+06
h = -522243
i = 138121
j = -23268.8
k = 2450.79
l = -147.834
m = 3.91268
然后,通过将 data 和 f(x) 绘制在一起,似乎给定的系数是正确的:
但是,我需要使用 c 代码来获得这样的拟合。在某些情况下,多项式拟合的 GNU 科学库代码 (as in this link) 的结果是正确的。但是对于上述数据(以及我数据集中的其他几个案例),我得到的结果是有缺陷的。
例如,以下代码(使用与上述示例相同的数据):
void testOfPolynomialFit(){
double x[13] = {4.877263, 4.794907, 4.703827, 4.618065, 4.530520, 4.443111, 4.357077, 4.274298, 4.188404, 4.109381, 4.027594, 3.946413, 3.874360};
double y[13] = {45.036000, 44.421000, 43.808000, 43.251000, 42.634000, 42.070000, 41.485000, 40.913000, 40.335000, 39.795000, 39.201000, 38.650000, 38.085000};
double coefficients[13];
polynomialfit(13, 13, x, y, coefficients);
int i, n = 13;
for (i = 0; i < n; i++)
{
printf("%lf\t", coefficients[i]);
}
printf("\n");
}
结果:
-6817581083.803348 12796304366.105989 -9942834843.404181 3892080279.353104
-630964566.517794 -75914607.005088 49505072.518952 -5062100.000931
-1426228.491628 514259.312320 -70903.844354 4852.824607
-136.738756
对应于形式中的一个函数:
c(x)=-6837615134.799868+12834646330.586414*x**1-9973474377.668280*x**2+3904659818.834625*x**3-633282611.288889*x**4-76066283.747942*x**5+49670960.939126*x**6-5091123.449217*x**7-1426628.818192*x**8+515175.778491*x**9-71055.177018*x**10+4863.969973*x**11-137.065848*x**12
可以在这里查看 c(x) 的样子:
在这样的图像中,a(x) 和 b(x) 是使用“多项式拟合”对少数点(4 和 7)进行拟合的函数。
那么,关于我在这里做错了什么的任何提示?还有其他一些 c 代码可以提供正确的拟合吗?
【问题讨论】:
-
实际上,@abligh,您可以完美地将
n-1度多项式拟合到任何n点。 -
@chux 查看链接中的源代码,您需要传递系数的数量,而不是多项式的次数,尽管他们决定调用变量。
-
嗯,想知道如果度数为 2、3、4 时结果如何……。问题是在 13 时出现还是显示出度数较小的迹象?
-
有一个 12 次多项式完全适合,但无论这些数字来自什么真实世界的过程,它可能都不是一个合理的模型。这些点看起来非常接近线性关系。你的大多项式摆动以准确地击中所有点,但是一旦你离开
[3.874360:4.877263]范围,它就会疯狂地偏离它们大约在线上的线。在你的fit命令之后尝试plot [3.5:5.5] f(x), '-'看看我的意思 -
@chux,我尝试了 2、4、6、8、10 和 12 系数,而 12 是我遇到的第一个问题。 See here