C#实现拉格朗日、牛顿、Hermite插值
2016-12-04 23:43
561 查看
拉格朗日、牛顿插值法
初始时需要至少两个参考坐标点,在参考点的基础之上构造插值函数y=f(x),然后由插值函数确定需要求解的x坐标的函数值。相较于拉格朗日插值,牛顿插值公式更加复杂,但是在增加一个参考点时,不需要像拉格朗日插值那样从头再来。具体数学公式及背景介绍见参考1与参考2。Hermite插值法
初始时不仅需要至少两个参考点坐标,还需要在参考点上的一阶导数值。除此之外,Hermite插值可以保证插值函数在参考点上一阶可导,且导数值与初始值一致。using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace CsharpPro1.scienceCalculate { class interpolation { private List<double> xx = new List<double>(); //存储自变量 private List<double> known = new List<double>(); private List<double> knownDerivatives = new List<double>(); //用来存储Hermite插值时的已知量的导函数值 private List<double> tempW = new List<double>(); //用来存储牛顿插值时的中间变量 private List<double> tempF = new List<double>(); //用来存储牛顿插值法需要的中间变量 private List<double> tempL = new List<double>(); //用来存储Hermite插值时的中间变量 private List<double> tempLL = new List<double>(); //用来存储Hermite插值法需要的中间变量 private int knownCount; //已知数数量 private double pn; //最终结果 public static double angle2arc(double rangle) { return rangle * Math.PI / 180; } public double fx(double rangle) { rangle = angle2arc(rangle); return Math.Cos(rangle); } public interpolation(int knownCount, int sign) //牛顿对象与拉格朗日对象构造函数 { this.knownCount = knownCount; this.pn = 0; for (int i = 0; i < knownCount; i++) { Console.WriteLine("请输入第{0}个已知点,以Enter结束一行的输入", i); known.Add(double.Parse(Console.ReadLine())); } } public interpolation(int knownCount) { this.knownCount = knownCount; this.pn = 0; for (int i = 0; i < knownCount; i++) { Console.WriteLine("请输入第{0}个已知点,以Enter结束一行的输入", i); xx.Add(double.Parse(Console.ReadLine())); Console.WriteLine("请输入第{0}个已知点的函数值,以Enter结束一行的输入", i); known.Add(double.Parse(Console.ReadLine())); Console.WriteLine("请输入第{0}个已知点的函数值,如不需要,则输入零即可,以Enter结束一行的输入", i); knownDerivatives.Add(double.Parse(Console.ReadLine())); } } public void lagrange(double x)//插值方法,拉格朗日插值 { double tempNum=1; for(int i = 0; i < knownCount; i++) { tempNum = fx(known[i]); for(int j = 0; j < knownCount; j++) { if (j != i) { tempNum *= (x - known[j]) / (known[i] - known[j]); } } pn += tempNum; } } public void setTempW(double x) //tempW的set方法,最好由对象调用 { tempW.Add(1); for(int i = 1; i < this.knownCount; i++) { tempW.Add(tempW[i - 1] * (x - known[i - 1])); } } public double setTempF(int headNum,int endNum,double x) { double tempresult; if (headNum == endNum) { tempresult = fx(known[headNum]); } else { tempresult= (setTempF(headNum, endNum-1, x) - setTempF(headNum+1, endNum, x)) / (known[headNum] - known[endNum]); } if (headNum == 0) tempF.Insert(endNum,tempresult); return tempresult; } public void newton(double x) //牛顿插值法 { setTempW(x); setTempF(0, knownCount - 1, x); for (int i = 0; i < knownCount; i++) { this.pn += tempW[i] * tempF[i]; } } public void getlxAndLx(double x) //hermite基函数与导基函数 { double temp = 1, temp1 = 0; for(int i = 0; i < knownCount; i++) { for(int j = 0; j < knownCount; j++) { if (i != j) { temp *= (x - xx[j]) / (xx[i] - xx[j]); temp1 += 1 / (xx[i] - xx[j]); } } tempL.Add(temp); tempLL.Add(temp1); temp = 1; temp1 = 0; } } public void hermite(double x) //Hermite插值方法的实现,不适用于正余弦函数的插值 { getlxAndLx(x); for (int i = 0; i < knownCount; i++) { pn += known[i] * (1 - 2 * (x - xx[i]) * tempLL[i]) * Math.Pow(tempL[i], 2) + knownDerivatives[i] * (x - xx[i]) * tempL[i]*tempL[i]; } } //static void Main(string[] agrs) //{ // Console.WriteLine("请输入已知参数个数"); // int knownCount = int.Parse(Console.ReadLine()); // interpolation hermiteDemo = new interpolation(knownCount); // Console.WriteLine("请输入需要计算的自变量值"); // double rangle = double.Parse(Console.ReadLine()); // //rangle = angle2arc(rangle); // hermiteDemo.hermite(rangle); // Console.WriteLine("{0}的Cos值为{1}", rangle, hermiteDemo.pn); //} } }
<参考1>http://baike.baidu.com/link?url=xEG2Gx2YJw5rC5yRiwi8Ngpt2kbabpz6ouRIRtmx4BX0KpI-3cZb0L4vFU3XgHzAEYjaAY1Kw3uBRP7RivuOLqu32-SkhFvw-t3h7sUOJuVXVhChCs1mMrZUazbk8gNMBhMRIBceS5jegTJfyAJmFKbdgFD3PshNWx-QkMykJ8_
<参考2>http://baike.baidu.com/link?url=UcEI_khjobQ5C1e_roIFE2krJ9p50KPgceHCiZA_0VG8aGtdgFPj2IC_B1dTfQPI-WgBqOVTC2eHibu_FMRs9YBzorzAkuz3x0IeFfTBFv5A0mf4w4sRewFA9MvZ_-TpLDuA10xVSHJpAWK1tieMo_
相关文章推荐
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯等等
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔 (转帖)
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
- 数据结构与算法(C#实现)系列---N叉树(一)
- 由SAT问题展开说(2)[演化计算c#实现上]
- 数据结构与算法(C#实现)系列---广义树(一)
- 数据结构与算法(C#实现)系列-----前言