Código paralelo para el cálculo del área bajo la curva de una función f(x)
.
[fontfamily=courier,fontshape=it,fontsize=\small,baselinestretch=0.6]
/**
* Este programa calcula el área bajo la curva del polinomio
* f(x)= Y = 10.5 + 1.2x + 0.8x^2 - 2.25x^3 + 0.5x^4 con límite
* inferior 0 y límite superior 9.5 haciendo uso de la librería
* MPI para código paralelo. La función f(x) puede ser cambiada
* en f_de_x(), ver más abajo.
* Código modificado de la fuente:
* http://www.cc.ku.edu/~grobe/docs/intro-MPI-C.shtml {Enero 2006}
**/
#include <stdio.h>
#include <math.h>
#include <mpi.h>
#define PI 3.1415926535
#define LIM_INF 0.0 /*Limite Inferior de la Integral*/
#define LIM_SUP 9.5 /*Limite Superior de la Integral*/
double f_de_x(double x);
/*En el cuerpo de esta función puedes cambiar el calculo para f(x)*/
main(int argc, char **argv)
{
int my_id, root_process, num_procs, ierr, num_intervals, i;
double rect_width, area, sum, x_middle, partial_sum;
MPI_Status status;
/* 0 es el proceso raíz. */
root_process = 0;
/* Replicar el proceso para crear procesos paralelos. */
ierr = MPI_Init(&argc, &argv);
/* Encuentra MI ID de proceso y cuantos procesos fueron iniciados. */
ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
if(my_id == root_process) {
/*Modificar el código de las siguientes líneas si se quiere
*preguntar al usuario cuantos procesos iniciar.
*printf("Please enter the number of intervals to interpolate: ");
scanf("%i", &num_intervals);*/
num_intervals = 150000000;
printf("Integrando la función \
Y = 10.5 + 1.2x + 0.8x^2 - 2.25x^3 + 0.5x^4 \
en %d intervalos...\n",num_intervals);
printf("Límite Inferior: %f\n",LIM_INF);
printf("Límite Superior: %f\n\n",LIM_SUP);
}
/* Se envía un mensaje a todos los subprocesos del número de
* intervalos. */
ierr = MPI_Bcast(&num_intervals, 1, MPI_INT, root_process,
MPI_COMM_WORLD);
/* cálculo de la base del rectángulo, y ... */
rect_width = (LIM_SUP - LIM_INF) / num_intervals;
/* se calcula la suma de las áreas de los rectángulos de las cuales el
* subproceso es responsable. */
partial_sum = 0;
for(i = my_id + 1; i <num_intervals + 1; i += num_procs) {
x_middle = (i - 0.5) * rect_width;
area = f_de_x(x_middle) * rect_width;
partial_sum = partial_sum + area;
}
printf("proc %i computes: %f\n", my_id, partial_sum);
/* Finalmente las sumas parciales son recogidas en la variable "sum" */
ierr = MPI_Reduce(&partial_sum, &sum, 1, MPI_DOUBLE,
MPI_SUM, root_process, MPI_COMM_WORLD);
/* Si soy el proceso raíz, imprimo el resultado */
if(my_id == root_process) {
printf("The integral is %f\n", sum);
}
/* finaliza el proceso. */
ierr = MPI_Finalize();
}
double f_de_x(double x)
{
double punto = 0.0, valor = 0.0;
double poli[]={10.5,1.2,0.8,-2.25,0.5};
int i = 0;
punto = x;
for(i=0;i<5;i++)
valor += poli[i]*pow(punto,i);
return valor;
/*El usuario puede definir otras funciones, Ejemplos:
1) return sin(x);
2) return cos(x);
3) return x*x;
4) return x/2;
*/
}
