\chapter{Sistem Persamaan Linier}
Mayoritas permasalahan di bidang sains dan rekayasa melibatkan sistem persamaan linier (SPL) yang tersusun atas beberapa persamaan linier yang jumlahnya sama dengan variabel yang tidak diketahui (sistem persamaan \ref{eq61}). Sistem persamaan ini dapat direpresentasikan ke dalam bentuk matriks dan vektor (sistem persamaan \ref{eq62}), sehingga dapat dengan mudah diselesaikan dengan metode - metode yang telah kita pelajari di mata kuliah Aljabar Linier Elementer (atau di beberapa tempat disebut sebagai Matriks dan Ruang Vektor).

\begin{equation}
    \begin{aligned}
a_{1,1}x_1 + a_{1,2}x_2 + \ldots + a_{1,n}x_n &= b_1 \\
a_{2,1}x_1 + a_{2,2}x_2 + \ldots + a_{2,n}x_n &= b_2 \\
& \vdots \\
a_{n,1}x_1 + a_{n,2}x_2 + \ldots + a_{n,n}x_n &= b_n
\end{aligned}
\label{eq61}
\end{equation}

\begin{equation}
    \begin{bmatrix}
a_{1,1} & a_{1,2} & \ldots & a_{1,n} \\
a_{2,1} & a_{2,2} & \ldots & a_{2,n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n,1} & a_{n,2} & \ldots & a_{n,n} \\
\end{bmatrix}
\begin{bmatrix}
x_1 \\
x_2 \\
\vdots \\
x_n
\end{bmatrix}
=
\begin{bmatrix}
b_1 \\
b_2 \\
\vdots \\
b_n
\end{bmatrix}
\label{eq62}
\end{equation}

Terdapat dua jenis metode numerik yang dapat diaplikasikan untuk mencari variabel dalam SPL ini. Pertama adalah metode eliminasi, yang bertujuan untuk mengeliminasi koefisien - koefisien matriks dengan menerapkan operasi baris dan kolom hingga variabel - variabel dapat diketahui dengan kalkulasi sederhana. Yang kedua adalah metode iteratif. Pada metode iteratif persamaan - persamaan disusun sedemikian rupa sehingga memungkinkan kita untuk melakukan perhitungan rekursif untuk mengetahui variabel - variabel, hingga tercapai kondisi konvergensi. Metode ini membutuhkan tebakan awal nilai - nilai variabel untuk menginisiasi proses perhitungan.

\section{Metode Eliminasi Gauss}
Metode ini merupakan metode yang paling dikenal khalayak luas untuk menyelesaikan SPL dan menjadi acuan dasar dari metode - metode penyelesaian lain yang lebih kompleks. Metode ini terdiri dari dua langkah penyelesaian. Langkah pertama adalah eliminasi elemen - elemen diagonal utama pada matriks koefisien. Langkah selanjutnya adalah pensubstitusian ulang variabel - variabel yang telah dikeathui ke sistem persamaan hingga seluruh variabel diketahui. Berikut rincian kedua tahapan tersebut:

\begin{enumerate}
    \item Eliminasi
    
    Pada tahap ini kita membutuhkan tiga struktur pengulangan bersarang:
    \begin{enumerate}
        \item Pengulangan $k$ dari 1 hingga $n-1$ untuk mengindeks baris - baris tetap dan mengeliminasi kolom.
        \item Pengulangan $i$ dari $k + 1$ hingga $n$ untuk mengindeks baris - baris yang telah dikurangi.
        \item Pengulangan $j$ dari $k$ hingga $n$ untuk mengindeks kolom - kolom guna operasi pengurangan antar elemen.
    \end{enumerate}

Kita dapat menggunakan pernyataan eliminasi sebagai berikut:

\begin{equation}
a_{i,j} := a_{k,j} - \frac{a_{k, k}}{a_{i,k}} a_{i,j}
    \label{eq63}
\end{equation}

Konstanta - konstanta baru dihitung dengan menggunakan pernyataan sebagai berikut di dalam pengulangan $i$:

\begin{equation}
    b_i := b_k - \frac{a_{k,k}}{a_{i,k}} b_i a
    \label{eq64}
\end{equation}

Pada akhir tahap ini, seluruh elemen diagonal utama harus sama dengan nol.

\item Pensubstitusian ulang

\begin{enumerate}
    \item Dimulai dari baris terakhir, kita terapkan perhitungan:
    
    \begin{equation}
    x_n := \frac{b_n}{a_{n,n}}
        \label{eq65}
    \end{equation}
    
    \item  Kemudian substitusikan nilai - nilai yang diperoleh untuk $x_{i+1}$, kemudian hitung nilai - nilai $x_i$ pada baris tersebut. Proses ini dapat dituliskan secara matematis melalui ekspresi sebagai berikut:
    
    \begin{equation}
    x_i := \frac{b_i - \sum_{j=i+1}^{n}a_{i, j} x_j }{a_{i,i}}
        \label{eq66}
    \end{equation}
\end{enumerate}
\end{enumerate}

Untuk memahami algoritma ini secara lebih praktis, maka kita akan mencoba untuk menyelesaikan sistem persamaan berikut ini secara numerik:

\begin{equation}
    \begin{bmatrix}
2 & 7 & -1 & 3 & 1 \\
2 & 3 & 4 & 1 & 7 \\
6 & 2 & -3 & 2 & -1 \\
2 & 1 & 2 & -1 & 2 \\
3 & 4 & 1 & -2 & 1 \\
\end{bmatrix}
\begin{bmatrix}
x_1 \\
x_2 \\
x_3 \\
x_4 \\
x_5 \\
\end{bmatrix}
=
\begin{bmatrix}
5 \\
7 \\
2 \\
3 \\
4 \\
\end{bmatrix}
\label{eq67}
\end{equation}

Berikut adalah kode Python-nya:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_061.py}
\linenumbers

Hasilnya: 

\nolinenumbers
\begin{verbatim}
    Solusi SPL: 

    [0.44444444 0.55555556 0.66666667 0.22222222 0.22222222]
\end{verbatim}
\linenumbers

Guna lebih memahami tentang implementasi numerik metode eliminasi Gauss, kita akan mencoba menyelesaikan SPL yang berbeda pada contoh berikut ini:

\begin{equation}
    \begin{bmatrix}
0 & 7 & -1 & 3 & 1 \\
2 & 3 & 4 & 1 & 7 \\
6 & 2 & 0 & 2 & -1 \\
2 & 1 & 2 & 0 & 2 \\
3 & 4 & 1 & -2 & 1 \\
\end{bmatrix}
\begin{bmatrix}
x_1 \\
x_2 \\
x_3 \\
x_4 \\
x_5 \\
\end{bmatrix}
=
\begin{bmatrix}
5 \\
7 \\
2 \\
3 \\
4 \\
\end{bmatrix}
\label{eq68}
\end{equation}

Berikut ini implementasi penyelesaiannya di Python:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_062.py}
\linenumbers

Hasilnya:

\nolinenumbers
\begin{verbatim}
    Solusi SPL:

    [0.02170543 0.79224806 1.05116279 0.15813953 0.03100775]
\end{verbatim}
\linenumbers

\section{Metode Gauss-Jordan}
Metode Gauss-Jordan bertujuan untuk mengeliminasi seluruh elemen di atas dan di bawah diagonal utama, sehingga mentransformasikan matriks koefisien menjadi matriks identitas $I_n$, serta mentransformasikan vektor konstanta menjadi vektor solusi. Dengan kata lain, metode Gauss-Jordan mentransformasikan sistem persamaan \ref{eq62} menjadi:

\begin{equation}
\begin{bmatrix}
1 & 0 & \dots & 0 \\
0 & 1 & \dots & 0 \\
\vdots & \vdots & \ddots & \vdots \\
0 & 0 & \dots & 1 \\
\end{bmatrix} 
\begin{bmatrix}
    x_1\\
    x_2\\
    \vdots\\
    x_n
\end{bmatrix}=
\begin{bmatrix}
    b_1^*\\
    b_2^*\\
    \vdots\\
    b_n^*
\end{bmatrix}
    \label{eq69}
\end{equation}

, di mana $b_1^* , b_2^* , \cdots, b_n^*$ merupakan nilai - nilai dari suku konstanta sesudah mengalami transformasi sebanyak $n$ kali.

