梯形积分法串行代码的实现:

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <math.h>
#define MAXN 30
double fun1(double x);
double fun2(double x);
double fun3(double x);
double Definite_integral(double a, double b, double (*p)(double x));

int main()
{
	int c = 1;
	double a, b;
	char d = '0';
	printf("*************************************\n");
	printf("*****  用梯形积分串行算法     *******\n");
	printf("*****   1、函数为:y = x      *******\n");
	printf("*****   2、函数为:y = x^2    *******\n");
	printf("*****   3、函数为:y = sin(x) *******\n");
	printf("*************************************\n");

	while (0 != c) {
		printf("请输入您要选择的类型:");
		scanf("%d",&c);

		switch (c)
		{
		case 1:
			printf("请输入积分上下限(以空格隔开):>");
			scanf("%lf %lf",&a,&b);
			printf("该函数在%lf-%lf上的积分值为:》%lf\n", a, b, Definite_integral(a, b, fun1));
			break;
		case 2:
			printf("请输入积分上下限(以空格隔开):>");
			scanf("%lf %lf",&a,&b);
			printf("该函数在%lf-%lf上的积分值为:》%lf\n", a, b, Definite_integral(a, b, fun1));
			break;
		case 3:
			printf("请输入积分上下限(以空格隔开):>");
			scanf("%lf %lf",&a,&b);
			printf("该函数在%lf-%lf上的积分值为:》%lf\n", a, b, Definite_integral(a, b, fun1));
			break;
		default:
			printf("您的输入有误,您的选择只能是:1、2、3、0,请重新输入!\n");
			break;
		}

		printf("您还要继续选择吗?(1/0):>");
		scanf("%d",&c);
	}
	printf("程序结束,欢迎下次再来!");

	return 0;
}
/* 梯形法求定积分*/
double Definite_integral(double a, double b, double (*p)(double x)) {
	int i, n = MAXN;
	double x, y1, y2, deta, f;
	deta = (b - a) / n;
	x = a;
	y1 = (*p)(x);
	f = 0;
	for (i = 0; i < n; i++) {
		x += deta;
		y2 = (*p)(x);
		f += (y1 + y2) * deta / 2;
		y1 = y2;
	}
	return f;
}
/*定义被积函数,三种供选择*/
double fun1(double x) {
	double fx;
	fx = x;
	return fx;
}
double fun2(double x) {
	double fx;
	fx = x * x;
	return fx;
}
double fun3(double x) {
	double fx;
	fx = sin(x);
	return fx;
}

结果:

使用MPI点对点通信梯形积分法并行代码的实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include "mpi.h"

//输入
void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p, int* n_p);
double Trap(double left_endpt, double right_endpt, int trap_count, double b);
double f(double x);

//使用MPI点对点通信梯形积分法并行代码的实现
int main(void) {
	int my_rank, comm_sz, n = 1000000000, local_n;//n为分成梯形的个数,a为积分下线,b为积分上线
	double a = 0.0, b = 1.0, h, local_a, local_b;
	double local_int, total_int;
	int source;
	double* a_p = &a;
	double* b_p = &b;
	int* n_p = &n;
MPI_Init(NULL, NULL);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);

	Get_input(my_rank, comm_sz, a_p, b_p, n_p);

	h = (b - a) / n;
	local_n = n / comm_sz;

	local_a = a + my_rank * local_n * h;
	local_b = local_a + local_n * h;
	local_int = Trap(local_a, local_b, local_n, h);

	if (my_rank != 0) {
		MPI_Send(&local_int, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
	}
	else {
		total_int = local_int;
		for (source = 1; source < comm_sz; source++) {
			MPI_Recv(&local_int, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
			total_int += local_int;
		}
	}

	if (my_rank == 0) {
		printf("With n = %d trapezoids, our estimate\n", n);
		printf("of the integral from %f to %f = %.15e\n", a, b, total_int);
	}

	MPI_Finalize();
	return 0;
}

//梯形面积和 =   h  * (  f(x0)/2 + f(x1) + ....... + f(xn)/2)       h = (b-a)/n;
double Trap(double left_endpt, double right_endpt, int trap_count, double base_len) {
	double estimate, x;
	int i;

	estimate = (f(left_endpt) + f(right_endpt)) / 2.0;
	for (i = 1; i <= trap_count - 1; i++) {
		x = left_endpt + i * base_len;
		estimate += f(x);
	}
	estimate = estimate * base_len;
	return estimate;
}

double f(double x) {
	return 4.0 / (1 + x * x);
}

void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p, int* n_p) {
	int dest;

	if (my_rank == 0) {
		printf("Enter a, b,and n \n");
		scanf("%lf  %lf  %d", a_p, b_p, n_p);
		for (dest = 1; dest < comm_sz; dest++) {
			MPI_Send(a_p, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
			MPI_Send(b_p, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
			MPI_Send(n_p, 1, MPI_INT, dest, 0, MPI_COMM_WORLD);
		}

	}
	else {
		MPI_Recv(a_p, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		MPI_Recv(b_p, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		MPI_Recv(n_p, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
	}
}

结果

使用MPI集合通信梯形积分法并行代码的实现。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include "mpi.h"

double Trap(double left_endpt, double right_endpt, int trap_count, double b);
double f(double x);
void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p, int* n_p);

int main(void) {
	int my_rank, comm_sz, n, local_n;
	double a, b, h, local_a, local_b;
	double local_int, total_int;
	int source;

	MPI_Init(NULL, NULL);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);

	Get_input(my_rank, comm_sz, &a, &b, &n);

	h = (b - a) / n;
	local_n = n / comm_sz;

	local_a = a + my_rank * local_n * h;
	local_b = local_a + local_n * h;
	local_int = Trap(local_a, local_b, local_n, h);
 
	MPI_Reduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

	if (my_rank == 0) {
		printf("With n = %d trapezoids, our estimate\n", n);
		printf("of the integral from %f to %f = %.15e\n", a, b, total_int);
	}

	MPI_Finalize();
	return 0;
}
double Trap(double left_endpt, double right_endpt, int trap_count, double base_len) {
	double estimate, x;
	int i;

	estimate = (f(left_endpt) + f(right_endpt)) / 2.0;
	for (i = 1; i <= trap_count - 1; i++) {
		x = left_endpt + i * base_len;
		estimate += f(x);
	}
	estimate = estimate * base_len;

	return estimate;
}

double f(double x) {
	return 4.0 / (1 + x * x);
}

void Get_input(int my_rank, int comm_sz, double* a_p, double* b_p, int* n_p) {
	int dest;

	if (my_rank == 0) {
		printf("Enter a, b, and n\n");
		scanf("%lf %lf %d", a_p, b_p, n_p);
	}

	MPI_Bcast(a_p, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Bcast(b_p, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
	MPI_Bcast(n_p, 1, MPI_INT, 0, MPI_COMM_WORLD);
}

结果: