數值分析 三次樣條插值及實現


 分析:

第一問,給出的是第一類邊界條件

第二問,給出的是第二類邊界條件

我們按照想要的步驟,分別求第一類與第二類邊界條件下的三次樣條插值函數即可

為了不重復計算,且易於擴展,我們用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",N-1);
 15     for(int i=0;i<N;++i)
 16     {
 17         printf("%f ",x[i]);
 18     }
 19     printf("\n\nY(i),i=0...%d\n",N-1);
 20     for(int i=0;i<N;++i)
 21     {
 22         printf("%f ",y[i]);
 23     }
 24     printf("\n\n");
 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",N-2);
 34     for(int i=0;i<N-1;++i)
 35     {
 36         printf("%f ",h[i]);
 37     }
 38     putchar('\n');
 39     putchar('\n');
 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",N-1);
 50     for(int i=1;i<N;++i)
 51     {
 52         printf("%f ",u[i]);
 53     }
 54     putchar('\n');
 55     putchar('\n');
 56     printf("r(i),i=1...%d\n",N-1);
 57     for(int i=1;i<N;++i)
 58     {
 59         printf("%f ",r[i]);
 60     }
 61     putchar('\n');
 62     putchar('\n');
 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",N-1);
 73     for(int i=1;i<N;++i)
 74     {
 75         printf("%f ",f[i]);
 76     }
 77     putchar('\n');
 78     putchar('\n');
 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",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.

同樣,所有數據已知,帶入,三次樣條函數即為所求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM