梦想赌坊的当家(EmilMatthew的侠意人生)

博客已转移至http://www.douban.com/people/emilmatthew/

原创 [数值算法]线性方程组的求解---迭代法小结收藏

[数值算法]线性方程组的求解---迭代法小结.

                                                       

                                             by EmilMatthew 05/9/08

当迭代法做多了之后,便感受到这种思想的好用了,今天再次实现用迭代法求解问题,感觉轻松了不少。

       当某个关于x的迭代式xk=fi(xk_1)保持收敛时,则可利迭代来求出最后的结果,直到满足精度要求为止.

       对于线性方程组的求解中迭代法的应用亦是如此,当矩阵的规模大于100*100时,迭代法的优势就突现出来了.

       1) Jacobi

对于线性方程组,可以很方便的对第i行中的元素xi用该行中的其余x来表示,

:

Xi_k+1=1/aii*(bi-sum(aij*Xj_k&&j1=i))

在数学上可以证明它满足迭代条件,所以,这便有了第一个求线性方程组的迭代算法:

Jacobi算法

/*

JacobiMethod, coded by EmilMathew 05/9/8, you can modify and use these code as you wish , but there is no guarantee that it can fit all you need.

*/

/*main aid function,to determine the end of the iterator*/

int preciseReached(Type* xList1,Type* xList2,int len,Type precise)

{

       int i=0;

       int flag;

       assertF(xList1!=NULL,"in preciseReached,xList1 is NULL\n");

       assertF(xList2!=NULL,"in preciseReached,xList2 is NULL\n");

      

       flag=1;

       for(i=0;i<len;i++)

              if(fabs(xList1[i]-xList2[i])>precise)

              {

                     flag=0;

                     break;

              }

       return flag;

}

 

 

void JacobiMethod(Type** inMatrixArr,Type* bList,Type* xAnsList,Type precise,int size,

FILE* outputFile)

{

      

       int iteratorNum;

       int i=0,j=0;

       Type sum=0;

       Type* tmpXList;

      

       /*pointer data assertion*/

       assertF(inMatrixArr!=NULL,"in JacobiMethod,matrixArr is NULL\n");

       assertF(bList!=NULL,"in JacobiMethod,bList is NULL\n");

       assertF(xAnsList!=NULL,"in JacobiMethod,xAnsList is NULL\n");

      

       tmpXList=(Type*)malloc(sizeof(Type)*size);

       assertF(tmpXList!=NULL,"in JacobiMethod,tmpXList is NULL\n");

      

       /*init data*/

       iteratorNum=0;

       for(i=0;i<size;i++)

              xAnsList[i]=0;

      

       fprintf(outputFile,"k\t\t");

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

              fprintf(outputFile,"x%d\t\t",i);

       fprintf(outputFile,"\r\n");

      

       fprintf(outputFile,"%-15d",iteratorNum);

       for(i=0;i<size;i++)

              fprintf(outputFile,"%-15f",xAnsList[i]);

       fprintf(outputFile,"\r\n");

      

       iteratorNum++;

       do

       {

              listArrCopy(xAnsList,tmpXList,size);

              for(i=0;i<size;i++)

              {

                     sum=0;

                     for(j=0;j<size;j++)

                            if(i!=j)

                                   sum+=inMatrixArr[i][j]*tmpXList[j];

                     xAnsList[i]=(float)1/inMatrixArr[i][i]*(bList[i]-sum);

              }

 

 

              fprintf(outputFile,"%-15d",iteratorNum);

              for(i=0;i<size;i++)

                     fprintf(outputFile,"%-15f",xAnsList[i]);

              fprintf(outputFile,"\r\n");

              iteratorNum++;

             

       }

       while(!preciseReached(xAnsList,tmpXList,size,precise));

      

       free(tmpXList);

}

 

 

2 Gauss_Seidel

接下来是一个改进版本,主要提高了迭代速度.注意到在逐个求x_k=1的分量时,当计算到分量xi_k+1时,分量x1_k+1~xi-1_k+1都已得到,而用新分量求下一步分量会比原来更准确,速度上也会有提高,而这个动作在编程上更易实现,原来在迭代的过程中还要用到一个tmpXList数组,此时已经不需要在主迭代过程中使用了.

这便有了下面的Gauss_Seidel方法:

/*

Gauss_Seidel, coded by EmilMathew 05/9/8, you can modify and use these code as you wish , but there is no guarantee that it can fit all you need.

*/

 

 

void Gauss_SeidelMethod(Type** inMatrixArr,Type* bList,Type* xAnsList,Type precise,int size,FILE* outputFile)

{

      

       int iteratorNum;

       int i=0,j=0;

       Type sum=0;

       Type* tmpXList;

       /*pointer data assertion*/

       assertF(inMatrixArr!=NULL,"in JacobiMethod,matrixArr is NULL\n");

       assertF(bList!=NULL,"in JacobiMethod,bList is NULL\n");

       assertF(xAnsList!=NULL,"in JacobiMethod,xAnsList is NULL\n");

      

       tmpXList=(Type*)malloc(sizeof(Type)*size);

       assertF(tmpXList!=NULL,"in JacobiMethod,tmpXList is NULL\n");

      

       /*init data*/

       iteratorNum=0;

       for(i=0;i<size;i++)

              xAnsList[i]=0;

      

       fprintf(outputFile,"k\t\t");

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

              fprintf(outputFile,"x%d\t\t",i);

       fprintf(outputFile,"\r\n");

      

       fprintf(outputFile,"%-15d",iteratorNum);

       for(i=0;i<size;i++)

              fprintf(outputFile,"%-15f",xAnsList[i]);

       fprintf(outputFile,"\r\n");

      

       iteratorNum++;

       do

       {

              listArrCopy(xAnsList,tmpXList,size);

              for(i=0;i<size;i++)

              {

                     sum=0;

                     for(j=0;j<size;j++)

                            if(i!=j)

                                   sum+=inMatrixArr[i][j]*xAnsList[j];

                     xAnsList[i]=(float)1/inMatrixArr[i][i]*(bList[i]-sum);

              }

 

 

              fprintf(outputFile,"%-15d",iteratorNum);

              for(i=0;i<size;i++)

                     fprintf(outputFile,"%-15f",xAnsList[i]);

              fprintf(outputFile,"\r\n");

              iteratorNum++;

             

       }

       while(!preciseReached(xAnsList,tmpXList,size,precise));

       free(tmpXList);

}

 

 

 

 

3逐次超松弛迭代法:

逐次超松弛迭代法主要是在前面的Gauss_Seidel基础上加以改进,考虑引入适当的松驰因子及做适当的线性变换可得.

/*

SORMethod, coded by EmilMathew 05/9/8, you can modify and use these code as you wish , but there is no guarantee that it can fit all you need.

*/

void SORMethod(Type** inMatrixArr,Type* bList,Type* xAnsList,Type w,Type precise,int size,FILE* outputFile)

{

       int iteratorNum;

       int i=0,j=0;

       Type sum=0;

       Type* tmpXList;

       /*pointer data assertion*/

       assertF(inMatrixArr!=NULL,"in JacobiMethod,matrixArr is NULL\n");

       assertF(bList!=NULL,"in JacobiMethod,bList is NULL\n");

       assertF(xAnsList!=NULL,"in JacobiMethod,xAnsList is NULL\n");

      

       tmpXList=(Type*)malloc(sizeof(Type)*size);

       assertF(tmpXList!=NULL,"in JacobiMethod,tmpXList is NULL\n");

      

       /*init data*/

       iteratorNum=0;

       for(i=0;i<size;i++)

              xAnsList[i]=0;

      

       fprintf(outputFile,"k\t\t");

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

              fprintf(outputFile,"x%d\t\t",i);

       fprintf(outputFile,"\r\n");

      

       fprintf(outputFile,"%-15d",iteratorNum);

       for(i=0;i<size;i++)

              fprintf(outputFile,"%-15f",xAnsList[i]);

       fprintf(outputFile,"\r\n");

      

       iteratorNum++;

       do

       {

              listArrCopy(xAnsList,tmpXList,size);

              for(i=0;i<size;i++)

              {

                     sum=0;

                     for(j=0;j<size;j++)

                            if(i!=j)

                                   sum+=inMatrixArr[i][j]*xAnsList[j];

                     xAnsList[i]=xAnsList[i]+w/inMatrixArr[i][i]*(bList[i]-sum);

              }

 

 

              fprintf(outputFile,"%-15d",iteratorNum);

              for(i=0;i<size;i++)

                     fprintf(outputFile,"%-15f",xAnsList[i]);

              fprintf(outputFile,"\r\n");

              iteratorNum++;

             

       }

       while(!preciseReached(xAnsList,tmpXList,size,precise));

       free(tmpXList);

}

 

 

