https://github.com/danzigerrr/project_mn_matrix_linear_equations_solver
https://github.com/danzigerrr/project_mn_matrix_linear_equations_solver
Last synced: over 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/danzigerrr/project_mn_matrix_linear_equations_solver
- Owner: Danzigerrr
- Created: 2022-04-16T06:35:51.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2022-04-19T07:14:56.000Z (about 4 years ago)
- Last Synced: 2025-01-22T18:34:52.237Z (over 1 year ago)
- Language: C++
- Size: 418 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Metody Numeryczne Projekt 2 – Układy równań liniowych
Krzysztof Nazar, 184698 16 kwietnia 2022
1. **Wstęp**
Celem projektu jest implementacja metod iteracyjnych (Jacobiego i Gaussa-Seidla) i bezpośrednich (faktoryzacja LU) rozwiazywania układów równań liniowych. Układy równań są kluczowe w dalszym rozwoju nauki w obszarze wielu dziedzin, na przykład biomechanika, symulacje odkształceń, dynamika płynów i wiele innych. Mimo, że w praktyce stosuje się macierze przechowywane w tak zwanym rzadkim formacie, w tym projekcie będę stosował macierz zapisaną w formacie pełnym.
Implementacja metod rozwiązywania układów równań została wykonana w języku C++ w środowisku Visual Studio. Wykresy zostały stworzone z wykorzystaniem programu MS Excel.
2. **Podstawa teoretyczna**
1. **Konstrukcja układu równań**
Układ równań liniowych przedstawiony jest formułą:
gdzie:
- macierz systemowa, np. obwód elektroniczny, karoserię samochodu, turbinę, itp.
- wektor pobudzenia, np. impuls elektroniczny, wektor siły, fala dźwiękowa itp.
- wektor rozwiązań reprezentujących szukaną wielkość fizyczną, np. rozkład pola
w przestrzeni, natężenie dźwięku itp.
2. **Wektor residuum**
Podczas wykorzystywania algorytmów iteracyjnych istotne jest określenie iteracji, w której algorytm powinien przestać się wykonywać. W tym celu korzysta się z tak zwanego wektora residuum. Dla k-tej iteracji wektor residuum można wyznaczyć za pomocą poniższego wzoru:
( ) = ( ) −
Aby obliczyć jaki błąd wnosi wektor ( ) należy wyznaczyć normę euklidesową z wektora residuum w k-tej iteracji. Wektor powinien być wektorem zerowym, jeśli algorytm zbiegnie do dokładnego rozwiązania. Zwykle jako kryterium stopu przyjmuje się normę euklidesową z wektora residuum o wartość mniejszej niż 10−6.
3. **Zadanie projektowe**
3.1. **Zadanie A**
W tym zadaniu macierz jest macierzą kwadratową o rozmiarze × gdzie = 998. Macierz A składa się z wyrazów , oraz , gdzie

Macierz A przedstawiona została poniżej.

Wektor ma długość . Jego n-ty element ma wartość

Wektor b przedstawiony został poniżej.

3.2. **Zadanie B**
Celem tego zadania była implementacja metod iteracyjnych rozwiązywania układów równań liniowych: Jacobiego i Gaussa–Seidla.
Podczas obliczeń przy pomocy obydwu metod wykorzystuje funkcje wyznaczające wartość residuum oraz normę wektora. Ich implementacje umieściłem poniżej.
Najpierw zaimplementowałem metodę Jacobiego.
Następnie zaimplementowałem metodę Gaussa-Seidla.
Program zwraca poniższe informacje.

Rozwiązanie układu równań uzyskuje się szybciej przy użyciu metody Gaussa-Seidla. Istotny jest także fakt, że przy użyciu metody Jacobiego potrzebna jest większa liczba iteracji aby obliczyć wynik. W tym przypadku, różnice pomiędzy metodami są mało znaczące.
3.3. **Zadanie C**
W tym zadaniu macierz A składa się z wyrazów 1, 2 oraz 3, gdzie

Macierz A przedstawiona została poniżej.

Wartości w wektorze b o długości N nie zmieniają się.

W funkcjach obliczających rozwiązanie układu równań zgodnie z metodą Jacobiego oraz Gaussa- Seidlera wprowadziłem warunek, aby kończyły się gdy liczba iteracji osiągnie 5000. Dzięki temu można uniknąć nieskończonej pętli w przypadku gdy układ nie ma dokładnego rozwiązania.

Metody iteracyjne dla analizowanego układu nie zbiegają się. Na konsoli widoczne jest, że norma wektora osiąga wartość -*nan(ind)*. Skrót *NAN* w języku angielskim oznacza „Not A Number”, a więc nie otrzymaliśmy dokładnego rozwiązania. Można z tego wyciągnąć wniosek, że pętla została przerwana przez warunek sprawdzający ilość wykonanych iteracji.
3.4. **Zadanie D**
Do wyznaczenia rozwiązania układu równań została wykorzystana implementacja metody faktoryzacji LU. Kod umieszczam poniżej.
Analizowane były macierze takie same jak w zadaniu C, w którym metody iteracyjne nie zbiegły się. Jednak używając metody faktoryzacji LU otrzymaliśmy dokładny wynik.

Wartość residuum osiągnęła wartość około 6,11 ∙ 10-13. Czas wykonywania algorytmu był relatywnie krótki – około 1,5 sekundy.
3.5. **Zadanie E**
Stworzyłem tablice *NArray* zawierającą kilka liczb całkowitych – są to kolejno analizowane rozmiary macierzy A.
int NArray[] = { 500, 1000, 2000, 3000, 4000, 5000};
Dzięki klasie *CSVWriter* informacje o ilości niewiadomych w danym przypadku oraz czasie rozwiązywania układu równań zapisywane są do plików CSV: *JacobiTimeVsSize.csv* oraz *GaussSeidlTimeVsSize.csv*. Na podstawie uzyskanych danych, w programie Microsoft Excel stworzyłem w wykresy przedstawiające zależności pomiędzy rozmiarem macierzy a czasem rozwiązywania układu równań. Wykresy zamieściłem poniżej.


3.6. **Zadanie F - Wnioski**
Po wykonaniu zadań nie potrafię stwierdzić która metoda jest najlepsza. Zadanie B pokazuje, że metody iteracyjne wykonują się bardzo szybko. Jednak zadania D oraz E ilustrują przypadek gdy metoda bezpośrednia ma znaczącą przewagę nad metodami iteracyjnymi. Uważam, że równania powinno się najpierw rozwiązywać metodami iteracyjnymi, a jeśli nie będą zbiegać, wtedy zastosować metodę bezpośrednią, na przykład metodę faktoryzacji LU. Na podstawie wyników funckji „Trendilne” w MS Excel, można powiedzieć, że zależność pomiędzy czasem wykonywania algorytmu a liczba niewiaodmych w równaniu rośnie potęgowo.