程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 研究生數值分析課後題(上機編程)-1

研究生數值分析課後題(上機編程)-1

編輯:關於C語言

       現將小生研一數值分析作業摘錄如下,上機的代老師要求我們分為四個部分:解題理論依據、計算程序、計算結果截圖和問題討論,因公式輸入不便所以第一部分的公式略去,需要的可去下載附件。因為本人編程水平有限,故使用的是最基本的函數,但保證原創和結果正確,所有程序在VC++6.0上驗證通過,還望各位兄台不吝賜教。   

  

            第一題二問):超松弛法求方程組根

1.解題理論依據或方法應用條件:

超松弛算法是在GS方法已求出x(m),x(m-1)的基礎上,經過重新組合得到新序列。如能恰當選擇松弛因子ω,收斂速度會比較快。當ω>1時,稱為超松弛法,可以用來加速收斂。    

2.計算程序使用軟件:VC):

#include<stdio.h>

#define w 1.4

main()

{float a[10][10]={ {0,0,0,0,0,0,0,0,0,0},

{0,12.38412,2.115237,-1.061074,1.112336,-0.113584,0.718719,1.742382,3.067813,-2.031743},

{0,2.115237,19.141823,-3.125432,-1.012345,2.189736,1.563849,-0.784165,1.112348,3.123124},

{0,-1.061074,-3.125432,15.567914,3.123848,2.031454,1.836742,-1.056781,0.336993,-1.010103},

{0,1.112336,-1.012345,3.123848,27.108437,4.101011,-3.741856,2.101023,-0.71828,-0.037585},

{0,-0.113584,2.189736,2.031454,4.101011,19.897918,0.431637,-3.111223,2.121314,1.784317},

0,0.718719,1.563849,1.836742,-3.741856,0.431637,9.789365,-0.103458,-1.103456,0.238417},

{0,1.742382,-0.784165,-1.056781,2.101023,-3.111223,-0.103458,14.7138465,3.123789,-2.213474},

{0,3.067813,1.112348,0.336993,-0.71828,2.121314,-1.103456,3.123789,30.719334,4.446782},

{0,-2.031743,3.123124,-1.010103,-0.037585,1.784317,0.238417,-2.213474,4.446782,40.00001}};

 float b[10][1]=

{{0},{2.1874369},{33.992318},{-25.173417},{0.84671695},{1.784317},{-86.612343},{1.1101230},{4.719345},{-5.6784392}};

 float x[10][10]={{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}};       /*x(0)=0得到其第一列全為零*/

 float sum1=0,sum2=0;

 int i,m,j;

 for(m=1;m<=9;m++)

          for(i=1;i<=9;i++)

          {sum1=0;

           for(j=1;j<=(i-1);j++)sum1+=(-a[i][j]/a[i][i])*x[j][m];             /*計算第一個累加和*/            

           sum2=0;

           for(j=(i+1);j<=9;j++)sum2+=(-a[i][j]/a[i][i])*x[j][m-1];           /*計算第二個累加和*/

      x[i][m]=(1-w)*x[i][m-1]+w*(sum1+sum2+b[i][0]/a[i][i]);        /*SOR方法計算*/

          }

 printf("x1為:%lf\n",x[1][9]);

 printf("x2為:%lf\n",x[2][9]);

 printf("x3為:%lf\n",x[3][9]);

 printf("x4為:%lf\n",x[4][9]);

 printf("x5為:%lf\n",x[5][9]);

 printf("x6為:%lf\n",x[6][9]);

 printf("x7為:%lf\n",x[7][9]);

 printf("x8為:%lf\n",x[8][9]);

 printf("x9為:%lf\n",x[9][9]);

}

3.計算結果

4.問題討論誤差分析、上機出現情況等)

這道題目是所有題目中編寫最順利的,一次即順利得出結果,當然這道題目還是有應該注意到地方,一是注意兩個求和的清零,二是注意下標,不要弄混行標和列標。

 

                第一題三問):列主元素法求方程組根

1.解題理論依據或方法應用條件:

    所謂列主元消去法是,對矩陣作恰當的調整,選取絕對值最大的元素作為主元素。然後把矩陣化為上三角陣,再進行回代,求出方程的解。

2.計算程序使用軟件:VC):

#include<stdio.h>

#include<math.h>

main()

