Программное обеспечение для решения дифференциальных уравнений

Курсовая работа по предмету «Программирование»
Информация о работе
  • Тема: Программное обеспечение для решения дифференциальных уравнений
  • Количество скачиваний: 28
  • Тип: Курсовая работа
  • Предмет: Программирование
  • Количество страниц: 40
  • Язык работы: Русский язык
  • Дата загрузки: 2014-12-24 16:50:41
  • Размер файла: 757.72 кб
Помогла работа? Поделись ссылкой
Информация о документе

Документ предоставляется как есть, мы не несем ответственности, за правильность представленной в нём информации. Используя информацию для подготовки своей работы необходимо помнить, что текст работы может быть устаревшим, работа может не пройти проверку на заимствования.

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

Анотація

Данна курсова робота спрямована на дослідження рішення диференціальних рівнянь 2-го порядку.
Робота викладена на 41 аркушах, містить 12 рисунків, 4 лістинги та один додаток. Було розроблено програмне забезпечення для вирішення задачі мовою Java.

Аннотация
Данная курсовая работа направлена на решение дифференциальных уравнений 2-го порядка.
Работа изложена на 41 листах, содержит 12 рисунков, 4 листинга и одно приложение. Было разработано программное обеспечение для решения задачи на языке Java.

Annotation
This course work is aimed at studying on finding a solution to a system of differential equations of second order.
Work is presented on 41 sheets, contains 12 figures, 4 listing and one appendix. Software was developed to solve the problem in Java. 
Содержание
Введение 4
1 Постановка задачи 5
2 Анализ решения СЛАУ методом Гауса 5
2.1 Прямой ход алгоритма Гаусса 6
2.2 Обратный ход алгоритма Гаусса 8
3 Построение параллельного алгоритма решения методом Гаусса 9
3.1 Определение подзадач 9
3.2 Выделение информационных зависимостей 9
3.3 Масштабирование и распределение подзадач по процессорам 10
4 Построение алгоритма работы программы в виде блок-схем 10
5 Реализация алгоритмов прямого и обратного метода Гаусса 18
6 Обработка результатов выполнения программы 18
Вывод 27
Приложение А – Текст программы 28


Введение
Дифференциальное уравнение — уравнение, связывающее значе-ние производной функции с самой функцией, значениями независимой перемен-ной, числами (параметрами). Порядок входящих в уравнение производных может быть различен (формально он ничем не ограничен). Производные, функции, независимые переменные и параметры могут входить в уравнение в различных комбинациях или все, кроме хотя бы одной производной, отсутствовать вовсе. Дифференциальное уравнение порядка выше первого можно преобразовать в систему уравнений первого порядка, в которой число уравнений равно порядку исходного уравнения.
Дифференциальные уравнения возникают при решении ряда прикладных задач, описываемыхдифференциальными, интегральными или системами нелинейных (трансцендентных) уравнений. Онимогут появляться также в задачах математического программирования, статистической обработкиданных, аппроксимации функций, при дискретизации краевых дифференциальных задач методомконечных разностей или методом конечных элементов и др.С распространением многопроцессорных вычислительных систем появилась возможность адаптации точных алгоритмов решения дифференциальных уравнений к данной архитектуре. Работы в этом направлении ведутся продолжительное время, разработано большое количество алгоритмов для вычислительных систем различной архитектуры. Поэтому целью данной лабораторной работы является разработка парал-лельной программы, которая выполняет решение дифференциальных уравнений.



1 Постановка задачи
Написать программное обеспечение для решения дифференциальных уравнений второго порядка.
Программа должна поддерживать:
1. Генерацию дифференциальных уравнений второго порядка, на основе введенных пользователем данных;
2. Сохранение сгенерированного дифференциального уравнения второго порядка во время испытаний.
. 3. Решение системдифференциального уравнения второго порядка;
4. Возможность замерять время выполнения, как решения дифференци-ального уравнения второго порядка.
5. Вывод результатов решения дифференциального уравнения второго порядка на экран.

2 Анализ решениядифференциальных уравнений второго порядка
Линейное дифференциальное уравнение второго порядка — обыкновен-ное уравнение вида

где x(t) - искомая функция, a p(t), q(t).и r(t) - заданные функции, непрерывные на некотором промежутке (a, b). Для любых действительных чи-сел существует единственное решение x(t).уравнения (1) с на-чальными условиями причем x(t).определено для всех
Если х 1(t).и x2(t) - линейно независимые решения соответствующего однородного уравнения

a x0(t) - частное решение неоднородного уравнения (1), то общее реше-ние уравнения (1) дается формулой

где C1 и С 2 - произвольные постоянные. Если известно одно ненулевое реше-ние х 1(t).уравнения (2), то второе его решениеx2(t), линейно ненависимое с x1(t), дается формулой

Если известны линейно независимые решения x1(t).и x2(t) уравнения (2), то частное решение x0(t).уравнения (1) можно найти методом произвольных постоянных вариации.
При изучении уравнения (2) большую роль играют его преобразования в уравнения других типов. Так, напр., заменой уравнение (2) приводится к нормальной системе линейных уравнений 2-го порядка; заменой искомой функции

уравнение (2) приводится к уравнению
где

наз. инвариантом уравнения (2); заменой уравнение (2) сводится к Риккати уравнению

После умножения на

уравнение (2) принимает самосопряженный вид

Уравнение (2) интегрируется в квадратурах лишь в отдельных случаях. Решения наиболее важных частных типов неинтегрируемых уравнений (2) входят в число специальных функций.
Справедлива теорема Штурма о разделении нулей: если x1(t), x2(t) - линейно независимые решения уравнения (2) и t1<t2 - соседние нули решения х 1(1), то на интервале (t1, t2) имеется в точности один нуль решения х 2(t).
Пусть в уравнениях

функции q1 и q2 непрерывны и q2(t)>q1(t).на промежутке (a, b). Справедлива теорема сравнения: если t1<t2 - последовательные нули ненулевого решения первого уравнения (3), то на интервале (t1, t2) имеется хотя бы один нуль любого решения второго уравнения (3).
Линейная краевая задача для уравнения (1) ставится следующим образом: найти решение x(t).уравнения (1), удовлетворяющее краевым условиям

где.

- заданные постоянные и

Штурма - Лиувилля задача для уравнения

где q(t)>0 и непрерывна на [ а, b], ставится следующим образом: найти те значения параметра при к-рых это уравнение имеет ненулевое решение x(t), удовлетворяющее краевым условиям х(а)=х(b)=0. Эти значения наз. собственными значениями, а соответствующие решения - собственными функциями.
Если в уравнении (2) t и x комплексны, а функции p(t).и q(t).голоморфны в точке t0, то для любых чисел существует единственное голоморфное в точке t0 комплексное решение x(t).уравнения (2), удовлетворяющее начальным условиям Если в уравнении

функции р(t).и q(t).голоморфны в точке t0, причем хотя бы одно из чи-сел отлично от нуля, то точка t0 наз. регулярной особой точкой для уравнения (4). В окрестности такой точки решение уравнения (4) отыскивается в виде обобщенного степенного ряда

здесь находится из определяющего уравнения

где p0=p(t0) и q0=q(t0). Пусть корни этого уравнения действительны. Ес-ли не является целым, то существуют два линейно независимых решения вида (5): при и при Если - целое, то, вообще говоря, существует лишь одно решение в виде (5) при второе решение имеет более сложный вид (см. [3]-[6]).


2.1 Однородное дифференциальное уравнение второго порядка

В теории и практике различают два типа таких уравнений – однородное уравнение инеоднородное уравнение.
Однородное ДУ второго порядка с постоянными коэффициентами имеет следующий вид:
, где и – константы (числа), а в правой части – строго ноль.
Неоднородное ДУ второго порядка с постоянными коэффициентами имеет вид:
, где и – константы, а – функция, зависящая только от «икс». В простейшем случае функция может быть числом, отличным от нуля.
Какая мысль приходит в голову после беглого взгляда? Неоднородное уравнение кажется сложнее. На этот раз первое впечатление не подводит!
Кроме того, чтобы научиться решать неоднородные уравне-ния необходимо уметь решать однородные уравнения. По этой причине сначала рассмотрим алгоритм решения линейного однородного уравнения второго порядка:

Для того чтобы решить данное ДУ, нужно составить так называе-мое характеристическое уравнение:

По какому принципу составлено характеристическое уравнение, отчётливо видно:
вместо второй производной записываем ;
вместо первой производной записываем просто «лямбду»;
вместо функции ничего не записываем.
– это обычное квадратное уравнение, которое предстоит решить.
Существуют три варианта развития событий. Они доказаны в курсе математического анализа, и на практике мы будем использовать готовые формулы.
Характеристическое уравнение имеет два различных действительных корня
Если характеристическое уравнение имеет два различных действительных корня , (т.е., если дискриминант ), то общее решение однородного уравнения выглядит так:
, где – константы.
В случае если один из корней равен нулю, решение очевидным образом упрощается; пусть, например, , тогда общее реше-ние: .




Рисунок 1 - Итерация прямого хода решения ДУ

2.2 Неоднородное дифференциальное уравнение второго порядка


Алгоритм решения неоднородного ДУ следующий:
1) Сначала нужно найти общее решение соответствующего однородного уравнения. Взять уравнение , откинуть правую часть: – и найти общее решение.Общее решение однородного уравнения я привык обозначать буквой .
2) Необходимо найти какое-либо частное решение неоднородного уравнения. Сделать это можно так называемым способом подбора частного решения с применением метода неопределенных коэффициентов.
3) На третьем этапе надо составить общее решение неоднородного уравнения. .
Если изначально в условии сформулирована задача Коши (найти частное решение, удовлетворяющее заданным начальным условиям), то добавляется четвёртый этап:
4) Нахождение частного решения, удовлетворяющего заданным началь-ным условиям. Порядок нахождения частного решение для уравнения второго порядка уже немного рассмотрен на уроке Однородные уравнения второго и высших порядков. В случае с неоднородным диффуром принципы нахождения частного решения сохраняются.

3 Построение параллельного алгоритма решения методом Гаусса
3.1 Определение подзадач
При внимательном рассмотрении метода Гаусса можно заметить, что все вычисления сводятся к однотипным вычислительным операциям над строками матрицы коэффициентов системы линейных уравнений. Как результат, в основу параллельной реализации алгоритма Гаусса может быть положен принцип распараллеливания по данным. В качестве базовой подзадачи можно принять тогда все вычисления, связанные с обработкой одной строки матрицы A и соответствующего элемента вектора b.

3.2 Выделение информационных зависимостей
Для выполнения прямого хода метода Гаусса необходимо осуществить (n-1) итерацию поисключению неизвестных для преобразования матрицы коэффициентов A к верхнему треугольномувиду.
Выполнение итерации i, 0≤ i<n-1, прямого хода метода Гаусса включает ряд последовательныхдействий. Прежде всего, в самом начале итерации необходимо выбрать ведущую строку, которая будет равняться номеру итерации.
Далее строки матрицы нужно распределить между потоками. Для того, чтобы каждому потоку досталось примерно одинаковое количество работы, строки будут распределяться поочередно. Например, для матрицы 4 х 4, первый поток будет обрабатывать 1 и 3 строки, а 2-ой поток – 2 и 4 строки.
Для продолжения вычислений ведущая подзадача (та которая обрабатывает ведущую строку) должна разослать свою строку матрицы A исоответствующий элемент вектора b всем остальным подзадачам с номерами k, k>i. Получив ведущуюстроку, подзадачи выполняют вычитание строк, обеспечивая тем самым исключение соответствующейнеизвестной xi.
При выполнении обратного хода метода Гаусса подзадачи выполняют необходимые вычислениядля нахождения значения неизвестных. Как только какая-либо подзадача i, 0≤i<n-1, определяетзначение своей переменной xi, это значение должно быть разослано всем подзадачам с номерами k, k<i.Далее подзадачи подставляют полученное значение новой неизвестной и выполняют корректировкузначений для элементов вектора b.Распределение строки матрицы между подзадачами определяется так же как и в прямом методе Гаусса.

4. Построение алгоритма работы программы в виде блок-схем
Во время разработки алгоритма программы были построены блок-схемы работы программы в целом и отдельных ее частей. Блок-схемы изображены на рисунках 2 – 3.


Рисунок 4 - Блок-схема работы программы


Рисунок 5 - Блок-схема генерации исходной матрицы и вектора


Рисунок 6 - Блок-схема решения ДУ

Рисунок 7 - Блок-схема прямого хода решения ДУ


Рисунок 8 - Блок-схема обратного хода решения ДУ



Рисунок 10 - Блок-схема общегорешения ДУ

Рисунок 11 - Блок-схема блока вычислений потока прямого метода Гаусса

Рисунок 12 - Блок-схема обратного хода Гаусса с многопоточностью

Рисунок 13 - Блок-схема блока вычислений потока обратного хода Гаусса



4 Реализация алгоритмов прямого и обратного метода Гаусса

Представленный ранее алгоритм был реализован на языке программирования Java. Текст программы представлено в приложении А. Интерфейс программы представлен на рисунке 14.


Рисунок 15 - Интерфейс программы


5 Обработка результатов выполнения программы

Проверим работу программы на матрице 4 х 4. Введем размерность матрицы 4 и нажмем кнопку «Сгенерировать матрицу» и в результат представлен в листинге 1:

Листинг 1. Сгенерированная матрица и вектор.

Initial matrix:
5,03 3,21 5,10 1,47
5,81 4,69 6,82 3,36
8,98 9,77 6,89 6,04
8,13 2,71 1,63 1,81


Initial vector:
3,87 6,46 3,39 6,32
Сначала найдем решение ДУ без использования многопоточности (листинг 2).



Листинг 2. Результат нахождения решения ДУ матрицы 4х4 без использования многопоточности

Начало выполнения прямого хода Гаусса

Начало выполнения прямого хода Гаусса

Iteration 0:
-----------------------------------------------------------

Matrix of iteration 0:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 4,04 -2,22 3,43
0,00 -2,47 -6,61 -0,56


Result vector of iteration 0:
3,87 2,00 -3,51 0,08

Iteration 1:
-----------------------------------------------------------

Matrix of iteration 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 -4,26 3,62


Result vector of iteration 1:
3,87 2,00 -11,71 5,10

Iteration 2:
-----------------------------------------------------------

Matrix of iteration 2:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Result vector of iteration 2:
3,87 2,00 -11,71 13,34

Iteration 3:
-----------------------------------------------------------

Matrix of iteration 3:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Result vector of iteration 3:
3,87 2,00 -11,71 13,34

Начало выполнения обратного хода Гаусса

Iteration 3:
-----------------------------------------------------------

Matrix of iteration 3:
5,03 3,21 5,10 0,00
0,00 0,99 0,94 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 3:
0,00 0,00 0,00 2,22

Iteration 2:
-----------------------------------------------------------

Matrix of iteration 2:
5,03 3,21 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 2:
0,00 0,00 0,69 2,22

Iteration 1:
-----------------------------------------------------------

Matrix of iteration 1:
5,03 0,00 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 1:
0,00 -2,38 0,69 2,22

Iteration 0:
-----------------------------------------------------------

Matrix of iteration 0:
5,03 0,00 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 0:
0,94 -2,38 0,69 2,22

Время выполнения прямого хода Гаусса:
8

Время выполнения обратного хода Гаусса:
8

General work time:
16

Result:
0,94 -2,38 0,69 2,22

Теперь найдем решение с использованием 2 потоков на процессоре intelcorei3, 2 ядра с технологией виртуализации каждого. Результат представлен в листинге 3.

Листинг 3. Результат нахождения решения СЛАУ матрицы 4х4 с использованием 2 потоков

Начало выполнения прямого хода Гаусса

Iteration 0:
-----------------------------------------------------------

Matrix of iteration 0 by thread 0:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 4,04 -2,22 3,43
0,00 -2,47 -6,61 -0,56


