合肥工业大学宣城校区计算方法 实验一

1实验目的和要求

实验目的:理解拉格朗日插值算法及牛顿插值算法的程序实现方法。
程序任务:
1)依据课本18页图1-3编程实现拉格朗日插值算法,并完成54页课后习题6.
注:分别以三个小题目中给出的条件画出插值函数,比较它们的不同。
2)编程实现牛顿插值算法,并完成如下题目:
用牛顿插值法来求sinx在区间多点的值,已知sin0°= 0, sin30°= 0.5, sin45°= 0.7071, sin60° = 0.8660, sin90°= 1. 以此为依据画出sinx在 区间的图像。

2实验环境和工具

用matlab或C语言实现

3实验结果

3.1算法流程图
拉格朗日算法
在这里插入图片描述
在这里插入图片描述
3.2程序核心代码
c语言:

#include<stdio.h>

void achievel(void);
void achieveNew(void);
int main()
{
    int m;
    printf("1.实现拉格朗日算法\n2.实现牛顿插值算法\n\n");
    scanf("%d",&m);

    switch(m)
    {
    case 1:
        achievel();
        break;
    case 2:
        achieveNew();
        break;
    }
    return 0;
}

void achievel(void)//实现拉格朗日插值算法
{
    double xi[20],yi[20];
    double x,y,t;
    int i=0,j,k;

    printf("输入x的值:\n");
    scanf("%lf",&x);
    getchar();

    printf("输入多个点的横纵坐标:\n");
    while(i<20)
    {
        scanf("%lf %lf",&xi[i],&yi[i]);//输入9999终止
        if(xi[i]==9999)
        {
            break;
        }
        i++;
    }

    y = 0;
    for(k=0;k<i;k++)
    {
        t = 1;
        for(j=0;j<i;j++)
        {
            if(j!=k)
            {
                t = t*(x-xi[j])/(xi[k]-xi[j]);
            }
        }
        y = y + t*yi[k];
    }
    printf("纵坐标为:%lf",y);
}

void achieveNew(void)//实现牛顿插值算法
{
    double x,y;
    double xi[20],yi[20],fx[20][20];
    int i,j,k,m;

    printf("输入x的值:\n");
    scanf("%lf",&x);

    printf("输入多个点的横纵坐标:\n");
    for(i=0;i<20;i++)
    {
        scanf("%lf %lf",&xi[i],&yi[i]);//输入9999
        fx[0][i] = yi[i];
        if(xi[i]==9999)
        {
            break;
        }
    }

    m = i;
    for(i=1;i<m;i++)//得到差商
    {
        for(j=i;j<m;j++)
        {
            fx[i][j] = (fx[i-1][j]-fx[i-1][j-i])/(xi[j]-xi[j-i]);
        }
    }

    y = fx[0][0];
    for(i=1;i<m;i++)
    {
        k = 1;
        for(j=i;j>0;j--)
        {
            k = fx[i][i]*(x-xi[j-1])*k;
        }
        y = y+k;
    }
    printf("纵坐标为:%lf",y);
}

Python(画图):

import matplotlib.pyplot as plt
import numpy as np
import math

def achievel(s):
    x = np.linspace(-5, 5, 50)
    x0 = -1
    x1 = 1
    y0 = -1
    y1 = 1
    if(s==1):
        y = (x-x1)/(x0-x1)*y0
        y = y + (x-x0)/(x1-x0)*y1
    else:
        x2 = 0
        y2 = 0
        if(s==2):
            y = (x-x1)*(x-x2)/(x0-x1)/(x0-x2)*y0
            y = y + (x-x0)*(x-x2)/(x1-x0)/(x1-x2)*y1
            y = y + (x-x0)*(x-x1)/(x2-x0)/(x2-x1)*y2
        elif(s==3):
            x3 = 2
            y3 = 8
            y = (x-x1)*(x-x2)*(x-x3)/(x0-x1)/(x0-x2)/(x0-x3)*y0
            y = y + (x-x0)*(x-x2)*(x-x3)/(x1-x0)/(x1-x2)/(x1-x3)*y1
            y = y + (x-x0)*(x-x1)*(x-x3)/(x2-x0)/(x2-x1)/(x2-x3)*y2
            y = y + (x-x0)*(x-x1)*(x-x2)/(x3-x0)/(x3-x1)/(x3-x2)*y3
    plt.figure()
    plt.plot(x, y)
    plt.show()

def achieven():
    x1 = 0
    x2 = math.pi/6
    x3 = math.pi/4
    x4 = math.pi/3
    x5 = math.pi/2
    y1 = 0
    y2 = 0.5
    y3 = 0.7071
    y4 = 0.8660
    y5 = 1
    
    y12 = (y2-y1)/(x2-x1)
    y23 = (y3-y2)/(x3-x2)
    y34 = (y4-y3)/(x4-x3)
    y45 = (y5-y4)/(x5-x4)

    y13 = (y23-y12)/(x3-x1)
    y24 = (y34-y23)/(x4-x2)
    y35 = (y45-y34)/(x5-x3)

    y14 = (y24-y13)/(x4-x1)
    y25 = (y35-y24)/(x5-x2)

    y15 = (y25-y14)/(x5-x1)

    x = np.linspace(0, math.pi/2, 50)
    y = y1+y12*(x-x1)+y13*(x-x1)*(x-x2)+y14*(x-x1)*(x-x2)*(x-x3)
    y = y+y15*(x-x1)*(x-x2)*(x-x3)*(x-x4)

    plt.figure()
    plt.plot(x, y)
    plt.show()

3.3运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.4运行结果分析
根据运行结果可得:拉格朗日算法的拟合效果较好,牛顿插值算法的拟合效果也很好。牛顿插值算法更适合较为复杂的函数进行拟合,而拉格朗日算法适合相较简单一点的函数。两者都是适合预估的函数值的算法。

4实验心得

在本次实验中,拉格朗日算法已经给出算法流程图,实现起来并不困难。牛顿插值算法虽然没有给出算法流程图,但这也帮助我们回顾了这个算法。
在这次实验中,我最大的收获,就是了解了c语言的局限性。画图可以使用c++、matlab、java、python,但无法使用c语言画图,或者说,用c语言画出函数图像的难度大大提高,用其他语言画函数的图像,难度较低。也证明了c语言有它的优越性,也有其局限性,c语言在图形处理方面不如别的语言。
这更让我明白,一个合格的程序员不能只掌握一种语言,一种语言对于一个合格的程序员是远远不够的,我们在掌握多门语言的基础上,也需要尽全力学通每一门语言,只有做到这两点,我们才能在未来大显身手。
这一次的实验,也是对我们的促进,告诉我们需要不断努力。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值