Artykuł przeprowadzi punkt po punkcie jak wprowadzoną przez użytkownika macierz odwrócić i pomnożyć dwie macierze. Uzupełnieniem kodu jest biblioteka matrix.h opracowana na podstawie wcześniejszych artykułów.
Przed przystąpieniem do pisania funkcji mnożenia i odwracania macierzy napiszemy funkcję kopiującą macierz.
(1.) Nasz funkcja zwróci wskaźnik na nową macierz. Jako argument przyjmujemy macierz do skopiowania. (2.) Tworzymy nową macierz i (3. - 4.) ustalamy wymiary pobierając je z argumentu mat. (5. - 13) Kopiujemy dane z mat do nowej macierzy matrix. Na sam koniec (14.) zwracamy nowy wskaźnik.
Zapis można uprościć i użyć dostępnej funkcji createMatrix(), która tworzy nową macierz o wymiarach n x m. To podejście jednak zwiększa czas kopiowania. Najpierw tworzymy macierz i ustawiamy każdy lement na 0. Potem przypisujemy dopiero żądane wartości. Lepiej w tym przypadku niejako skopiować funkcję createMatrix() i ją zmodyfikować.
Do wyznaczania macierzy odwrotnej wykorzystamy zredukowaną postać schodkową. Zadaną macierz rozszerzymy o macierz jednostkową. Następnie przeprowadzimy redukcję i macierz po prawej stronie będzie naszą macierzą odwrotną. Przykładowo:
Deklarujemy funkcje:
Funkcja będzie zwrać prawdę, gdy odwracanie się powiedzie i fałsz kiedy nie jest to możliwe. Sprawdzamy warunek konieczny do odwrócenia czyli czy macierz jest nieosobliwa. To jak wyznacznik jest różny od 0 (implementacja tego w części 4) oraz czy macierz jest kwadratowa. Jeśli macierz nie spełnia warunku to zwracamy fałsz.
Tworzymy nową macierz o wymiarach n x 2m. (8. 9.) Do pierwszej części przepisujemy wartości z zadanej macierzy. (10. 11.) Drugą część wypełniamy zerami pamiętając, żeby po prawej stronie była macierz jednostkowa. Jedynki wpisuje linijka (12.).
(18.) Wywołujemy funkcję reducedRowEchelonForm(), aby zredukować macierz to zredukowanej postaci schodkowej. Dzięki temu po prawej stronie tworzy się macierz odwrotna. (19. - 24.) Przepisujemy prawą macierz do oryginalnej macierzy podanej w argumencie. Po przepisaniu każdej linijki (22.) dealokujemy pamięć z tymczasowej macierzy. (23.) Usuwamy zadeklarowną macierz tymczasową do końca. (25.) Na sam koniec sygnalizujemy, że wszystko się udało i zwracamy true.
Tym razem nasza funkcja będzie zwracać kompletnie nową macierz, więc nagłówek deklarujemy tak:
Następnie sprawdzamy czy dane macierze da się pomnożyć czyli czy ilość wierszy w macierzy A nie jest różna od ilości kolumn macierzy B. Jeśli tak nie jest to zwracamy NULL. Będzie to sygnał, że danych macierzy nie da się pomnożyć. (4.) Tworzymy nową macierz o wymiarach n z A i m z B. (5.) Dla każdego wiersza i (6.) każdej kolumny (8.) obliczamy wartość pola i, j nowej macierzy. (9.) Na sam koniec zwracamy nową macierz.
Na sam koniec testujemy stworzone funkcje: użytkownik wprowadza poprawną macierz, kopiujemy ją, odwracamy i wypisujemy. Później mnożymy obie macierze. W rezultacie powinniśmy otrzymać macierz jednostkową.
Czasami funkcja nieco różni się od macierzy jednostkowej, ale jest to problem zaokrąglania mnożenia i dodawania spowodowane ograniczeniami przechowywania liczb rzeczywistych w komputerze.