测试:

用以上三种方法对同一个线性方程组进行求解,精度为0.0001,得到的迭代结果如下:

testProgram:

inputData:

3,0.0001;

10,-1,-2,7.2;

-1,10,-2,8.3;

-1,-1,5,4.2;

 

 

Jacobi:

k                   x1                  x2                  x3          

0              0.000000       0.000000       0.000000      

1              0.720000       0.830000       0.840000      

2              0.971000       1.070000       1.150000      

3              1.057000       1.157100       1.248200      

4              1.085350       1.185340       1.282820      

5              1.095098       1.195099       1.294138      

6              1.098337       1.198337       1.298039      

7              1.099442       1.199442       1.299335      

8              1.099811       1.199811       1.299777      

9              1.099936       1.199936       1.299924      

10             1.099978       1.199979       1.299975 

 

 

 

 

Guass_SeidelMethod

k                   x1                  x2                  x3                 

0              0.000000       0.000000       0.000000      

1              0.720000       0.902000       1.164400      

2              1.043080       1.167188       1.282054      

3              1.093130       1.195724       1.297771      

4              1.099126       1.199467       1.299719      

5              1.099890       1.199933       1.299965      

6              1.099986       1.199992       1.299996     

 

 

 

 

SORMethod 松驰系数w1.05

k                   x1                  x2                  x3                 

0              0.000000       0.000000       0.000000      

1              0.756000       0.950880       1.240445      

2              1.078536       1.197696       1.297986      

3              1.100408       1.199735       1.300131      

4              1.099979       1.200039       1.299997      

5              1.100004       1.199998       1.300001 

 

 

 

 

可以看出,各种方法在迭代的速度上是逐个增加的,与理论是相一致的.

发表于 @ 2005年09月08日 19:52:00|评论(loading...)

新一篇: [数值算法]线性方程组的求解---平方根法及改进平方根法 | 旧一篇: [数值算法]线性方程组求解算法---基于LU分解法的追赶法

用户操作
[即时聊天] [发私信] [加为好友]
秦盛
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
秦盛的公告

〖我的作品〗



〖我的连载〗

快速Flash开发

〖文化视角〗

     1.90年代初的苏州

     2.中国动画80年

     3.古城真定

     4.三国知识问答

     5.大哥陈松勇

     6.圣斗士.终章

     7.武侠配乐.少林雄风

     8.李宗盛.生活家的院子

     9.李敖精彩语录选

     10.安东尼奥尼.中国.剪影.1

     11.安东尼奥尼.中国.剪影.2

     12.林青霞向季老讨文气

     13.山水情.中国水墨动画之巅峰

     14.《人物》之媒体人.刘长乐

     15.侯孝贤谈悲情城市

     16.转.夜泊秦淮近酒家

     17.冯骥才:守望民间文化的精卫鸟


我是一个快乐的赌徒,因为我掷出去的每把骰子,都是自己的,玩的都是真性情。


和很多人一样,我没有好的家境可以依赖,一切都从零开始,靠自己打拼.有时,站在太阳下,经常问自己:"我就这样了?"回答,当然是否定的,但要的是------行动.



〖宣言〗

前途是光明的

道路是曲折的


〖祈福〗

祝季羡林老先生在301医院身体健康,心情愉快!

祝李敖大师精神矍铄,风采不逊当年,多出新作!

遥祝Bertrand Rusell在天堂依旧幸福人生!


    〖强烈推荐〗

   ACM图灵奖演讲集

   FF背后的牛人们

   (视频)Dijkstra风采













