Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
kursovaya_rabota.docx
Скачиваний:
25
Добавлен:
21.09.2019
Размер:
564.8 Кб
Скачать

2. Практична частина

2.1. Завдання а. Варіант 7. Розробити програму паралельного розрахунку означеного інтеграла для функції з кроком дискретизації 0,00002.

2.1.1. Метод рішення

Рішення багатьох технічних завдань зводиться до обчислення певних інтегралів, точний вираз яких складно, вимагає тривалих обчислень і незавжди виправдане практично. Тут буває цілком достатньо їх наближеного значення. Найпростішим наближеним методом є мотод прямокутників.

Нехай на відрізку [a,b], a<b, задана безперервна функція f(x). Потрібно обчислити інтеграл чисельно рівний прощу відповідної криволінійної трапеції.

Розіб’ємо підставу цієї трапеції, тобто відрізок [a;b], на n рівних частин (відрізків) довжини (крок розбиття) за допомогою точок х0=а, х1,х2,…хn=b. Можна записати, що хі=х0+h*i, де і=1,2,…, n.

У середині кожного такого відрізка побудуємо ординату уі=f(сі) графіка функції у= f(х). Прийнявши цю ординату за висоту, будуємо прямокутник з площиною h* уі.

Тоді сума площ всіх n прямокутників дає площа ступінчатої фігури, яка була наближена до наближеного значення шуканого визначегого інтегралу:

Рис.2.1. Метод прямокутників

Формула середніх прямокутників

Рис.2.2. Метод лівих прямокутників

Формула метода лівих прямокутників

Рис.2.3. Метод правих прямокутників

Формула метода правих прямокутників

При використанні бібліотеки MPI площа фігури, описуваною функцією, можна розділити між процесами, потім зібрати обчислені окремими процесами суми і отримати шукану площу.

2.1.2. Алгоритм і блок-схема роботи програми

Рис. 2.4.Блок-схема алгоритму розрахунку означеного інтегралу

Алгоритм роботи програми:

1.Початок роботи програми.

2.Оголошення змінних, присвоєння інтегралу кордон інтеграції із кроком дискретизації, завдання констант.

3.Ініціалізація MPI.

4.Визначееня кількості процесів.

5.Визначення номера процесу.

6.Якщо номер процесу дорівнює 0, то починає працювати таймер, в іншому випадку, починається пункт 7.

7.циклом від першого до останнього інтервалу,який визначений номером процесу, з кроком, рівним числу процесорів і підсумуванням висоти відрізань, визначуваних заданою функцією.

8.Обчислення всіх локальних сум площі інтегралу.

9. Якщо номер процесу дорівнює 0, то зупиняємо таймер, виконуємо обчислення площі інтегралу у нульовому процесі,і передача локальної суми від поточного процесу до нульового.

10.Фіналізація MPI.

11.Кінець роботи програми.

2.1.3. Текст програми:

#include "stdafx.h"

#include "math.h"

#include "mpi.h"

#include <stdlib.h>

int _tmain (int argc, char* argv [])

{

double PI=3.1415926535897932;

//крок дискретизації

double IntervalWidth = 0.00002;

//інтервал від

double a = PI;

//вивід на екран значення а

printf ("a = %.16f\n", a);

//інтервал до

double b =(PI)/2;

//вивід на екран значення b

printf ("b = %.16f\n", b);

//кількість інтервалів

int numbIntervals = (int)((b-a)/IntervalWidth);

//висота інтервалу

double IntervalHeight = 0.0;

//координата поточної точки на осі х

double x = 0.0;

//поточний інтервал

int Interval = 0;

//локальна сума на одному комп’ютері

double summaLocal = 0.0;

//локальна сума на всіх комп’ютерах

double summaGlobal;

//номер процесу

int ProcNumb;

//ранг процесу

int ProcRank;

//ім’я процесу

char processor_name[MPI_MAX_PROCESSOR_NAME];

//довжина імені процесу

int namelen;

//час початку і кінця розрахунку процесу

double t1, t2;

//ініціалізація MPI

MPI_Init(&argc,&argv);

//кількість компютерів у кластері

MPI_Comm_size(MPI_COMM_WORLD,&ProcNumb);

//номер процесу

MPI_Comm_rank(MPI_COMM_WORLD,&ProcRank);

//імя процесу у кластері

MPI_Get_processor_name(processor_name,&namelen);

printf ("Process %d of %d running on %s\n", ProcRank,

ProcNumb);

if ( ProcRank == 0 )

{

printf ("numbIntervals = %i\n", numbIntervals);

t1 = MPI_Wtime();

}

//цикл від першого до останнього інтервалу з кроком рівним числу процесорів

for ( Interval=1+ProcRank; Interval <= numbIntervals; Interval

+=ProcNumb )

{

x = a + (IntervalWidth * ((double)Interval-0.5));

IntervalHeight += (sin(x)+cos(x));

}

summaLocal = IntervalWidth * IntervalHeight;

printf ("summaLocal is approximately %.16f\n", summaLocal);

MPI_Reduce (&summaLocal, &summaGlobal, 1, MPI_DOUBLE,

MPI_SUM,0,MPI_COMM_WORLD );

if ( ProcRank == 0 )

{

t2 = MPI_Wtime();

printf ("Integral is approximately %.16f\n", summaGlobal);

printf ("Time is %f seconds \n", t2-t1);

}

//фіналізація MPI

MPI_Finalize();

return 0;

}

Значення інтегралу дорівнює 1.8749238809545756

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]