Algoritma dari metode ini cukup mirip dengan metode eliminasi Gauss dengan satu pengecualian, yakni proses eliminasi akan diterapkan pada seluruh baris di atas dan di bawah baris pivot. Dengan demikian, kita tidak menemukan operasi pensubstitusian ulang seperti pada metode eliminasi Gauss karena pada akhir proses eliminasi vektor konstanta akan dengan sendirinya bertransformasi menjadi vektor solusi.

Langkah pertama pada metode Gauss-Jordan adalah melakukan \textit{pivoting} parsial dengan cara menyusun ulang baris SPL untuk setiap transformasi guna menjamin terdapatnya elemen - elemen bukan nol pada diagonal utama matriks koefisien. Selanjutnya dilakukan pembagian setiap baris SPL terhadap elemen pivot pada masing - masing baris $a_{k,k}$. Langkah ini dilakukan untuk mendapatkan nilai satu pada seluruh elemen di diagonal utama. Langkah terakhir adalah pengeliminasian seluruh elemen di atas dan di bawah diagonal utama. Diperlukan tiga struktur pengulangan sebagai berikut untuk menyelesaikan operasi tersebut:

\begin{enumerate}
    \item Pengulangan utama $k$ dilakukan dari baris $1$ hingga baris ke-$n$ guna mengindeks baris - baris pivot. Pada operasi ini, setiap elemen pada baris pivot dibagi oleh elemen pivot:
    
    \begin{equation}
        a_{k,j}^* := \frac{a_{k,j}}{a_{k,k}}; \quad b_k^* := \frac{b_k}{a_{k,k}}; \quad k=1,2,\cdots; \quad j = k, n     
        \label{eq610}
    \end{equation}
    
Tanda $*$ menandakan elemen dengan nilai baru.
    
    \item  Pengulangan $i$ dari baris $1$ hingga baris ke-$n$ digunakan untuk mengindeks baris - baris pengurangan. Guna menghindari pengurangan baris pivot dari baris itu sendiri, maka ketika $i = k$, atau jika koefisien sudah bernilai nol, proses pengurangan pada $i$ dapat dilangkahi.
\item Pengulangan $k$ dari $j$ ke $n$ bertujuan untuk mengindeks elemen - elemen hasil pengurangan mulai dari elemen pivot hingga ke kolom terakhir. 
\end{enumerate}

Operasi eliminasi ini dapat dirangkum melalui ekspresi sebagai berikut:

\begin{equation}
    a_{i,j}^* := a_{i,j} - a_{i, k} a_{k,j}
    \label{eq611}
\end{equation}

Vektor konstanta baru yang juga merupakan solusi dari SPL dihitung melalui pengulangan $i$ dengan menggunakan ekspresi sebagai berikut:

\begin{equation}
    b_i^* := b_i - a_{i, k}b_k^*, \quad k=1,2,\cdots,n; i=1,2,\cdots, n; i\neq k
    \label{eq612}
\end{equation}

Implementasi numerik-nya di Python dapat diperhatikan pada kode berikut ini:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_063.py}
\linenumbers

\nolinenumbers
\begin{verbatim}
    Solusi SPL: 
    [-0.5         1.          0.33333333 -2.        ]


    Matriks koefisien sesudah transformasi: 
    [[ 1.  0.  0.  0.]
    [ 0.  1.  0.  0.]
    [-0. -0.  1.  0.]
    [-0. -0. -0.  1.]]
\end{verbatim}
\linenumbers

\section{Metode Jacobi}
Metode ini merupakan metode iteratif dasar yang umum digunakan untuk menyelesaikan SPL. Prinsip dasar metode ini mirip dengan metode iterasi sederhana yang telah kita bahas sebelumnya. SPL yang hendak diselesaikan diatur ulang dengan mengambil variabel yang berbeda dari setiap persamaan ke sisi kiri, kemudian, dimulai dengan tebakan awal untuk semua variabel, nilai-nilai yang dihasilkan dari persamaan tersebut digantikan kembali pada setiap iterasi hingga kondisi konvergensi terpenuhi untuk setiap variabel.

Pada bagian ini, kita akan menyelesaikan sistem persamaan berikut dengan menggunakan metode Jacobi:

\begin{equation}
    \begin{aligned}
4x_1 + x_2 + 2x_3 - x_4 &= 2 \\
3x_1 + 6x_2 - x_3 + 2x_4 &= -1 \\
2x_1 - x_2 + 5x_3 - 3x_4 &= 3 \\
4x_1 + x_2 - 3x_3 - 8x_4 &= 2
\end{aligned}
\label{eq613}
\end{equation}

