Задача: Вычисление двойного интеграла с использованием MPI
Исходник: Вычисление двойного интеграла, короче площади, язык: C [code #163, hits: 11989]
автор: - [добавлен: 30.06.2006]
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "mpi.h"
  4.  
  5. //----------------- Эта функция считает значение функции 5*X^2*Y+2*Y^3
  6. float Func ( float X , float Y )
  7. {
  8. return ( 5*X*X*Y-2*Y*Y*Y );
  9. }
  10. //------- Эта функция возвращает случайное число в диапозоне от 0 до 1
  11. double GetRandom ()
  12. {
  13. return (double) rand ()/RAND_MAX;
  14. }
  15. //----------------- Эта функция считает интеграл --------------------
  16. float DoubleIntegrall ( int N , // Количество отрезков интегрирования
  17. float AX , float BX ,// Интервал откуда бер&#9574;м случайные значения для X
  18. float AY , float BY )// Интервал откуда бер&#9574;м случайные значения для Y
  19. {
  20. float HX = BX-AX , HY = BY-AY ,x, y, f = 0;
  21. int i;
  22. for ( i=0; i<N; i++ )
  23. {
  24. x = (float) ( GetRandom ()*HX + AX );
  25. y = (float) ( GetRandom ()*HY + AY );
  26. f =+ Func ( x , y );
  27. }
  28. return ( HX*HY*f/N );
  29. }
  30. //------------------- MAIN -------------------------------
  31. int main(int argc, char *argv[])
  32. {
  33. int My_Rank; /* ранг текущего процесса */
  34. int NumProcs; /* общее число процессов */
  35. double AX , AY; /* левый конец интервала */
  36. double BX , BY; /* правый конец интервала */
  37. int N; /* число точек разбиения */
  38. double LenX; /*LenY; /* длина отрезка интегрирования для текущего процесса*/
  39. double Local_AX , Local_AY;/* левый конец интервала для текущего процесса */
  40. double Local_BX , Local_BY; /* правый конец интервала для текущего процесса */
  41. int Local_N; /* число точек разбиения для текущего процесса */
  42. double Local_Res;/* значение интеграла в текущем процессе */
  43. double Result; /* результат интегрирования */
  44. double WTime; /* время работы программы */
  45.  
  46. /* Инициализация */
  47. srand ( ( unsigned ) time ( NULL ) );
  48. /* Начать работу с MPI */
  49. MPI_Init(&argc, &argv);
  50. /* Получить номер текущего процесса в группе всех процессов */
  51. MPI_Comm_rank(MPI_COMM_WORLD, &My_Rank);
  52. /* Получить общее количество запущенных процессов */
  53. MPI_Comm_size(MPI_COMM_WORLD, &NumProcs);
  54. /* Получить данные */
  55. if (My_Rank == 0)
  56. {
  57. printf("Введите начальное значение X: ");
  58. scanf("%lf", &AX);
  59. printf("Введите конечное значение X: ");
  60. scanf("%lf", &BX);
  61.  
  62. printf("Введите начальное значение Y: ");
  63. scanf("%lf", &AY);
  64. printf("Введите конечное значение Y: ");
  65. scanf("%lf", &BY);
  66.  
  67. printf("Введите количество случайных значений : ");
  68. scanf("%d", &N);
  69. }
  70. /* Рассылаем данные из процесса 0 остальным */
  71. MPI_Bcast(&AX, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  72. MPI_Bcast(&BX, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  73.  
  74.  
  75. MPI_Bcast(&AY, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  76. MPI_Bcast(&BY, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  77.  
  78. MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
  79. /* Синхронизация процессов */
  80. MPI_Barrier(MPI_COMM_WORLD);
  81. /* Запускаем таймер */
  82. WTime = MPI_Wtime();
  83. /* Вычисляем отрезок интегрирования для текущего процесса */
  84. LenX = (BX-AX)/NumProcs;
  85. //LenY = (BY-AY)/NumProcs;
  86.  
  87. Local_N = N/NumProcs;
  88.  
  89. Local_AX = AX + My_Rank*LenX;
  90. Local_BX = Local_AX + LenX;
  91.  
  92. Local_AY = AY; // + My_Rank*LenY;
  93. Local_BY = BY; //Local_AY + LenY;
  94. /* Вычислить интеграл на каждом из процессов */
  95. Local_Res = DoubleIntegrall (Local_N, Local_AX, Local_BX, Local_AY, Local_BY);
  96. /* Сложить все ответы и передать процессу 0 */
  97. MPI_Reduce(&Local_Res, &Result, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  98. /* Синхронизация процессов */
  99. MPI_Barrier(MPI_COMM_WORLD);
  100. /* Вычисляем время работы */
  101. WTime = MPI_Wtime() - WTime;
  102. /* Напечатать ответ */
  103. if (My_Rank == 0)
  104. {
  105. printf("Integral X:[ %.2lf ; %.2lf ] Y:[ %.2lf ; %.2lf ] = %.8lf\n", AX, BX, AY, BY, Result);
  106. printf("Working time: %.2lf seconds\n", WTime);
  107. }
  108. /* Заканчиваем работу с MPI */
  109. MPI_Finalize();
  110. return 0;
  111. }
C/C++, Linux

автор: http://forum.codenet.ru/member.php?action=getinfo&username=Mapcuk

+добавить реализацию