用雅可比迭代法求线性方程组的解的并行算法(MPI)

简介:
 1  // =================================================================
  2  //  Name : 使用雅可比迭代法求解线性方程组
  3  //  Author : 袁冬(2107020046)
  4  //  Copyright : 中国海洋大学
  5  //  LastUpdate : 2007.10.18    
  6  //  Develop Evrionment : Windows Server 2003 SP2
  7  //                         + Eclipse 3.3.1 + CDT 4.0.1 
  8  //                         + MinGW 3.81 + GDB 6.6 
  9  //                         + mpich2-1.0.6-win32-ia32
 10  // =================================================================
 11 
 12  // #define DEBUG 1  // 调试符号
 13 
 14  #define TRUE 1
 15  #define FALSE 0
 16  #define bool int
 17 
 18  #define MAX_N 100  // 允许的最大未知数个数
 19  #define MAX_A (MAX_N * MAX_N)  // 允许最大的系数的个数
 20 
 21  #define MAX_ITERATION 10000  // 最大迭代次数
 22  #define TOLERANCE 0.001  // 误差
 23 
 24 #include "mpi.h"
 25 #include <stdio.h>
 26 #include <stdlib.h>
 27 
 28  int pID, pSize;  // pID:当前进程ID,pSize:总的进程数
 29  int n, iteration = 0;  // n:未知数的个数,iternation:迭代的次数
 30  float x[MAX_N], new_x[MAX_N], result_x[MAX_N];  // x:表示上一次迭代的结果,new_x:表示这一次迭代的结果,result_x:表示归约之后得到的总的结果
 31  float a[MAX_N][MAX_N];  // 系数
 32  float b[MAX_N]; 
 33 
 34  // 输入
 35  void input(){
 36     
 37      int i, j;
 38     
 39     printf("The n is %d\n", n);
 40     fflush(stdout);
 41     
 42      // 输入系数
 43      for(i = 0; i < n; i++) {
 44         printf("Input a[%d][0] to a[%d][n-1]:\n", i, i);
 45         fflush(stdout);
 46          for(j = 0; j < n; j++)
 47             scanf("%f", &a[i][j]);
 48     }
 49     
 50      // 输入b
 51     printf("Input b[0] to b[n-1]:\n");
 52     fflush(stdout);
 53      for(j = 0; j < n; j++)
 54         scanf("%f", &b[j]);
 55 }
 56  // 输出结果
 57  void output(){
 58     
 59      int i;
 60     
 61     printf("Total iteration : %d", iteration);
 62      if(iteration > MAX_ITERATION) printf(", that is out of the limit of iteration!");
 63     printf("\n");
 64     
 65      for(i = 0; i < n; i++)
 66         printf("x[%d] is %f\n", i, result_x[i]);
 67 }
 68  // 判断精度是否满足要求,满足要求则返回TRUE,否则,返回FALSE
 69  bool tolerance(){
 70     
 71      int i;
 72     
 73      // 有一个不满足误差的,则返回FALSE
 74      for(i = 0; i < n; i++)
 75          if(result_x[i] - x[i] > TOLERANCE || x[i] - result_x[i] > TOLERANCE)
 76              return FALSE;
 77     
 78 #ifdef DEBUG
 79     printf("TRUE From %d\n", pID);
 80     fflush(stdout);
 81  #endif
 82     
 83      // 全部满足误差,返回TRUE
 84      return TRUE;
 85 }
 86 
 87  // 入口,主函数
 88  int main( int argc,  char* argv[]) {
 89     
 90     MPI_Status status; 
 91      int i, j;
 92      float sum;
 93     
 94      // 初始化
 95     MPI_Init(&argc, &argv); 
 96     MPI_Comm_rank(MPI_COMM_WORLD, &pID); 
 97     MPI_Comm_size(MPI_COMM_WORLD, &pSize); 
 98     
 99      // 每个进程对应一个未知数
100     n = pSize; 
101 
102      // 根进程负责输入
103      if(!pID) input();
104         
105      // 广播系数
106     MPI_Bcast(a, MAX_A, MPI_FLOAT, 0, MPI_COMM_WORLD);
107      // 广播b
108     MPI_Bcast(b, MAX_N, MPI_FLOAT, 0, MPI_COMM_WORLD);
109     
110 #ifdef DEBUG
111      // 打印a, b
112      for(j = 0; j < n; j++)
113         printf("%f ", b[j]);
114     printf(" From %d\n", pID);
115     fflush(stdout);
116  #endif
117     
118      // 初始化x的值
119      for(i = 0; i < n; i++) {
120         x[i] = b[i];
121         new_x[i] = b[i];
122     }
123     
124      // 当前进程处理的元素为该进程的ID
125     i = pID;
126     
127      // 迭代求x[i]的值
128      do{
129          // 迭代次数加1
130         iteration++;
131         
132          // 将上一轮迭代的结果作为本轮迭代的起始值,并设置新的迭代结果为0
133          for(j = 0; j < n; j++)
134         {
135             x[j] = result_x[j];
136             new_x[j] = 0;
137             result_x[j] = 0;
138         }            
139         
140          // 同步等待
141         MPI_Barrier(MPI_COMM_WORLD);
142         
143 #ifdef DEBUG
144          // 打印本轮迭代的初始值
145          for(j = 0; j < n; j++)
146             printf("%f ", x[j]);
147         printf(" From %d\n", pID);
148         fflush(stdout);
149  #endif
150         
151          // 求和
152         sum = - a[i][i] * x[i];
153          for(j = 0; j < n; j++) sum += a[i][j] * x[j];
154         
155          // 求新的x[i]
156         new_x[i] = (b[i] - sum) / a[i][i];
157         
158 #ifdef DEBUG
159          // 打印本轮迭代的结果
160          for(j = 0; j < n; j++)
161             printf("%f ", new_x[j]);
162         printf(" From %d\n", pID);
163         fflush(stdout);
164  #endif        
165         
166          // 使用归约的方法,同步所有计算结果
167         MPI_Allreduce(new_x, result_x, n, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD);
168         
169 #ifdef DEBUG
170          // 打印归约后的结果
171          for(j = 0; j < n; j++)
172             printf("%f ", result_x[j]);
173         printf(" From %d\n", pID);
174         fflush(stdout);
175  #endif        
176         
177          // 如果迭代次数超过了最大迭代次数则退出
178          if(iteration > MAX_ITERATION) {
179              break;
180         }
181     }  while(!tolerance());  // 精度不满足要求继续迭代
182      
183       // 根进程负责输出结果
184      if(!pID) output();
185     
186      // 结束
187     MPI_Finalize();
188      return 0;
189 }
190 
本文转自冬冬博客园博客,原文链接:http://www.cnblogs.com/yuandong/archive/2007/10/24/Jacobi_MPI.html ,如需转载请自行联系原作者
相关文章
|
1月前
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
14天前
|
缓存 算法 Python
python算法对音频信号处理Sonification :Gauss-Seidel迭代算法
python算法对音频信号处理Sonification :Gauss-Seidel迭代算法
10 0
|
1月前
|
算法
递归算法和迭代算法有什么不同
递归算法和迭代算法有什么不同
10 1
|
1月前
|
存储 算法 搜索推荐
【数据结构与算法】【初学者也能学的数据结构与算法】迭代算法专题
【数据结构与算法】【初学者也能学的数据结构与算法】迭代算法专题
|
4月前
|
机器学习/深度学习 分布式计算 并行计算
【MATLAB】数据拟合第11期-基于粒子群迭代的拟合算法
【MATLAB】数据拟合第11期-基于粒子群迭代的拟合算法
67 0
|
8月前
|
存储 算法 索引
算法训练Day15|理论基础● 递归遍历 ● 迭代遍历● 统一迭代
算法训练Day15|理论基础● 递归遍历 ● 迭代遍历● 统一迭代
|
9月前
|
算法
粒子群算法的迭代寻优算法(Matlab代码实现)
粒子群算法的迭代寻优算法(Matlab代码实现)
|
9月前
|
存储 编解码 算法
使用迭代最近点算法组合多个点云以重建三维场景
使用迭代最近点算法组合多个点云以重建三维场景。
202 0
|
9月前
|
算法 C语言
【C语言】带你玩转递归,迭代算法2
【C语言】带你玩转递归,迭代算法
68 0
|
9月前
|
算法 程序员 C语言
【C语言】带你玩转递归,迭代算法1
【C语言】带你玩转递归,迭代算法
42 0