{double a[10][11]={ {0,0,0,0,0,0,0,0,0,0,0},

{0,12.38412,2.115237,-1.061074,1.112336,-0.113584,0.718719,1.742382,3.067813,-2.031743,2.1874369},

{0,2.115237,19.141823,-3.125432,-1.012345,2.189736,1.563849,-0.784165,1.112348,3.123124,33.992318},

{0,-1.061074,-3.125432,15.567914,3.123848,2.031454,1.836742,-1.056781,0.336993,-1.010103,-25.173417},

{0,1.112336,-1.012345,3.123848,27.108437,4.101011,-3.741856,2.101023,-0.71828,-0.037585,0.84671695},

{0,-0.113584,2.189736,2.031454,4.101011,19.897918,0.431637,-3.111223,2.121314,1.784317,1.784317},

{0,0.718719,1.563849,1.836742,-3.741856,0.431637,9.789365,-0.103458,-1.103456,0.238417,-86.612343},

{0,1.742382,-0.784165,-1.056781,2.101023,-3.111223,-0.103458,14.7138465,3.123789,-2.213474,1.1101230},

{0,3.067813,1.112348,0.336993,-0.71828,2.121314,-1.103456,3.123789,30.719334,4.446782,4.719345},

{0,-2.031743,3.123124,-1.010103,-0.037585,1.784317,0.238417,-2.213474,4.446782,40.00001,-5.6784392}};

 double x[10],y[11];                                                                                      

 double sum=0,max;

 int i,j,j1,m,n,k,g,h;

 for(j=1;j<=8;j++)

         {max=a[j][j];

     for(k=j+1;k<=9;k++)

     {if(fabs(a[k][j])>fabs(max))max=a[k][j];}

     for(k=j;k<=9;k++)

     {if(a[k][j]/max==1)g=k;}                  /*確定本列絕對值最大元素所在行:g*/

          for(h=j;h<=10;h++)

                    y[h]=a[j][h];

     for(h=j;h<=10;h++)

                    a[j][h]=a[g][h];

          for(h=j;h<=10;h++)

                    a[g][h]=y[h];                       /*g行與J行所有元素進行交換*/

     for(i=j+1;i<=9;i++)

                    for(j1=j+1;j1<=10;j1++)

                             a[i][j1]-=(a[i][j]/a[j][j])*a[j][j1];}    /*逐行消元,將矩陣轉化為上三角矩陣*/

 printf("x9為:%lf\n",x[9]=a[9][10]/a[9][9]);

 for(m=8;m>=1;m--)

 {sum=0;

 for(n=m+1;n<=9;n++)                                   

 sum+=x[n]*a[m][n];                                      

 printf("x%d為:%lf\n",m,x[m]=(a[m][10]-sum)/a[m][m]);}      /*x9x1逐個解出結果*/

}

3.計算結果

4.問題討論誤差分析、上機出現情況等)

1)這道題目出現的最大問題在 for(j1=j+1;j1<=10;j1++)a[i][j1]-=(a[i][j]/a[j][j])*a[j][j1]; ,剛開始我錯寫為:for(j1=j;j1<=10;j1++)a[i][j1]-=(a[i][j]/a[j][j])*a[j][j1]; ,也就是j1應該從j+1開始取值,如果從j開始取,會導致a[i][j1]-=(a[i][j]/a[j][j])*a[j][j1]; 一句中a[i][j]是零,這樣後面的a[i][j1]全部都將是原來的數值,不會變化,導致錯誤。

2)對於列主元素消元法,個人感覺將a,b兩個矩陣,放在一個矩陣中進行編程,較方便。

 

 

                第三題:三次樣條插值求近似值

1.解題理論依據或方法應用條件:

依據三彎矩插值法列出相應的方程,然後將x的值帶入在求解三彎矩方程的參數時,應用追趕法求解方程組求出相應參數值)。

2.計算程序使用軟件:VC):

#include<stdio.h>

#include<math.h>

main()

{ int i;

 double s,z;                                       /*定義函數近似值,導數近似值*/

 double b[11]={0,2,2,2,2,2,2,2,2,2,2},p[11],g[11],l[11];     /*追趕法中變量b,β,δ,l*/

 double m[11]={0,0,0,0,0,0,0,0,0,0,0};

doublef[11]={0,0,0.69314718,1.0986123,1.3862944,1.6094378,1.7917595,1.9459101,2.079445,2.1972246,2.3025851};                              /*原插值點對應函數值*/

 double y[11]={0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1};     /*變量η*/

 double x[10]={0,1,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5};        /*變量λ*/

doubled[11]={0,6*(f[2]-1),3*(f[3]+f[1]-2*f[2]),3*(f[4]+f[2]-2*f[3]),3*(f[5]+f[3]-2*f[4]),3*(f[6]+f[4]-2*f[5]),3*(f[7]+f[5]-2*f[6]),3*(f[8]+f[6]-2*f[7]),3*(f[9]+f[7]-2*f[8]),3*(f[10]+f[8]-2*f[9]),6*(0.1-f[10]+f[9])};

 p[1]=2;g[1]=d[1];

 for(i=1;i<=9;i++)

 {l[i+1]=y[i]/p[i];

  p[i+1]=b[i+1]-l[i+1]*x[i];

  g[i+1]=d[i+1]-l[i+1]*g[i];}                            /*求出追趕法中相應參數*/

m[10]=g[10]/p[10];

 for(i=9;i>=1;i--)

  m[i]=(g[i]-x[i]*m[i+1])/p[i];                          /*應用追趕法求出最終方程解*/

s=m[4]*pow(5-4.563,3)/6+m[5]*pow(4.563-4,3)/6+(f[4]-m[4]/6)*(5-4.563)+(f[5]-m[5]/6)*(4.563-4);

z=-m[4]/2*pow(5-4.563,2)+m[5]/2*pow(4.563-4,2)-(f[4]-m[4]/6)+(f[5]-m[5]/6);

printf("函數f(4.563)近似值 %.16lf\n導數f'(4.563)近似值:%.16lf\n",s,z);       

                                                 /*求出函數值和導數值並輸出*/}           

3.計算結果

4.問題討論誤差分析、上機出現情況等)

1)在做數組相關的編程時,特別注意下標的使用,因為數組下標是從0開始的,以後可以統一將下標為0的數組位置置0,從下標為1的位置開始賦值使用。

2)編程的過程出現問題如下:①第二個for循環i--誤寫成i++,造成無限循環錯誤②在乘法的運算中漏掉了兩個小括號間的“×”號

 

本文出自 “馬凱的技術博客” 博客,請務必保留此出處http://makai.blog.51cto.com/2205493/496806

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved