您的位置:首页 > 编程语言 > C#

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_
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# 数学
相关文章推荐