Berikut adalah susunan ulang sistem persamaan tersebut guna menyelesaikannya dengan metode Jacobi:

\begin{equation}
    \begin{aligned}
x_1 &= -\frac{1}{4}(x_2 + 2x_3 - x_4 - 2) \\
x_2 &= -\frac{1}{6}(3x_1 - x_3 + 2x_4 + 1) \\
x_3 &= -\frac{1}{5}(2x_1 - x_2 - 3x_4 - 3) \\
x_4 &= \frac{1}{8}(4x_1 + x_2 - 3x_3 - 2)
\end{aligned}
\label{eq614}
\end{equation}

Atau secara umum dapat dirangkum ke dalam ekspresi berikut ini:

\begin{equation}
x_i^* := -\frac{1}{a_{i,i}} \left( \sum_{\substack{j=1 \\ j \neq i}}^{n} a_{i,j}x_j - b_i  \right)
    \label{eq615}
\end{equation}

Tanda $*$ pada $x_i$ menunjukkan nilai baru saat iterasi berlangsung. Metode Jacobi ini dapat diselesaikan dengan dua struktur pengulangan. Pengulangan $i$ digunakan untuk menyelesaikan masing - masing persamaan guna mendapatkan nilai $x_i$. Sementara itu, pengulangan $j$ digunakan untuk melakukan operasi penjumlahan suku - suku sisa pada sisi kanan persamaan. Sesudah menempatkan tebakan awal, diperlukan pengaturan toleransi galat yang dikehendaki sebagai syarat konvergensi dari seluruh variabel. Kita juga wajib mengatur batas iterasi sebagai antisipasi jika syarat konvergensi itu tidak juga dipenuhi, untuk mencegah pengulangan terus menerus. Berikut ini merupakan implementasinya di Python: 

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_064.py}
\linenumbers

Hasilnya:

\nolinenumbers
\begin{verbatim}
    Jumlah iterasi: 31 
    Solusi SPL:
    
    [ 0.3650067  -0.23378439  0.28506845 -0.20362079]
\end{verbatim}
\linenumbers

\section{Metode Gauss-Seidel}
Metode ini merupakan metode iteratif yang mempunyai banyak kemiripan dengan metode Jacobi yang telah kita bahas sebelumnya. Metode Gauss-Seidel mengaplikasikan nilai - nilai $x$ baru ke dalam persamaan - persamaan berikutnya di dalam satu iterasi yang sama, sementara pada metode Jacobi nilai - nilai tersebut baru diaplikasikan pada iterasi selanjutnya. Secara umum metode Gauss-Seidel ini dapat dituliskan dalam ekpresi berikut ini:

\begin{equation}
x_i^* := -\frac{1}{a_{i,i}} \left( \sum_{\substack{j=1 \\ j\neq i}}^{n} a_{i,j}x_j^* - b_i \right)
    \label{eq616}
\end{equation}

 Dalam konteks ini, variabel $x_j^*$ merupakan solusi dari penyelesaian persamaan sebelumnya. Berikut ini implementasi numeriknya di Python untuk sistem persamaan \ref{eq613}:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_065.py}
\linenumbers

Hasilnya:

\nolinenumbers
 \begin{verbatim}
     Jumlah iterasi: 13 
     Solusi SPL:
     
     [ 0.36500739 -0.23378566  0.28506799 -0.20362001]
 \end{verbatim}
\linenumbers
\nolinenumbers
\linenumbers

Nampak dari jumlah iterasinya, bahwa metode Gauss-Seidel lebih efektif dibandingkan metode Jacobi.

\section{Syarat Dominasi Diagonal}
Terdapat kondisi konvergensi yang wajib dipenuhi sebelum kita mengaplikasikan metode Jacobi atau Gauss-Seidel. Syarat ini dikenal sebagai dominasi diagonal (\textit{diagonal dominance}). Syarat ini menyatakan bahwa nilai absolut dari elemen - elemen di diagonal utama harus menjadi koefisien terbesar pada setiap persamaan di dalam SPL. Oleh karena itu, persamaan - persamaan di dalam SPL harus disusun sedemikian rupa agar dapat memenuhi kriteria ini.

