[英]Polynomial Curve fittings with GNU Scientific Library (GSL)
I'm going to use GNU Scientific Library (GSL) for solving Polynomial Curve fittings. 我将使用GNU科学库(GSL)求解多项式曲线拟合。 Here is my function for polyFit - see "C++ code" . 这是我的polyFit函数-请参见“ C ++代码” 。 If I use below example data, then I got the result below - see "Output" . 如果我使用下面的示例数据,那么我得到下面的结果-参见“输出” 。 I've tried to verification if it is OK or not with python - see "Python Code" and Python Output . 我试图用python验证是否可以-请参见“ Python代码”和Python Output 。 I don't know why GSL and Python result is different. 我不知道为什么GSL和Python结果不同。 The trend of Python result is similar with original data. Python结果的趋势与原始数据相似。 However, GSL result is different. 但是,GSL结果不同。 Why it is different ? 为什么与众不同? It would be very helpful if Somebody help me. 如果有人帮助我,那将非常有帮助。
Output : 输出:
> Polynomial Curve Fittings : order = 6 th, Data Size = 200
> best fit: Y = 840810 + 2354.69 X + 1.66468 X^2 + -0.000321755 X^3 + -3.53193e- 007 X^4 + 1.06755e-010 X^5 + -8.11813e-015 X^6
> chisq = 4.76957e+008
C++ Code : C ++代码:
struct LensTiltMap{
double xPos;
double yPos1;
double yCompPos1;
};
std::vector<LensTiltMap> polyFit(std::vector<LensTiltMap> _vecData)
{
std::vector<LensTiltMap> _vec;
if (_vecData.size() != 0)
{
double* data_x = &_vecData[0].xPos;
double* data_y = &_vecData[0].yPos1;
int n = _vecData.size();
int order = 6;
double chisq;
gsl_vector *y, *c;
gsl_matrix *X, *cov;
y = gsl_vector_alloc(n);
c = gsl_vector_alloc(order + 1);
X = gsl_matrix_alloc(n, order + 1);
cov = gsl_matrix_alloc(order + 1, order + 1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < order + 1; j++) {
gsl_matrix_set(X, i, j, pow(data_x[i], j));
}
gsl_vector_set(y, i, data_y[i]);
}
gsl_multifit_linear_workspace * work = gsl_multifit_linear_alloc(n, order + 1);
gsl_multifit_linear(X, y, c, cov, &chisq, work);
gsl_multifit_linear_free(work);
std::vector<double> vc;
for (int i = 0; i < order + 1; i++) {
vc.push_back(gsl_vector_get(c, i));
}
cout << "# Polynomial Curve Fittings : order = " << order << " th, Data Size = " << n << endl;
cout << "# best fit: Y = " << vc[0] << " + " << vc[1] << " X + " << vc[2] << " X^2 + " << vc[3] << " X^3 + " << vc[4] << " X^4 + " << vc[5] << " X^5 + " << vc[6] << " X^6 " << endl;
cout << "# covariance matrix = \n"
<< "[" << gsl_matrix_get(cov, (0), (0)) << ", " << gsl_matrix_get(cov, (0), (1)) << ", " << gsl_matrix_get(cov, (0), (2)) << ", " << gsl_matrix_get(cov, (0), (3)) << ", " << gsl_matrix_get(cov, (0), (4)) << ", " << gsl_matrix_get(cov, (0), (5)) << ", " << gsl_matrix_get(cov, (0), (6))
<< gsl_matrix_get(cov, (1), (0)) << ", " << gsl_matrix_get(cov, (1), (1)) << ", " << gsl_matrix_get(cov, (1), (2)) << ", " << gsl_matrix_get(cov, (1), (3)) << ", " << gsl_matrix_get(cov, (1), (4)) << ", " << gsl_matrix_get(cov, (1), (5)) << ", " << gsl_matrix_get(cov, (1), (6))
<< gsl_matrix_get(cov, (2), (0)) << ", " << gsl_matrix_get(cov, (2), (1)) << ", " << gsl_matrix_get(cov, (2), (2)) << ", " << gsl_matrix_get(cov, (2), (3)) << ", " << gsl_matrix_get(cov, (2), (4)) << ", " << gsl_matrix_get(cov, (2), (5)) << ", " << gsl_matrix_get(cov, (2), (6))
<< gsl_matrix_get(cov, (3), (0)) << ", " << gsl_matrix_get(cov, (3), (1)) << ", " << gsl_matrix_get(cov, (3), (2)) << ", " << gsl_matrix_get(cov, (3), (3)) << ", " << gsl_matrix_get(cov, (3), (4)) << ", " << gsl_matrix_get(cov, (3), (5)) << ", " << gsl_matrix_get(cov, (3), (6))
<< gsl_matrix_get(cov, (4), (0)) << ", " << gsl_matrix_get(cov, (4), (1)) << ", " << gsl_matrix_get(cov, (4), (2)) << ", " << gsl_matrix_get(cov, (4), (3)) << ", " << gsl_matrix_get(cov, (4), (4)) << ", " << gsl_matrix_get(cov, (4), (5)) << ", " << gsl_matrix_get(cov, (4), (6))
<< gsl_matrix_get(cov, (5), (0)) << ", " << gsl_matrix_get(cov, (5), (1)) << ", " << gsl_matrix_get(cov, (5), (2)) << ", " << gsl_matrix_get(cov, (5), (3)) << ", " << gsl_matrix_get(cov, (5), (4)) << ", " << gsl_matrix_get(cov, (5), (5)) << ", " << gsl_matrix_get(cov, (5), (6))
<< gsl_matrix_get(cov, (6), (0)) << ", " << gsl_matrix_get(cov, (6), (1)) << ", " << gsl_matrix_get(cov, (6), (2)) << ", " << gsl_matrix_get(cov, (6), (3)) << ", " << gsl_matrix_get(cov, (6), (4)) << ", " << gsl_matrix_get(cov, (6), (5)) << ", " << gsl_matrix_get(cov, (6), (6))
<< "]" << endl;
cout << "# chisq = " << chisq << endl;
gsl_vector_free(y);
gsl_vector_free(c);
gsl_matrix_free(X);
gsl_matrix_free(cov);
for (std::vector<LensTiltMap>::iterator it = _vecData.begin(); it != _vecData.end(); ++it) {
LensTiltMap _data = *it;
_data.yCompPos1 = vc[6] + vc[5] * pow(_data.xPos, 1) + vc[4] * pow(_data.xPos, 2) + vc[3] * pow(_data.xPos, 3) + vc[2] * pow(_data.xPos, 4) + vc[1] * pow(_data.xPos, 5) + vc[0] * pow(_data.xPos, 6);
_vec.push_back(_data);
}
}
else
return _vecData;
return _vec.size() != 0 ? _vec : _vecData;
}
Python Code : Python代码:
See below example data with python. 请参见下面的python示例数据。 I use the example below link. 我使用下面的示例链接。
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-1000,1000,10)
y = np.array([ 5347.21, 5338.78, 5365.01, 5351.12, 5349.49, 5351.44,
5321.54, 5302.74, 5354.44, 5349.04, 5322.55, 5353.69,
5366.55, 5345.69, 5295.52, 5331.35, 5343.48, 5327.36,
5364.93, 5369.18, 5341.57, 5326.26, 5381.95, 5343.6 ,
5372.34, 5341.09, 5341.8 , 5319.17, 5357.89, 5366.52,
5372.47, 5405.77, 5335.64, 5375.94, 5334.32, 5408.44,
5345.63, 5388.27, 5407.22, 5415.23, 5402.14, 5401.65,
5425.57, 5370.68, 5418.62, 5476.2 , 5447.66, 5467.31,
5444.86, 5450.44, 5525.4 , 5489.32, 5494.43, 5457.14,
5504.57, 5555.23, 5520.92, 5513.36, 5585.96, 5621.79,
5558.42, 5608.05, 5596.97, 5599.98, 5583.34, 5610.35,
5679.16, 5666.85, 5695.01, 5693.84, 5722.46, 5726.53,
5714.61, 5722.61, 5733.16, 5699.93, 5753.52, 5754.43,
5745.86, 5828.79, 5772.72, 5825.61, 5819.32, 5852.81,
5876. , 5852.52, 5849.53, 5863.86, 5892.23, 5907.96,
5858.39, 5942.41, 5938.36, 5935.82, 5955.2 , 5910.05,
5958.88, 5995.05, 5923.07, 5968.93, 5933.05, 5920.94,
5930.83, 5993.96, 5919.47, 5956.48, 5948.48, 5966.21,
5990.58, 5996.2 , 5937.79, 5922.37, 5903.46, 5925.97,
5942.13, 5878.51, 5915.93, 5895.85, 5881.16, 5835.25,
5895.39, 5794.58, 5842.72, 5809.81, 5834.05, 5843.11,
5771.03, 5741.2 , 5763.68, 5738.31, 5756.64, 5686.59,
5686.05, 5711.26, 5680.77, 5678. , 5670.78, 5626.55,
5599.49, 5572.86, 5573.88, 5572.26, 5532.51, 5523.21,
5541.77, 5528.95, 5531.11, 5542.49, 5515.9 , 5509.62,
5485.16, 5488.85, 5495.59, 5465.52, 5434.44, 5507.97,
5459.17, 5421.25, 5419.23, 5416.85, 5396.44, 5410.29,
5430.09, 5385.02, 5361.95, 5391.7 , 5345.41, 5350.12,
5345.22, 5370.72, 5322.03, 5348.25, 5370.73, 5338.4 ,
5300.9 , 5325.29, 5323.3 , 5341.07, 5316.03, 5281.7 ,
5333.72, 5287.52, 5355.5 , 5313.96, 5315.16, 5314.75,
5293.81, 5313.89, 5317.65, 5289.2 , 5322.9 , 5275.23,
5273.53, 5278.15, 5291.24, 5260.07, 5290.77, 5272.02,
5284.21, 5317.56])
z=numpy.polyfit(x,y,6)
xp = np.linspace(-1000,1000,200)
p = np.poly1d(z)
_ = plt.plot(x, y, '.', xp, p(xp), '-')
plt.ylim(4000,7000)
plt.show()
Python Output : Python输出:
z
Out[35]:
array([ -1.93861649e-15, 1.30945729e-13, 3.97750836e-09,
-2.32744951e-07, -2.69634938e-03, 7.39431395e-02,
5.93818062e+03])
http://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html http://docs.scipy.org/doc/numpy/reference/generation/numpy.polyfit.html
Example Data : 示例数据:
x = [-1000, -990, -980, -970, -960, -950, -940, -930, -920,
-910, -900, -890, -880, -870, -860, -850, -840, -830,
-820, -810, -800, -790, -780, -770, -760, -750, -740,
-730, -720, -710, -700, -690, -680, -670, -660, -650,
-640, -630, -620, -610, -600, -590, -580, -570, -560,
-550, -540, -530, -520, -510, -500, -490, -480, -470,
-460, -450, -440, -430, -420, -410, -400, -390, -380,
-370, -360, -350, -340, -330, -320, -310, -300, -290,
-280, -270, -260, -250, -240, -230, -220, -210, -200,
-190, -180, -170, -160, -150, -140, -130, -120, -110,
-100, -90, -80, -70, -60, -50, -40, -30, -20,
-10, 0, 10, 20, 30, 40, 50, 60, 70,
80, 90, 100, 110, 120, 130, 140, 150, 160,
170, 180, 190, 200, 210, 220, 230, 240, 250,
260, 270, 280, 290, 300, 310, 320, 330, 340,
350, 360, 370, 380, 390, 400, 410, 420, 430,
440, 450, 460, 470, 480, 490, 500, 510, 520,
530, 540, 550, 560, 570, 580, 590, 600, 610,
620, 630, 640, 650, 660, 670, 680, 690, 700,
710, 720, 730, 740, 750, 760, 770, 780, 790,
800, 810, 820, 830, 840, 850, 860, 870, 880,
890, 900, 910, 920, 930, 940, 950, 960, 970,
980, 990]
y = [ 5347.21, 5338.78, 5365.01, 5351.12, 5349.49, 5351.44,
5321.54, 5302.74, 5354.44, 5349.04, 5322.55, 5353.69,
5366.55, 5345.69, 5295.52, 5331.35, 5343.48, 5327.36,
5364.93, 5369.18, 5341.57, 5326.26, 5381.95, 5343.6 ,
5372.34, 5341.09, 5341.8 , 5319.17, 5357.89, 5366.52,
5372.47, 5405.77, 5335.64, 5375.94, 5334.32, 5408.44,
5345.63, 5388.27, 5407.22, 5415.23, 5402.14, 5401.65,
5425.57, 5370.68, 5418.62, 5476.2 , 5447.66, 5467.31,
5444.86, 5450.44, 5525.4 , 5489.32, 5494.43, 5457.14,
5504.57, 5555.23, 5520.92, 5513.36, 5585.96, 5621.79,
5558.42, 5608.05, 5596.97, 5599.98, 5583.34, 5610.35,
5679.16, 5666.85, 5695.01, 5693.84, 5722.46, 5726.53,
5714.61, 5722.61, 5733.16, 5699.93, 5753.52, 5754.43,
5745.86, 5828.79, 5772.72, 5825.61, 5819.32, 5852.81,
5876. , 5852.52, 5849.53, 5863.86, 5892.23, 5907.96,
5858.39, 5942.41, 5938.36, 5935.82, 5955.2 , 5910.05,
5958.88, 5995.05, 5923.07, 5968.93, 5933.05, 5920.94,
5930.83, 5993.96, 5919.47, 5956.48, 5948.48, 5966.21,
5990.58, 5996.2 , 5937.79, 5922.37, 5903.46, 5925.97,
5942.13, 5878.51, 5915.93, 5895.85, 5881.16, 5835.25,
5895.39, 5794.58, 5842.72, 5809.81, 5834.05, 5843.11,
5771.03, 5741.2 , 5763.68, 5738.31, 5756.64, 5686.59,
5686.05, 5711.26, 5680.77, 5678. , 5670.78, 5626.55,
5599.49, 5572.86, 5573.88, 5572.26, 5532.51, 5523.21,
5541.77, 5528.95, 5531.11, 5542.49, 5515.9 , 5509.62,
5485.16, 5488.85, 5495.59, 5465.52, 5434.44, 5507.97,
5459.17, 5421.25, 5419.23, 5416.85, 5396.44, 5410.29,
5430.09, 5385.02, 5361.95, 5391.7 , 5345.41, 5350.12,
5345.22, 5370.72, 5322.03, 5348.25, 5370.73, 5338.4 ,
5300.9 , 5325.29, 5323.3 , 5341.07, 5316.03, 5281.7 ,
5333.72, 5287.52, 5355.5 , 5313.96, 5315.16, 5314.75,
5293.81, 5313.89, 5317.65, 5289.2 , 5322.9 , 5275.23,
5273.53, 5278.15, 5291.24, 5260.07, 5290.77, 5272.02,
5284.21, 5317.56]
Using an orthogonal least square fit algorightm, I get: 使用正交最小二乘拟合算法,我得到:
-1.9386e-015 X^6 + 1.3095e-013 X^5 + 3.9775e-009 X^4 + -2.3274e-007 X^3 + -2.6963e-003 X^2 + 7.3943e-002 X + 5.9382e+003 -1.9386e-015 X ^ 6 + 1.3095e-013 X ^ 5 + 3.9775e-009 X ^ 4 + -2.3274e-007 X ^ 3 + -2.6963e-003 X ^ 2 + 7.3943e-002 X + 5.9382 e + 003
which matches the python output. 匹配python输出。 Link to .rtf document for the algorithm I use, including example c code: 链接到我使用的算法的.rtf文档,包括示例C代码:
http://rcgldr.net/misc/opls.rtf http://rcgldr.net/misc/opls.rtf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.