• 数值分析 三次样条插值及实现


     分析:

    第一问,给出的是第一类边界条件

    第二问,给出的是第二类边界条件

    我们按照想要的步骤,分别求第一类与第二类边界条件下的三次样条插值函数即可

    为了不重复计算,且易于扩展,我们用C++编程,循环实现即可。

     (这肯定不能手算的,手算必手酸)

      1 #include <cstdio>
      2 #include <iostream>
      3 
      4 using namespace std;
      5 
      6 const int N = 5;
      7 
      8 int main()
      9 {
     10     // 录入数据
     11     double x[N]={0.25,0.30,0.39,0.45,0.53};
     12     double y[N]={0.5,0.5477,0.6245,0.6708,0.7280};
     13     // 输出数据
     14     printf("X(i),i=0...%d
    ",N-1);
     15     for(int i=0;i<N;++i)
     16     {
     17         printf("%f ",x[i]);
     18     }
     19     printf("
    
    Y(i),i=0...%d
    ",N-1);
     20     for(int i=0;i<N;++i)
     21     {
     22         printf("%f ",y[i]);
     23     }
     24     printf("
    
    ");
     25 
     26     // 计算h[i]
     27     double h[N];
     28     for(int i=0;i<N-1;++i)
     29     {
     30         h[i]=x[i+1]-x[i];
     31     }
     32     // 输出数据
     33     printf("h(i),i=0...%d
    ",N-2);
     34     for(int i=0;i<N-1;++i)
     35     {
     36         printf("%f ",h[i]);
     37     }
     38     putchar('
    ');
     39     putchar('
    ');
     40 
     41     // 计算u[i],r[i]
     42     double u[N],r[N];
     43     for(int i=1;i<N;++i)
     44     {
     45         u[i]=h[i-1]/(h[i-1] + h[i]);
     46         r[i]=h[i]/(h[i-1] + h[i]);
     47     }
     48     // 输出数据
     49     printf("u(i),i=1...%d
    ",N-1);
     50     for(int i=1;i<N;++i)
     51     {
     52         printf("%f ",u[i]);
     53     }
     54     putchar('
    ');
     55     putchar('
    ');
     56     printf("r(i),i=1...%d
    ",N-1);
     57     for(int i=1;i<N;++i)
     58     {
     59         printf("%f ",r[i]);
     60     }
     61     putchar('
    ');
     62     putchar('
    ');
     63 
     64     // 计算f[x(i-1),x(i)]
     65     // 用f[i]表示f[x(i-1),x(i)]
     66     double f[N+1];
     67     for(int i=1;i<N;++i)
     68     {
     69         f[i]=(y[i] - y[i-1])/(x[i] - x[i-1]);
     70     }
     71     // 输出数据
     72     printf("f[x(i),x(i-1)],i=1...%d
    ",N-1);
     73     for(int i=1;i<N;++i)
     74     {
     75         printf("%f ",f[i]);
     76     }
     77     putchar('
    ');
     78     putchar('
    ');
     79 
     80     // 记录两个导数
     81     f[0]=1;
     82     f[N]=0.6868;
     83 
     84     // 计算d(i)
     85     double d[N+1];
     86     d[0]=6*(f[1]-f[0])/h[0];
     87     for(int i=1;i<N-1;++i)
     88     {
     89         d[i]=6*(f[i+1]-f[i])/(h[i-1] + h[i]);
     90     }
     91     d[N]=6*(f[N]-f[N-1])/h[N-2];
     92 
     93     printf("d[i],i=0...%d
    ",N);
     94     for(int i=0;i<=N;++i)
     95     {
     96         printf("%f ",d[i]);
     97     }
     98 
     99     // AX=B
    100     // X=[A^(-1)]*B
    101     return 0;
    102 }

    求出上述数据后,代入矩阵求解即可得到所有的M( i ) 的值,对应矩阵的求逆与矩阵乘法的操作,用python或matlab都可以实现,这里不再重复实现,只需将上述计算所得的数据,写入相应的文件,然后在python中读取调用numpy库函数或用matlab实现都可。

    所有数据都已经求出后,带入,三次样条函数即为所求

    第二问给出了第二类边界条件

    M0与Mn即为给出的第二类边界条件的值,这里都是0,计算更加的简单,等式右边的直接与之前一问所求的d相同,无需重复计算

    同样带入如下矩阵,

    利用矩阵的逆运算,即可求出剩余的M1,...,n-1.

    同样,所有数据已知,带入,三次样条函数即为所求。

  • 相关阅读:
    按次计费简单实现思路
    java读取和写入excel
    SpringBoot定时任务自动停止关闭
    class path resource [applicationContext.xml] cannot be opened because it does not exist
    Tomcat安装配置idea
    Git rebase
    MongoDB高可用集群配置方案
    keepalived主从及双主配置
    openssl 生成免费证书
    Nginx proxy_cache 缓存静态文件
  • 原文地址:https://www.cnblogs.com/jishuren/p/12392668.html
Copyright © 2020-2023  润新知