Vector of iteration 0 by thread 0:
3,87 2,00 -3,51 0,08

Matrix of iteration 0 by thread 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 4,04 -2,22 3,43
0,00 -2,47 -6,61 -0,56


Vector of iteration 0 by thread 1:
3,87 2,00 -3,51 0,08

Iteration 1:
-----------------------------------------------------------

Matrix of iteration 1 by thread 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 4,04 -2,22 3,43
0,00 0,00 -4,26 3,62


Vector of iteration 1 by thread 1:
3,87 2,00 -3,51 5,10

Matrix of iteration 1 by thread 0:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 -4,26 3,62


Vector of iteration 1 by thread 0:
3,87 2,00 -11,71 5,10

Iteration 2:
-----------------------------------------------------------

Matrix of iteration 2 by thread 0:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 -4,26 3,62


Vector of iteration 2 by thread 0:
3,87 2,00 -11,71 5,10

Matrix of iteration 2 by thread 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Vector of iteration 2 by thread 1:
3,87 2,00 -11,71 13,34

Iteration 3:
-----------------------------------------------------------

Matrix of iteration 3 by thread 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Vector of iteration 3 by thread 1:
3,87 2,00 -11,71 13,34

Matrix of iteration 3 by thread 0:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 1,66
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Vector of iteration 3 by thread 0:
3,87 2,00 -11,71 13,34

Начало выполнения обратного хода Гаусса

Iteration 3:
-----------------------------------------------------------

Matrix of iteration 3 by thread 1:
5,03 3,21 5,10 1,47
0,00 0,99 0,94 0,00
0,00 0,00 -6,06 -3,40
0,00 0,00 0,00 6,00


Result vector of iteration 3 by thread 1:
-1,00 -1,00 -1,00 2,22

Matrix of iteration 3 by thread 0:
5,03 3,21 5,10 0,00
0,00 0,99 0,94 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 3 by thread 0:
-1,00 -1,00 -1,00 2,22

Iteration 2:
-----------------------------------------------------------

Matrix of iteration 2 by thread 0:
5,03 3,21 0,00 0,00
0,00 0,99 0,94 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 2 by thread 0:
-1,00 -1,00 0,69 2,22

Matrix of iteration 2 by thread 1:
5,03 3,21 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 2 by thread 1:
-1,00 -1,00 0,69 2,22

Iteration 1:
-----------------------------------------------------------

Matrix of iteration 1 by thread 1:
5,03 3,21 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 1 by thread 1:
-1,00 -2,38 0,69 2,22

Matrix of iteration 1 by thread 0:
5,03 0,00 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 1 by thread 0:
-1,00 -2,38 0,69 2,22

Iteration 0:
-----------------------------------------------------------

Matrix of iteration 0 by thread 0:
5,03 0,00 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 0 by thread 0:
0,94 -2,38 0,69 2,22

Matrix of iteration 0 by thread 1:
5,03 0,00 0,00 0,00
0,00 0,99 0,00 0,00
0,00 0,00 -6,06 0,00
0,00 0,00 0,00 6,00


Result vector of iteration 0 by thread 1:
0,94 -2,38 0,69 2,22

Время выполнения прямого хода Гаусса:
17

Время выполнения обратного хода Гаусса:
18

General work time:
36

Threads count:
2

Result:
0,94 -2,38 0,69 2,22


Из результатов видно, что оба способа решения задачи работают, оба дали верный результат. Так же можно пронаблюдать действия программы над матрицами и векторами на каждой итерации.
Для того, чтобы оценить возможности многопоточного и однопоточного решения СЛАУ, решим систему линейных уравнений 2000 х 2000 и сравним время выполнения.

Листинг 4. Сравнение времени нахождения решения СЛАУ 2000 х 2000 с использованием многопоточности и без.

Решение СЛАУ 2000х2000 одним потоком

Время выполнения прямого хода Гаусса:
5150

Время выполнения обратного хода Гаусса:
79

General work time:
5343

Решение СЛАУ 2000х2000 с использованием 2 потоков

Время выполнения прямого хода Гаусса:
4965

Время выполнения обратного хода Гаусса:
169

General work time:
5180

Threads count:
2



Решение СЛАУ 2000х2000 с использованием 4 потоков

Время выполнения прямого хода Гаусса:
4821

Время выполнения обратного хода Гаусса:
116

General work time:
4964

Threads count:
4

Решение СЛАУ 2000х2000 с использованием 8 потоков

Время выполнения прямого хода Гаусса:
4742

Время выполнения обратного хода Гаусса:
111

General work time:
4872

Threads count:
8

Полученные результаты показали, что применение многопоточности практически не влияет на скорость вычислений. Это может быть связано с нюансами работы интерпретатора виртуальной машины Java или из-за постоянной синхронизации потоков между собой и работой с одними и теми объектами одновременно.



Вывод

Во время выполнения курсовой работы было исследовано влияние использования многопотоковой обработки данных для решения систем линейных уравнений методом Гаусса. Был построен и реализован алгоритм решения СЛАУ с использованием многопоточности, а так же были выполнены с его помощью расчеты и их анализ. Результат показал, что применение потоков практически не повлияло на скорость вычислений.


Приложение А – Текст программы

Текст файла MainForm.java

package nuos.oops.kr;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;

import org.eclipse.wb.swing.FocusTraversalOnArray;

