环境
- centos7
- mpi 3.2
要求
求cosxdx在a到b区间的积分可以由上图方法近似,图中p是process进程的数量,n是划分小长方形的数量,在输入的时候给出。
代码
注:本代码输入的时候b和a是角度值
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#define PI acos(-1.0)
double to_rad(double degree){
return degree / 180 * PI;
}
int main(int argc,char **argv){
int size,rank;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(comm,&size);
MPI_Comm_rank(comm,&rank);
if(rank == 0) {
int n;
double b,a;
printf("input a num\n");
scanf("%d",&n);
printf("then input b and a\n");
scanf("%lf %lf",&b, &a);
if(b < a){//防止输错
double tmp = a;
a = b;
b = tmp;
}
for(int i = 1;i < size;i++){
MPI_Send(&n,1,MPI_INT,i,99,comm);
MPI_Send(&a,1,MPI_DOUBLE,i,99,comm);
MPI_Send(&b,1,MPI_DOUBLE,i,99,comm);
}
int p = size;
double h = (to_rad(b) - to_rad(a))/p/n;
double sum = 0.0;
for(int i = 0;i < n;i++) {
double num = to_rad(a) + (rank*n + i)*h;
sum += cos(num + h/2)*h;
}
for(int i = 1;i < size;i++) {
double tmp_num;
MPI_Recv(&tmp_num,1,MPI_DOUBLE,i,99,comm,&status);
sum += tmp_num;
}
printf("区间(a,b) cosdx 的积分 = %.3lf\n",sum);
}
else {
int p = size;
int n;
double b,a;
MPI_Recv(&n,1,MPI_INT,0,99,comm,&status);
MPI_Recv(&a,1,MPI_DOUBLE,0,99,comm,&status);
MPI_Recv(&b,1,MPI_DOUBLE,0,99,comm,&status);
double h = (to_rad(b) - to_rad(a))/p/n;
printf("PI_%lf h_%lf\n",PI,h);//中间结果
double sum = 0.0;
for(int i = 0;i < n;i++) {
double num = to_rad(a) + (rank*n + i)*h;
sum += cos(num + h/2)*h;
}
printf("cos(x)%d = %.3lf\n",rank,sum);//中间结果
MPI_Send(&sum,1,MPI_DOUBLE,0,99,comm);
}
MPI_Finalize();
return 0;
}