C#--插值问题之拉格朗日插值法(C#窗体应用程序实现的)

概念

一般地,若已知
在互不相同 n+1 个点
处的函数值
( 即该函数过
这n+1个点),则可以考虑构造一个过这n+1 个点的、次数不超过n的多项式
,使其满足:
要估计任一点ξ,ξ≠x i,i=0,1,2,...,n,则可以用P n(ξ)的值作为准确值f(ξ)的近似值,此方法叫做“插值法”。
称式(*)为插值条件(准则),含x i(i=0,1,...,n)的最小区间[a,b],其中a=min{x 0,x 1,...,x n},b=max{x 0,x 1,...,x n}。

定理

满足插值条件的、次数不超过n的多项式是存在而且是唯一的。

一般形式运用方法
在平面上有
共n个点,现作一条函数
使其图像经过这n个点。
作法:设集合
是关于点
的角标的 集合
,作n个多项式
。对于任意
,都有
使得
是n-1次 多项式,且满足
并且
最后可得
形如上式的插值多项式
称为拉格朗日(Lagrange)插值多项式。
例如:当n=4时,上面的公式可简化为:
这是一个过4个点的唯一的三次多项式。
在form窗体加一个 button控件;加一个MouseDown事件;
需要加的指令:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

窗体部分,From1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 拉格朗日插值
{
    public partial class Form1 : Form
    {
        Lagrange objLag = new Lagrange();
        Newton objNto = new Newton();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            objLag.xs.Add(e.X);
            objLag.ys.Add(e.Y);
            objNto.xs.Add(e.X);
            objNto.ys.Add(e.Y);
            Graphics g = this.CreateGraphics();
            objLag.DrawPoints(g);
            objNto.DrawPoints(g);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Graphics g = this.CreateGraphics();
            objLag.DrawLnxLines(g);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Application.Restart ();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Graphics g = this.CreateGraphics();
            objNto.DrawNnxLines(g);
        }
    }
}

窗体界面设计:

添加拉格朗日类部分,Lagrange.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;

namespace 拉格朗日插值
{
    class Lagrange
    {
        public List<float> xs = new List<float>();
        public List<float> ys = new List<float>();
        public float Lkx(float x,int k)
        {
            float sum = 1;
            for (int i=0;i<xs .Count;i++)
            {
                if (i != k) sum *= (x - xs[i]) / (xs[k] - xs[i]);
            }
            return sum;
        }
        public float Lnx(float x)
        {
            float sum = 0;
            for(int k=0;k<xs .Count;k++)
            {
                sum += Lkx(x, k) * ys[k];
            }
            return sum;
        }
        public void DrawPoints(Graphics g)
        {
            for (int i = 0; i < xs.Count; i++)
                g.DrawEllipse(new Pen(Color.Red),
                    xs[i] - 3, ys[i] - 3, 6, 6);
        }
        public void DrawLnxLines(Graphics g)
        {
            for (float x = xs[0]; x < xs[xs.Count - 1]; x = x + 1)
            {
                float y = Lnx(x);
                g.DrawEllipse(new Pen(Color.Black),
                    x - 1, y - 1, 2, 2);
            }
        }
    }
}

运行结果:
有错误之处,希望大家指出,谢谢!!

猜你喜欢

转载自blog.csdn.net/qq_40953393/article/details/80212332