资讯动态

数值分析——牛顿前插公式和牛顿后插公式

发布时间:2026/10/3 16:47:00 来源:尧图企业网站定制
提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录文章目录前言一、核心算法原理二、 C 完整代码三、运行结果总结前言基于C编写了一套完整的代码。这套代码不仅实现了牛顿前插公式和牛顿后插公式还特别针对特殊要求实现了差分表的格式化打印与教材表格一致。GeoGebra友好的插值公式打印输出以 xx 为自变量的多项式代数式可直接复制粘贴到GeoGebra。例5的完整计算与误差估计采用书中给定的数据和4次牛顿前插公式。例题资料如下图提示以下是本篇文章正文内容下面案例可供参考一、核心算法原理1.前插公式以 x0​ 为基准tx−x0/h2.后插公式以 xn​ 为基准t(x−xn)/h)二、 C 完整代码#include iostream #include vector #include iomanip #include cmath #include string #include sstream using namespace std; // 计算阶乘 double factorial(int n) { double res 1.0; for (int i 2; i n; i) res * i; return res; } //牛顿插值 class NewtonInterpolator { private: vectordouble x_data;//x值 vectordouble y_data;//y值 vectorvectordouble diff_table; // 差分表 int n; double h; // 步长 public: NewtonInterpolator(const vectordouble x, const vectordouble y) : x_data(x), y_data(y), n(x.size()) { // 自动计算步长 (假设等距) h x_data[1] - x_data[0]; buildDifferenceTable();//构建差分表 } // 1. 构建差分表 void buildDifferenceTable() { diff_table.assign(n, vectordouble(n, 0.0)); // 0阶差分即函数值本身 for (int i 0; i n; i) { diff_table[i][0] y_data[i];//i行0列是函数值 } // 递推计算高阶差分 for (int j 1; j n; j) { //j1:一阶差分 for (int i 0; i n - j; i) { diff_table[i][j] diff_table[i 1][j - 1] - diff_table[i][j - 1];//求j阶差分 } } } // 2. 打印差分表 void printDifferenceTable() const { cout 差分表 endl; cout setw(8) xk setw(12) f(xk) setw(12) Δf setw(12) Δ^2f setw(12) Δ^3f setw(12) Δ^4f setw(12) Δ^5f endl; for (int i 0; i n; i) { cout setw(8) fixed setprecision(2) x_data[i]; for (int j 0; j n - i; j) { cout setw(12) fixed setprecision(5) diff_table[i][j]; } cout endl; } cout endl endl; } // 3. 打印适用于 GeoGebra 的前插公式 void printForwardFormula() const { cout 【牛顿前插公式】(可直接复制到 GeoGebra 绘图): endl; cout f(x) ; for (int i 0; i n; i) { double coef diff_table[0][i] / (factorial(i) * pow(h, i)); if (i 0) { if (coef 0) cout ; else { cout - ; coef -coef; } } else { if (coef 0) { cout -; coef -coef; } } cout fixed setprecision(5) coef; for (int j 0; j i; j) { cout (x - fixed setprecision(2) x_data[j] ); } } cout endl endl; } // 4. 打印适用于 GeoGebra 的后插公式 void printBackwardFormula() const { cout 【牛顿后插公式】(可直接复制到 GeoGebra 绘图): endl; cout g(x) ; for (int i 0; i n; i) { // 后插公式的差分取自差分表底部的对角线 double coef diff_table[n - 1 - i][i] / (factorial(i) * pow(h, i)); if (i 0) { if (coef 0) cout ; else { cout - ; coef -coef; } } else { if (coef 0) { cout -; coef -coef; } } cout fixed setprecision(5) coef; for (int j 0; j i; j) { cout (x - fixed setprecision(2) x_data[n - 1 - j] ); } } cout endl endl; } // 5. 牛顿前插公式求值 double solveForward(double target_x) const { double t (target_x - x_data[0]) / h; double result diff_table[0][0]; double term 1.0; for (int i 1; i n; i) { term * (t - (i - 1));//二项式展开系数的分子分母是阶乘 result (diff_table[0][i] / factorial(i)) * term; } return result; } // 6. 牛顿后插公式求值 double solveBackward(double target_x) const { double t (target_x - x_data[n - 1]) / h; double result diff_table[n - 1][0]; double term 1.0; for (int i 1; i n; i) { term * (t (i - 1)); result (diff_table[n - 1 - i][i] / factorial(i)) * term; } return result; } }; int main() { // 输入例5的数据f(x) cos(x), x_k k*h, h0.1, k0..5 vectordouble x { 0.00, 0.10, 0.20, 0.30, 0.40, 0.50 }; vectordouble y { 1.00000, 0.99500, 0.98007, 0.95534, 0.92106, 0.87758 }; double target_x 0.048; cout 牛顿插值法计算例5 endl; cout 已知节点 x_k k*0.1, 求 f(0.048) endl endl; NewtonInterpolator newton(x, y); // 打印差分表 newton.printDifferenceTable(); // 打印可用于 GeoGebra 的公式 newton.printForwardFormula(); newton.printBackwardFormula(); // 计算并输出结果 double result_fwd newton.solveForward(target_x); double result_bwd newton.solveBackward(target_x); cout 【计算结果】 endl; cout 牛顿前插公式计算 f(0.048) ≈ fixed setprecision(6) result_fwd endl; cout 牛顿后插公式计算 f(0.048) ≈ fixed setprecision(6) result_bwd endl; cout 真实值 cos(0.048) ≈ fixed setprecision(6) cos(target_x) endl; // 误差估计使用书中公式 3.14 double t (target_x - x[0]) / 0.1; double M5 sin(0.5); // M5 max|f^(5)(x)| max|sin(x)| 在 [0, 0.5] 上 double error_bound (M5 / factorial(5)) * abs(t * (t - 1) * (t - 2) * (t - 3) * (t - 4)) * pow(0.1, 5);//求余项 cout \n【误差估计】(使用 4 次前插公式) endl; cout 余项 |R_4(0.048)| scientific setprecision(4) error_bound endl; return 0; }三、运行结果 牛顿插值法计算例5 已知节点 x_k k*0.1, 求 f(0.048) 差分表 xk f(xk) Δf Δ^2f Δ^3f Δ^4f Δ^5f0.00 1.00000 -0.00500 -0.00993 0.00013 0.00012 -0.000020.10 0.99500 -0.01493 -0.00980 0.00025 0.000100.20 0.98007 -0.02473 -0.00955 0.000350.30 0.95534 -0.03428 -0.009200.40 0.92106 -0.043480.50 0.87758【牛顿前插公式】(可直接复制到 GeoGebra 绘图):f(x) 1.00000 - 0.05000(x - 0.00) - 0.49650(x - 0.00)(x - 0.10) 0.02167(x - 0.00)(x - 0.10)(x - 0.20) 0.05000(x - 0.00)(x - 0.10)(x - 0.20)(x - 0.30) - 0.01667(x - 0.00)(x - 0.10)(x - 0.20)(x - 0.30)(x - 0.40)【牛顿后插公式】(可直接复制到 GeoGebra 绘图):g(x) 0.87758 - 0.43480(x - 0.50) - 0.46000(x - 0.50)(x - 0.40) 0.05833(x - 0.50)(x - 0.40)(x - 0.30) 0.04167(x - 0.50)(x - 0.40)(x - 0.30)(x - 0.20) - 0.01667(x - 0.50)(x - 0.40)(x - 0.30)(x - 0.20)(x - 0.10)【计算结果】牛顿前插公式计算 f(0.048) ≈ 0.998842牛顿后插公式计算 f(0.048) ≈ 0.998842真实值 cos(0.048) ≈ 0.998848【误差估计】(使用 4 次前插公式)余项 |R_4(0.048)| 1.3445e-07总结1.前插与后插的等价性前插公式和后插公式打印出来的多项式看起来完全不一样因为基准点不同展开的多项式系数不同但它们在数学上是完全等价的。在 x0.048 处计算的结果均为0.998843这也印证了牛顿插值多项式的唯一性。2.误差估计代码严格遵守了教材中式 (3.14) 的余项公式其中。程序算出的误差上限为 1.3445e-07与教材十分接近。3.图形计算器 - GeoGebra可以把公式复制进去查看曲线。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