当前位置:   article > 正文

「数学」- 手撸 Newton插值法 C++

「数学」- 手撸 Newton插值法 C++

具体思路现在,没空补,看代码之前,建议推一下newton插值公式。

 

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <stdlib.h>
  5. #include <ctime>
  6. /// Newton 插值法的实现方法
  7. #define NAN 0x3f3f3f3f
  8. class Newdon{
  9. // (x-x0)(x-x1).....(x-xn) *a
  10. private:
  11. double fac[1000]={0}; // o ~ n 的u多项式系数, 系数从0到n
  12. double fac_ploy[1000]={0}; // 新增一项的(x-x0)(x-x1).....(x-xn)的各个多项式的系数,用于构造新的多项式系数
  13. int fac_len = 0; //有效系数的长度 从0开始
  14. double get_fac_ploy(double);// (x-x0)(x-x1).....(x-xn)的值
  15. public:
  16. Newdon(double *,double *,int);
  17. void add_node(double,double);
  18. double get_value(double x);
  19. void test_print();
  20. };
  21. void Newdon::test_print()
  22. {
  23. for(int i=0;i<fac_len;i++)
  24. printf(" %lf ",fac[i]);
  25. printf("\n");
  26. for(int i=0;i<fac_len;i++)
  27. printf(" %lf ",fac_ploy[i]);
  28. printf("\n");
  29. }
  30. Newdon::Newdon(double *x_value,double *y_value, int len)
  31. {
  32. if(len<1) printf("len is too small to creat Newton\n");
  33. // 系数构造方式 比较巧妙
  34. //动态构造 新建新newton项式的系数, 当然newton项式之间的系数有递推关系
  35. for(int i=0;i<len;i++)
  36. {
  37. //test_print();
  38. add_node(x_value[i],y_value[i]);
  39. }
  40. }
  41. // 已有一个节点的基础上 添加一个新节点
  42. void Newdon::add_node(double x,double y)
  43. {
  44. //第一个节点
  45. if(fac_len == 0)
  46. {
  47. fac[0] = y;
  48. fac_ploy[0] = -x; fac_ploy[1] = 1;//下一个多项式的(x-x0
  49. fac_len ++;
  50. return;
  51. }
  52. // 之后的节点
  53. double tmp1 = get_value(x);
  54. fac_len++;// 有效的fac_ploy 比当前fac多一个
  55. double tmp2 = get_fac_ploy(x);
  56. double ploy_a = (y - tmp1) / tmp2; // 求出系数a,之后将系数相乘相加即可
  57. for(int i=0;i<fac_len;i++)
  58. {
  59. fac[i] += fac_ploy[i] * ploy_a;
  60. }
  61. //随之,增加有效的ploy系数
  62. for(int i=fac_len-1;i>=0;i--)
  63. {
  64. fac_ploy[i+1] += fac_ploy[i];
  65. fac_ploy[i] = fac_ploy[i] * (-x);
  66. }
  67. }
  68. double Newdon::get_fac_ploy(double x)
  69. {
  70. if(fac_len <= 0){
  71. printf("fac_len is <= 0\n");
  72. return 0;
  73. }
  74. double res = fac_ploy[fac_len-1];
  75. for(int i=fac_len-2;i>=0;i--)
  76. res = res * x + fac_ploy[i];
  77. return res;
  78. }
  79. double Newdon::get_value(double x)
  80. {
  81. if(fac_len <= 0){
  82. printf("fac_len is <= 0\n");
  83. return 0;
  84. }
  85. double res = fac[fac_len-1];
  86. for(int i=fac_len-2;i>=0;i--)
  87. res = res * x + fac[i];
  88. return res;
  89. }
  90. int main(){
  91. srand(time(0));
  92. double y[10] = {10,20,49,50,40,0,-40,-30,-10,20};
  93. double x[10] = {1,2,3,4,5,6,7,8,9,10};
  94. int len = 10;
  95. /* for(int i=0;i<len;i++)
  96. {
  97. x[i] = rand()%10000;
  98. y[i] = rand()%20000;
  99. }
  100. */
  101. Newdon first = Newdon(x,y,len);
  102. first.test_print();
  103. int a = 11, b =15;
  104. for(int i=a;i<b;i++)
  105. printf("c(%d) = %.2lf\n",i,first.get_value(i));
  106. }

可用MATLAB的Newton的插值法源代码进行验证!

代码转自

  1. %newton.m
  2. %求牛顿插值多项式、差商、插值及其误差估计的MATLAB主程序
  3. %输入的量:X是n+1个节点(x_i,y_i)(i = 1,2, ... , n+1)横坐标向量,Y是纵坐标向量,
  4. %x是以向量形式输入的m个插值点,M在[a,b]上满足|f~(n+1)(x)|≤M
  5. %注:f~(n+1)(x)表示f(x)的n+1阶导数
  6. %输出的量:向量y是向量x处的插值,误差限R,n次牛顿插值多项式L及其系数向量C,
  7. %差商的矩阵A
  8. function[y,R,A,C,L] = newton(X,Y,x,M)
  9. n = length(X);
  10. m = length(x);
  11. for t = 1 : m
  12. z = x(t);
  13. A = zeros(n,n);
  14. A(:,1) = Y';
  15. s = 0.0; p = 1.0; q1 = 1.0; c1 = 1.0;
  16. for j = 2 : n
  17. for i = j : n
  18. A(i,j) = (A(i,j-1) - A(i-1,j-1))/(X(i)-X(i-j+1));
  19. end
  20. q1 = abs(q1*(z-X(j-1)));
  21. c1 = c1 * j;
  22. end
  23. C = A(n, n); q1 = abs(q1*(z-X(n)));
  24. for k = (n-1):-1:1
  25. C = conv(C, poly(X(k)));
  26. d = length(C);
  27. C(d) = C(d) + A(k,k);%在最后一维,也就是常数项加上新的差商
  28. end
  29. y(t) = polyval(C,z);
  30. R(t) = M * q1 / c1;
  31. end
  32. L = poly2sym(C);

运行

  1. M = 10000000000000
  2. X = [1 2 3 4 5 6 7 8 9 10 ]
  3. Y = [ 10 20 49 50 40 0 -40 -30 -10 20 ]
  4. x = [11,12,13,14]
  5. newton(X,Y,x,M)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/380873
推荐阅读
相关标签
  

闽ICP备14008679号