publicclassMainFormextends JFrame {

private JPanel contentPane;
private JTextField txfSize;
private JTextArea txtLog;

private SystemOfLinearEquation systemOfLinearEquation;


private JCheckBox chbPrintOptionalInfo;
private JSpinner spnThreads;
private JSpinner spnRangElementsFrom;
private JSpinner spnRangElementsTo;

publicstaticvoid main(String[] args) {
EventQueue.invokeLater(new Runnable() {
publicvoid run() {
try {
MainForm frame = new MainForm();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public MainForm() {
setTitle("OOPS");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 641, 325);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);

final JButton btnCalculation = new JButton("Посчитать");
btnCalculation.setEnabled(false);
btnCalculation.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent arg0) {
btnCalculation();
}
});

JButton button_1 = new JButton("u0412u044Bu0445u043Eu0434");
button_1.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent e) {
System.exit(0);
}
});

JButton btnGenerateMatrix = new JBut-ton("u0421u0433u0435u043Du0435u0440u0438u0440u043Eu0432u0430u0442u044C u043Cu0430u0442u0440u0438u0446u0443");
btnGenerateMatrix.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent e) {
int size = Integer.valueOf(txfSize.getText());
int rangeFrom = Integ-er.parseInt(String.valueOf(spnRangElementsFrom.getValue()));
int rangeTo = Integ-er.parseInt(String.valueOf(spnRangElementsTo.getValue()));
if (systemOfLinearEquation == null){
systemOfLinearEquation = new SystemOfLinearEquation();
}
systemOfLinearEquation.generateMatrix(size, rangeFrom, rangeTo);
Log.setMessage(Log.OTHER, "", "Матрицасгенерирована");
Log.setMessage(Log.OPTIONAL_INFORMATION, "Initial matrix", sys-temOfLinearEquation.getInitialMatrix());
Log.setMessage(Log.OPTIONAL_INFORMATION, "Initial vector", sys-temOfLinearEquation.getInitialVector());
printLog();
btnCalculation.setEnabled(true);
}
});

txfSize = new JTextField();
txfSize.setColumns(10);

JLabel lblNXM = new JLa-bel("u0420u0430u0437u043Cu0435u0440u043Du043Eu0441u0442u044C u043Au0432. u043Cu0430u0442u0440u0438u0446u044B:");

chbPrintOptionalInfo = new JCheck-Box("u041Fu0435u0447u0430u0442u0430u0442u044C u0434u043Eu043F. u0438u043Du0444u043Eu0440u043Cu0430u0446u0438u044E?");
chbPrintOptionalInfo.addActionListener(new ActionListener() {
publicvoid actionPerformed(ActionEvent event) {
if (!chbPrintOptionalInfo.isSelected()){
Log.block_log(Log.OPTIONAL_INFORMATION);
} else {
Log.unblock_log(Log.OPTIONAL_INFORMATION);
}
}
});
chbPrintOptionalInfo.setSelected(true);

spnThreads = new JSpinner();

JLabel label = new JLa-bel("u041Au043Eu043Bu0438u0447u0435u0441u0442u0432u043E u043Fu043Eu0442u043Eu043Au043Eu0432:");

txtLog = new JTextArea();
txtLog.setFont(new Font("Courier New", Font.PLAIN, 11));

JScrollPane scrollPane = new JScrollPane(txtLog);

JLabel label_1 = new JLabel("u0414u0438u0430u043Fu0430u0437u043Eu043D u0437u043Du0430u0447u0435u043Du0438u0439 u044Du043Bu0435u043Cu043Du0442u043Eu0432 u043Cu0430u0442u0440u0438u0446u044B:");

spnRangElementsFrom = new JSpinner();

spnRangElementsTo = new JSpinner();
spnRangElementsTo.setModel(new SpinnerNumberModel(new Integer(10), null, null, new Integer(1)));

JLabel label_2 = new JLabel("u043Eu0442");

JLabel label_3 = new JLabel("u0434u043E");
GroupLayout gl_contentPane = new GroupLayout(contentPane);
gl_contentPane.setHorizontalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(10)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(lblNXM)
.addGap(18)
.addComponent(txfSize, Group-Layout.PREFERRED_SIZE, 61, GroupLayout.PREFERRED_SIZE))
.addComponent(label_1)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(label_2)
.addGap(10)
.addComponent(spnRangElementsFrom, Group-Layout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE)
.addGap(45)
.addComponent(label_3)
.addGap(16)
.addComponent(spnRangElementsTo, Group-Layout.PREFERRED_SIZE, 63, GroupLayout.PREFERRED_SIZE))
.addComponent(btnGenerateMatrix, Group-Layout.PREFERRED_SIZE, 231, GroupLayout.PREFERRED_SIZE)
.addComponent(chbPrintOptionalInfo, Group-Layout.PREFERRED_SIZE, 231, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_contentPane.createSequentialGroup()
.addComponent(label, Group-Layout.PREFERRED_SIZE, 149, GroupLayout.PREFERRED_SIZE)
.addGap(6)
.addComponent(spnThreads, Group-Layout.PREFERRED_SIZE, 76, GroupLayout.PREFERRED_SIZE))
.addComponent(btnCalculation, Group-Layout.PREFERRED_SIZE, 231, GroupLayout.PREFERRED_SIZE)
.addComponent(button_1, GroupLayout.PREFERRED_SIZE, 231, GroupLayout.PREFERRED_SIZE))
.addGap(7)
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE)
.addGap(8))
);
gl_contentPane.setVerticalGroup(
gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(9)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(2)
.addComponent(lblNXM))
.addComponent(txfSize, Group-Layout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(9)
.addComponent(label_1)
.addGap(6)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(3)
.addComponent(label_2))
.addComponent(spnRangElementsFrom, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(3)
.addComponent(label_3))
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(1)
.addComponent(spnRangElementsTo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
.addGap(5)
.addComponent(btnGenerateMatrix)
.addGap(43)
.addComponent(chbPrintOptionalInfo)
.addGap(8)
.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
.addGroup(gl_contentPane.createSequentialGroup()
.addGap(2)
.addComponent(label))
.addComponent(spnThreads, Group-Layout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGap(5)
.addComponent(btnCalculation, Group-Layout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)
.addGap(7)
.addComponent(button_1))
.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 261, Short.MAX_VALUE))
.addGap(7))
);
contentPane.setLayout(gl_contentPane);
contentPane.setFocusTraversalPolicy(new FocusTraversalOnArray(new Compo-nent[]{btnCalculation, button_1, btnGenerateMatrix, txfSize, lblNXM, chbPrintOptionalInfo, spnThreads, label}));


}