Untuk memahami syarat dominasi diagonal perhatikanlah SPL berikut ini:

\begin{equation}
    \begin{aligned}
2x_1 - x_2 + 5x_3 - 3x_4 &= 3 \\
4x_1 + x_2 + 2x_3 - x_4 &= 2 \\
4x_1 + x_2 - 3x_3 - 8x_4 &= 2 \\
3x_1 + 6x_2 - x_3 + 2x_4 &= -1
\end{aligned}
\label{eq617}
\end{equation}

SPL ini sama dengan SPL \ref{eq613}. Satu - satu-nya hal yang berbeda hanya susunan persamaan. Berikut ini bentuknya di dalam format matriks:

\begin{equation}
\mathbf{A} = \begin{bmatrix}
2 & -1 & \mathbf{5} & -3 \\
\mathbf{4} & 1 & 2 & -1 \\
4 & 1 & -3 & \mathbf{-8} \\
3 & \mathbf{6} & -1 & 2 \\
\end{bmatrix}, \quad
\mathbf{b} = \begin{bmatrix}
3 \\
2 \\
2 \\
-1 \\
\end{bmatrix}
    \label{eq618}
\end{equation}

Pada SPL \ref{eq618} elemen absolut terbesar di dalam matriks koefisien untuk masing - masing persamaan (ditandai dengan cetak tebal) tidak terletak di diagonal utama. Guna melihat bagaimana hal ini mempengaruhi konvergensi, kita coba terapkan kode Python berikut ini untuk menemukan solusi SPL \ref{eq618} dengan menggunakan metode Gauss-Seidel:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_066.py}
\linenumbers

Nampak bahwa terjadi divergensi, yang ditandai dengan bertambahnya jumlah iterasi dan ketidakakuratan solusi, oleh karena SPL tersebut tidak disusun sesuai dengan syarat dominasi diagonal meskipun menggunakan SPL dan metode penyelesaian yang sama:

\nolinenumbers
\begin{verbatim}
    Jumlah iterasi: 100
    Solusi SPL: 
    [ 8.43572172e+109 -2.71345274e+110 -1.09039090e+110  6.32980450e+110]
\end{verbatim}
\linenumbers

\section{Penyelesaian Sistem Persamaan Linier Menggunakan NumPy dan SciPy}

Modul aljabar linier \verb|numpy.linalg| dan \verb|scipy.linalg| memiliki berbagai macam fungsi yang dapat kita gunakan untuk memanipulasi matriks dan menyelesaikan SPL tanpa memusingkan soal struktur pengulangan bersarang yang banyak kita gunakan sejauh ini. Terdapat dua metode yang umum digunakan untuk menyelesaikan SPL, yakni metode langsung dengan menggunakan fungsi \verb|solve()| dari SciPy dan kombinasi dengan menggunakan fungsi \verb|inv()| di SciPy dan \verb|dot()| di NumPy. Berikut adalah contoh penggunaannya:

\nolinenumbers
\lstinputlisting[language=Python]{./kode/contoh_067.py}
\linenumbers

Hasilnya: 

\nolinenumbers
\begin{verbatim}
    x1 (langsung): 
    [0.02170543 0.79224806 1.05116279 0.15813953 0.03100775]
    x2 (langsung): 
    [ 0.36500754 -0.23378582  0.28506787 -0.20361991]
    
    x1 (tdk langsung): 
    [0.02170543 0.79224806 1.05116279 0.15813953 0.03100775]
    x2 (tdk langsung): 
    [ 0.36500754 -0.23378582  0.28506787 -0.20361991]
\end{verbatim}
\linenumbers

Meskipun menghasilkan solusi yang sama, untuk kebutuhan praktis, seperti dalam riset maupun industri, kami menyarankan untuk menggunakan metode langsung dengan fungsi \verb|solve()|. Hal ini dilakukan untuk mengurangi operasi matriks yang dapat memperlambat waktu komputasi. Untuk mengetahui secara lebih lanjut mengenai fungsi - fungsi ini kalian dapat berkunjung pada situs - situs berikut ini:

\begin{itemize}
    \item \url{https://numpy.org/doc/stable/reference/routines.linalg.html}
    \item \url{https://docs.scipy.org/doc/scipy/reference/linalg.html}
\end{itemize}