原理:
将积分区间平均分成多份,每个进程计算相应的任务,计算完成后通过根进程收集并求和得出答案并计算出相应的误差。
代码如下:
#include <stdio.h>
#include "mpi.h"
#include <string.h>
#include<math.h>
#define PI 3.1415926
double my_abs(double x)
{
if(x <= 0)
x = x * -1;
return x;
}
int main(int argc,char **argv)
{
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Status status;
int size,rank,dest;
char str[100];
MPI_Init(&argc,&argv);
MPI_Comm_size(comm,&size);
MPI_Comm_rank(comm,&rank);
int n = 100000; //将区间分成100000份
double dx = PI / 2 / n;
if(rank==0)
{
double sum,sum1,sum2,sum3,sum4;
double error_ ;
MPI_Recv(&sum1,1,MPI_DOUBLE,1,1,comm,&status); //接收子进程计算结果
MPI_Recv(&sum2,1,MPI_DOUBLE,2,2,comm,&status);
MPI_Recv(&sum3,1,MPI_DOUBLE,3,3,comm,&status);
//MPI_Recv(&sum4,1,MPI_DOUBLE,4,4,comm,&status);
sum = sum1 + sum2 + sum3;
error_ = (1 - my_abs(1 - my_abs(sum))) * 100; //计算误差
printf("result is : %lf\n",sum);
printf("right is : %lf%% \n",error_);
}
else if(rank==1)
{
double aij = 0;
double sum = 0;
int i = 0;
//while(aij + i * dx <= PI / 2)
while(i <= n) //计算积分
{
sum += dx * cos(aij + dx / 2);
i++;
aij += dx;
}
MPI_Send(&sum,1,MPI_DOUBLE,0,1,comm);//将计算结果发给根进程
}
else if(rank==2)
{
double aij = PI / 2;
double sum = 0;
int i = 0;
while(i <= n)
{
sum += dx * cos(aij + dx / 2);
i++;
aij += dx;
}
MPI_Send(&sum,1,MPI_DOUBLE,0,2,comm);
}
else if(rank==3)
{
double aij = PI;
double sum = 0;
int i = 0;
while(i <= n)
{
sum += dx * cos(aij + dx / 2);
i++;
aij += dx;
}
MPI_Send(&sum,1,MPI_DOUBLE,0,3,comm);
}
/*
else if(rank==4)
{
double aij = 3*PI /2;
double sum = 0;
int i = 0;
while(aij + i * dx <= PI*2)
{
sum += dx * cos(aij + dx / 2);
i++;
}
MPI_Send(&sum,1,MPI_DOUBLE,0,4,comm);
}
*/
MPI_Finalize();
return 0;
}
运行结果:
如图所示,区间分的份数越多,误差越小。