privatevoid btnCalculation(){

long startTime = System.currentTimeMillis();
double[] result;

if (Integer.valueOf((String.valueOf(spnThreads.getValue()))) <= 1){
result = systemOfLinearEquation.calculationBySerialGauss();
} else {
int threads = Integer.parseInt(spnThreads.getValue().toString());
Log.setMessage(Log.OTHER, "Threads count", String.valueOf(threads));
result =systemOfLinearEquation.calculationByParalelGauss(threads);
}
Log.setMessage(Log.TIME, "General work time", String.valueOf(System.currentTimeMillis() - startTime));
Log.setMessage(Log.OTHER, "Result", systemOfLinearEquation.printLastResult());

printLog();
}

publicvoid printLog(){
String log = Log.getAllMessages();
txtLog.append(log);
Log.clearLog();
}
}


Текстфайла SystemOfLinearEquation.java:

package nuos.oops.kr;

importjava.lang.reflect.Array;


publicclass SystemOfLinearEquation {

privatedouble[][] matrix;
privatedouble[][] initialMatrix;
privatedouble[] vector;
privatedouble[] initialVector;
privatedouble[] lastResult;

private SerialGauss serialGauss;
private ParalelGauss paralelGauss;

publicvoid generateMatrix(int size, int rangeFrom, int rangeTo) {
initialMatrix = newdouble[size][size];
initialVector = newdouble[size];
for (int i = 0; i <initialMatrix.length; i++) {
initialVector[i] = Math.random() * (Math.abs(Math.abs(rangeTo) - Math.abs(rangeFrom))) + rangeFrom;
for (int j = 0; j <initialMatrix[0].length; j++) {
initialMatrix[i][j] = Math.random() * (Math.abs(Math.abs(rangeTo) - Math.abs(rangeFrom))) + rangeFrom;
}
}
}

publicdouble[][] getMatrix() {
returnmatrix;
}

publicdouble[][] getInitialMatrix() {
returninitialMatrix;
}

publicdouble [] getInitialVector(){
returninitialVector;
}

publicdouble[] getVector() {
returnvector;
}

publicstatic String printVector(double[] vector){
String str = "";
String value = "";
if (vector == null){
return"Vector is not initial";
}
for (int i = 0; i < vector.length; i++) {
str += String.format("%10.2f", vector[i]);
}
return str;
}

public String printCurrentVector(){
returnprintVector(vector);
}

public String printInitialVector(){
returnprintVector(initialVector);
}

public String printLastResult(){
returnprintVector(lastResult);
}

publicstatic String printMatrix(double[][] matrix){
String str = "";
if (matrix == null){
return"Matrix is not initial";
}
for (int i = 0; i < matrix.length; i++) {
str += printVector(matrix[i]) + "
";
}
return str;
}

public String printCurrentMatrix(){
returnprintMatrix(matrix);
}

public String printInitialMatrix(){
returnprintMatrix(initialMatrix);
}

publicstaticdouble[][] cloneMatrix(double[][] matrix){
double[][] clone = newdouble[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
clone[i][j] = matrix[i][j];
}
}
return clone;
}

publicstaticdouble[] cloneVector(double[] vector){
double[] clone = newdouble[vector.length];
for (int i = 0; i < vector.length; i++) {
clone[i] = vector[i];
}
return clone;
}

publicdouble[] calculationBySerialGauss(){
matrix = cloneMatrix(initialMatrix);
vector = cloneVector(initialVector);

serialGauss = new SerialGauss();
lastResult = serialGauss.gaussCalculation(matrix, vector);
returnlastResult;
}

publicdouble[] calculationByParalelGauss(int countThreads){
matrix = cloneMatrix(initialMatrix);
vector = cloneVector(initialVector);

paralelGauss = new ParalelGauss(countThreads);
lastResult = paralelGauss.gaussCalculation(matrix, vector);
returnlastResult;
}

}

Текстфайла SerialGauss.java:

package nuos.oops.kr;


