用雅可比迭代法求线性方程组的解的并行算法(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 ,如需转载请自行联系原作者
相关文章
|
存储 缓存 算法
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
【数据结构与算法】【小白也能学的数据结构与算法】递归 分治 迭代 动态规划 无从下手?一文通!!!
|
2月前
|
并行计算 算法 调度
基于串行并行ADMM算法的主从配电网分布式优化控制研究(Matlab代码实现)
基于串行并行ADMM算法的主从配电网分布式优化控制研究(Matlab代码实现)
214 0
|
8月前
|
资源调度 算法 数据可视化
基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。
267 14
|
资源调度 算法
基于迭代扩展卡尔曼滤波算法的倒立摆控制系统matlab仿真
本课题研究基于迭代扩展卡尔曼滤波算法的倒立摆控制系统,并对比UKF、EKF、迭代UKF和迭代EKF的控制效果。倒立摆作为典型的非线性系统,适用于评估不同滤波方法的性能。UKF采用无迹变换逼近非线性函数,避免了EKF中的截断误差;EKF则通过泰勒级数展开近似非线性函数;迭代EKF和迭代UKF通过多次迭代提高状态估计精度。系统使用MATLAB 2022a进行仿真和分析,结果显示UKF和迭代UKF在非线性强的系统中表现更佳,但计算复杂度较高;EKF和迭代EKF则更适合维数较高或计算受限的场景。
|
机器学习/深度学习 人工智能 分布式计算
算法金 | 最难的来了:超参数网格搜索、贝叶斯优化、遗传算法、模型特异化、Hyperopt、Optuna、多目标优化、异步并行优化
机器学习中的超参数调优是提升模型性能的关键步骤,包括网格搜索、随机搜索、贝叶斯优化和遗传算法等方法。网格搜索通过穷举所有可能的超参数组合找到最优,但计算成本高;随机搜索则在预设范围内随机采样,降低计算成本;贝叶斯优化使用代理模型智能选择超参数,效率高且适应性强;遗传算法模拟生物进化,全局搜索能力强。此外,还有多目标优化、异步并行优化等高级技术,以及Hyperopt、Optuna等优化库来提升调优效率。实践中,应结合模型类型、数据规模和计算资源选择合适的调优策略。
763 0
算法金 | 最难的来了:超参数网格搜索、贝叶斯优化、遗传算法、模型特异化、Hyperopt、Optuna、多目标优化、异步并行优化
|
存储 算法 数据挖掘
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】
python5种算法模拟螺旋、分层填充、递归、迭代、分治实现螺旋矩阵ll【力扣题59】
|
机器学习/深度学习 存储 算法
Python5种算法回溯+剪枝、字典序、递归交换、计数回溯、迭代法 实现全排列ll【力扣题47】
Python5种算法回溯+剪枝、字典序、递归交换、计数回溯、迭代法 实现全排列ll【力扣题47】
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
220 0
|
搜索推荐 C语言 C++
【排序算法】C语言实现归并排序,包括递归和迭代两个版本
【排序算法】C语言实现归并排序,包括递归和迭代两个版本
398 1

热门文章

最新文章