文章分类
收藏
05大师有大智慧
Alan Kay(Smalltalk,OOP)
BERTRAND RUSSELL
Donald E. Knuth(Art of Algorithm)
Edsger W. Dijkstra(Programming & Algorithm Design,Shortest Path)
John McCarthy(人工智能)
李敖
06闲情,感悟
苏州古城的历史
苏州杂志
读者论坛
赵云庙
07天籁之音
[周华健,李度]难以抗拒
[成龙,苏慧伦]在我生命中的每一天
[成龙]壮志在我胸
[灌篮高手]直到世界的尽头
Somewhere out there
somke gets in your eyes
When You Believe
野风[新龙门客栈片尾曲,林忆莲]
08苏州中学
苏中主页
09算法,数据结构,优化
ACM/ICPC的司令部
Dictionary of Algo&DS
IOI选手优秀论文
Lucky猫的ACM园地
UVA在线答题系统
中国人工智能网
中国数据挖掘网
中国网格信息中转站
中国运筹学协会
信息学初学者之家
信息学奥林匹克基地
北大ACM站
数据结构自考网
浙大ACM站
10科学,论文
Citeseer
Scientific American
Tex中文站
yesize资料坊
上海网上天文台
中国学术期刊网
中国工程院
中国水利期刊
中国知网
中国科学院
大众科普网
奇迹文库
科研中国
集智俱乐部
11名校计算机科学院巡礼
(UIUC)伊利诺伊香槟分校
Carnegie Mellon(卡梅基隆)
Mit[麻省理工学院]
Princeton[普灵斯顿大学]
purdue[普度大学]
Stanford[斯坦福大学]
中国科学技术大学
交通大学
北京大学
南京大学
复旦大学
浙江大学
清华大学
12应用数学,建模
Math.com
中国数学建模
中国统计网
数学中国
数学常用工具FAQ
13ComputerScience
《计算机教育》期刊网站
acm来了
李开复学生网
15综合科学
《科学》杂志
从欧氏几何到微分几何
16数值计算
Pi的小站
17朋友的链接
Nemon
大漠穷秋
18EnglishLearning
沪江英语
20图形学
The Chaos Games
VRML用户手册
中国虚拟现实开发者
中国计算机图形学教学研究会
分形屏道
分形艺术
机器视觉在线
虚拟无忌
21操作系统
Bochs摸拟环境
ChinaLinux
Linux/BSD/UNIX文档
Linux_Kernel
中国UNIX技术联盟
帮助Linux爱好者
永远的UNIX
22ActionScript_Flash
[Flasher]Dengjie
[开源的AS2编译器]Mtasc
FlashASM
RobertPenner
ultrashock
X-Woods
闪吧音乐盒
23C/C++
C++ Home
C++FAQ-LITE
C-C++ User Journal
CPlusPlus.com
C语言之家
GCC Compiler
GCC.GNU
SGI-STL
VCHelp[CN DEV]
VC知识库
24GameDev
CSDN游戏开发站
GamaSutra
GameAI
GameDev.NET
Gamerers
vbgamer
25JAVA技术
JAVA.SUN
中文JAVA技术网
26编程技术
[MSDN Eng]
[MSDN 中文版]
ASCII Table
SourceForge
UML.ORG
中国程序员(CSDN)
文件格式汇编
程序员联合开发网
问专家
28物理模拟与仿真
中国仿真互动
流体中文网
29网络安全
绿盟论坛
30环保
中国环境监测
南水北调网
国家环保总局
江苏环保网
31可爱的事物
叮铛论坛
32设计,排版
5D多媒体
BlueIdea
印科网
33影视,音乐,电台
上海文广新闻传媒
阿拉上海人
34优秀个人BLOG
fisher_jiang的专栏
gzfqh的专栏
ScienceStudy
刘爱贵的个人主页
大肚能容天下剑
寒蝉退士
梦想风暴
煮石
男儿当自强
男单618
编程夜未眠
记得忘记@博客
35专栏
抗战胜利60年(sina)
抗战胜利60年(yahoo)
50电子游戏
Raine街机模拟器
WAR3中文网
专业射击游戏联盟
地精研究院
51常用软件
flashfxp
GreenBrowser
小巧好用的编辑器SciTEFlash
强力抓屏
金山在线词典
52网上书店
DearBook
当当网
53硬件DIY
52硬件
电脑报论坛
存档
Csdn Blog version 3.1a
Copyright © 秦盛