publicclass SerialGauss {

privateint[] pivotPosition;
privateint[] pivotIteration;

privatevoid columnElimination(double[][] matrix, double[] vector, int pivot, int iter) {
double pivotValue, pivotFactor;
pivotValue = matrix[pivot][iter];
for (int i = 0; i < matrix.length; i++) {
if (pivotIteration[i] == -1) {
pivotFactor = matrix[i][iter] / pivotValue;
for (intj = iter; j< matrix.length; j++) {
matrix[i][j] -= pivotFactor * matrix[pivot][j];
}
vector[i] -= pivotFactor * vector[pivot];
}
}
}

privatevoid gaussianElimination(double[][] matrix, double[] vector){
int pivotRow;

for (int i = 0; i < matrix.length; i++) {
pivotRow = i; //getPivotRow(matrix, i);
pivotPosition[i] = pivotRow;
pivotIteration[pivotRow] = i;
columnElimination(matrix, vector, pivotRow, i);
Log.setSeparate(Log.OPTIONAL_INFORMATION, "Iteration " + String.valueOf(i));
Log.setMessage(Log.OPTIONAL_INFORMATION,
"Matrix of iteration " + i, matrix);
Log.setMessage(Log.OPTIONAL_INFORMATION,
"Result vector of iteration " + i, vector);
}
}

privatedouble[] backSubstitution(double[][] matrix, double[] vector) {
double[] result = newdouble[matrix.length];
for (int i = pivotPosition.length - 1; i >= 0; i--) {
result[i] = vector[pivotPosition[i]] / matrix[pivotPosition[i]][i];
for (int j = 0; j < i; j++) {
vector[j] -= matrix[pivotPosition[j]][i] * result[i];
matrix[pivotPosition[j]][i] = 0;
}
Log.setSeparate(Log.OPTIONAL_INFORMATION, "Iteration " + String.valueOf(i));
Log.setMessage(Log.OPTIONAL_INFORMATION,
"Matrix of iteration " + i, matrix);
Log.setMessage(Log.OPTIONAL_INFORMATION,
"Result vector of iteration " + i, result);
}
return result;
}

publicdouble[] gaussCalculation(double[][] matrix, double[] vector){
pivotPosition = newint[matrix.length];
pivotIteration = newint[matrix.length];
for (int i = 0; i <pivotIteration.length; i++) {
pivotIteration[i] = -1;
}

long startTime = System.currentTimeMillis();
Log.setMessage(Log.OPTIONAL_INFORMATION,
"", "Начало выполнения прямого хода Гаусса");
gaussianElimination(matrix, vector);
Log.setMessage(Log.TIME, "Время выполнения прямого хода Гаусса", String.valueOf(System.currentTimeMillis() - startTime));

startTime = System.currentTimeMillis();
Log.setMessage(Log.OPTIONAL_INFORMATION,
"", "Начало выполнения обратного хода Гаусса");
double[] result = backSubstitution(matrix, vector);
Log.setMessage(Log.TIME, "ВремявыполненияобратногоходаГаусса", String.valueOf(System.currentTimeMillis() - startTime));
return result;
}

}


Текстфайла ParalelGauss.java:

package nuos.oops.kr;

importjava.lang.management.ManagementFactory;
import java.util.Arrays;

publicclass ParalelGauss {

privatevolatileint[] pivotPosition;
privatevolatileint[] pivotIteration;
privateintthreadsFinished = 0;

privatedouble[] result;

privateintcountThreads;
privatevolatileintfinishedThreads = 0;

private ParalelGauss context;

public ParalelGauss(int countThreads) {
this.countThreads = countThreads;
context = this;
}

privatevoid partColumnElimination(double[][] matrix, double[] vector,
int thread) {
double pivotValue, pivotFactor;
int iteration = -1;
finalint count_rows = matrix.length / countThreads;

while (iteration != matrix.length - 1) {
synchronized (context) {
try {
if (++finishedThreads != countThreads) {
context.wait();
} else {
finishedThreads = 0;
context.notifyAll();
Log.setSeparate(Log.OPTIONAL_INFORMATION, "Iteration "
+ String.valueOf(iteration + 1));
}
} catch (InterruptedException e) {
}
}
iteration++;
pivotIteration[iteration] = iteration;
pivotValue = matrix[iteration][iteration];
int k = 0;
for (int i = 0; i < count_rows; i++) {
k = thread + countThreads * i;
if (pivotIteration[k] == -1) {
pivotFactor = matrix[k][iteration] / pivotValue;
for (int j = iteration; j < matrix.length; j++) {
matrix[k][j] -= pivotFactor * matrix[iteration][j];
}
vector[k] -= pivotFactor * vector[iteration];
}
}

synchronized (context) {
Log.setMessage(Log.OPTIONAL_INFORMATION, "Matrix of iteration "
+ iteration + " by thread " + thread, matrix);
Log.setMessage(Log.OPTIONAL_INFORMATION, "Vector of iteration "
+ iteration + " by thread " + thread, vector);
}
}
}

privatevoid distpibutionGaussianEliminationThreads(
finaldouble[][] matrix, finaldouble[] vector) {
for (int i = 0; i <countThreads; i++) {
finalint thread = i;
new Thread(new Runnable() {
@Override
publicvoid run() {
partColumnElimination(matrix, vector, thread);
synchronized (context) {
threadsFinished++;
if (threadsFinished == countThreads) {
context.notifyAll();
}
}
}

}).start();
}
}

privatevoid gaussianElimination(double[][] matrix, double[] vector) {
distpibutionGaussianEliminationThreads(matrix, vector);
for (int i = 0; i < matrix.length; i++) {
finalint pivotRow = i;
pivotPosition[i] = pivotRow;
}
synchronized (context) {
try {
while (threadsFinished != countThreads) {
context.wait();
}
} catch (InterruptedException e) {
}
}
}

privatedouble[] backSubstitution(double[][] matrix, double[] vector) {
result = newdouble[matrix.length];
Arrays.fill(result, -1);
threadsFinished = 0;
distpibutionBackSubstitutionThreads(matrix, vector);
synchronized (context) {
try {
while (threadsFinished != countThreads) {
context.wait();
}
} catch (InterruptedException e) {
}
}
returnresult;
}

privatevoid distpibutionBackSubstitutionThreads(finaldouble[][] matrix,
finaldouble[] vector) {
for (int i = 0; i <countThreads; i++) {
finalint thread = i;
new Thread(new Runnable() {
@Override
publicvoid run() {
partBackSubstitution(matrix, vector, thread);
synchronized (context) {
threadsFinished++;
if (threadsFinished == countThreads) {
context.notifyAll();
}
}
}

}).start();
}
}

privatevoid partBackSubstitution(double[][] matrix, double[] vector,
int thread) {
int iteration = matrix.length - 1;
int k = 0;
int len = 0;
while (iteration >= 0) {
synchronized (context) {
try {
if (iteration % countThreads == thread) {
result[iteration] = vector[pivotPosition[iteration]]
/ ma-trix[pivotPosition[iteration]][iteration];
context.notifyAll();
Log.setSeparate(Log.OPTIONAL_INFORMATION, "Iteration "
+ String.valueOf(iteration));
} else {
while (result[iteration] == -1) {
context.wait();
}
}
} catch (InterruptedException e) {
}
}
len = iteration / countThreads
+ ((iteration % countThreads - thread) <= 0 ? 0 : 1);
for (int j = 0; j < len; j++) {
k = thread + j * countThreads;
vector[k] -= matrix[pivotPosition[k]][iteration]
* result[iteration];
matrix[pivotPosition[k]][iteration] = 0;
}

synchronized (context) {
Log.setMessage(Log.OPTIONAL_INFORMATION, "Matrix of iteration "
+ iteration + " by thread " + thread, matrix);
Log.setMessage(Log.OPTIONAL_INFORMATION,
"Result vector of iteration " + iteration
+ " by thread " + thread, result);
}
iteration--;
}

}

publicdouble[] gaussCalculation(double[][] matrix, double[] vector) {
pivotPosition = newint[matrix.length];
pivotIteration = newint[matrix.length];
for (int i = 0; i <pivotIteration.length; i++) {
pivotIteration[i] = -1;
}

Log.setMessage(Log.OPTIONAL_INFORMATION, "",
"Начало выполнения прямого хода Гаусса");
long startTime = System.currentTimeMillis();
gaussianElimination(matrix, vector);
Log.setMessage(Log.TIME, "Время выполнения прямого хода Гаусса",
String.valueOf(System.currentTimeMillis() - startTime));

Log.setMessage(Log.OPTIONAL_INFORMATION, "",
"Начало выполнения обратного хода Гаусса");
startTime = System.currentTimeMillis();
double[] result = backSubstitution(matrix, vector);
Log.setMessage(Log.TIME, "Время выполнения обратного хода Гаусса",
String.valueOf(System.currentTimeMillis() - startTime));
return result;
}
}


Текста Log.java:


package nuos.oops.kr;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

publicclass Log {

publicstaticintOPTIONAL_INFORMATION = 0;
publicstaticintTIME = 1;
publicstaticintOTHER = 2;

privatestatic List<Integer>BLOCKED_LOGS = new ArrayList<>();

privatestatic Map<Integer, StringBuilder>LOGS = new HashMap<Integer, StringBuilder>();

publicstaticvoid setMessage(int type, String tag, String message) {
if (is_blocked_log(type)){
return;
}
StringBuilder LOG = LOGS.get(type);
if (LOG == null) {
LOG = new StringBuilder();
LOGS.put(type, LOG);
}
if (!tag.equals("")){
LOG.append(tag);
LOG.append(":
");
}
LOG.append(message);
LOG.append("

");
}

publicstaticvoid setMessage(int type, String tag, double[][] matrix) {
if (is_blocked_log(type)){
return;
}
setMessage(type, tag, SystemOfLinearEquation.printMatrix(matrix));
}

publicstaticvoid setMessage(int type, String tag, double[] vector) {
if (is_blocked_log(type)){
return;
}
setMessage(type, tag, SystemOfLinearEquation.printVector(vector));
}

publicstatic String getMessages(int type) {
returnLOGS.get(type).toString();
}

publicstatic String getAllMessages() {
String log_str = "";
for (Entry<Integer, StringBuilder> log : LOGS.entrySet()) {
log_str += log.getValue().toString();
}
return log_str;
}

publicstaticvoid setSeparate(int type, String tag){
setMessage(type, "", tag + ":
-----------------------------------------------------------");
}

publicstaticvoid block_log(int type){
BLOCKED_LOGS.add(type);
}

publicstaticvoid unblock_log(int type){
BLOCKED_LOGS.remove(type);
}

publicstaticboolean is_blocked_log(int type){
returnBLOCKED_LOGS.contains(type);
}

publicstaticvoid clearLog(){
LOGS.clear();
}
}