\chapter{Interpolasi dan Pencocokan Kurva}

\section{Interpolasi Linier}
Interpolasi linier mengasumsikan penggunaan persamaan garis lurus untuk menginterpolasi titik - titik di antara sepasang titik tertentu pada 
data. Salah satu contoh penggunaannya adalah pada contoh kasus sebagai berikut, misalkan kita sedang mengukur temperatur reaksi kimia pada durasi tertentu seperti yang ditunjukkan pada Tabel \ref{tab1} berikut ini:

\begin{table}[H]
\begin{center}
\begin{tabular}{|c| c| c| c|c|c|}
\hline
Waktu (s) & 20  & 40 &  60  & 80 & 100\\ \hline
Temperatur ($^{\circ}$C) & 26.0 & 48.6  & 61.6 & 74.8 & 75.2 \\
\hline
\end{tabular}
\end{center}
\caption{Data temperatur sebagai fungsi waktu pada suatu reaksi kimia.}
\label{tab31}
\end{table}

Grafik linier-nya dapat dilihat sebagai berikut:

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{gambar/gambar031.png}
    \caption{Grafik linieritas hubungan waktu reaksi dan temperatur.}
    \label{fig31}
\end{figure}

Jika kita ingin mengetahui temperatur reaksi pada detik ke 50, namun hal tersebut luput dari pengukuran, bagaimana cara mengatasinya? Metode paling sederhana yang sering digunakan di SMP dan SMA untuk mencari nilai tengah dari Tabel \ref{tab31} adalah interpolasi linier. Pada metode ini, bagian kurva yang menghubungkan dua titik yang kita ketahui $(x_1 , y_1 )$ dan $(x_2 , y_2 )$ dianggap sebagai garis lurus. Dalam hal ini, bayangkan suatu garis lurus antara (40; 61,6) dan (60; 71,2) (Gambar \ref{fig32}).

\begin{figure}[H]
    \centering
    \includegraphics[width=.65\textwidth]{gambar/gambar032.png}
    \caption{Representasi grafis interpolasi linier.}
    \label{fig32}
\end{figure}

Oleh karena kesamaan pada kemiringan garis lurus tersebut, maka kita dapat menuliskan persamaan sebagai berikut, sebagaimana yang telah kita pelajari di bangku SMP:

\begin{equation}
\frac{y-y_1 }{x - x_1 } = \frac{y_2 - y_1 }{x_2 - x_1 } 
    \label{eq31}
\end{equation}

Maka, nilai $y$ pada suatu nilai $x$ tertentu dapat dituliskan sebagai berikut:

\begin{equation}
y = y_1 + \frac{y_2 - y_1 }{x_2 - x_1 } (x - x_1 )
    \label{eq32}
\end{equation}

Persamaan sederhana ini dapat disimpan dalam kalkulator saku yang dapat diprogram dan digunakan untuk mencari nilai interpolasi dari tabel di berbagai bidang sains dan teknik.

Kembali ke permasalahan temperatur pada reaksi kimia dalam contoh sebelumnya. Dengan menerapkan persaman \ref{eq32}, maka temperatur pada detik ke-50 dapat dirumuskan sebagai berikut:

\begin{equation}
T(50) = 61.6 + \frac{71.2 - 61.6}{60 - 40} (50 - 40) = 66.4^{\circ}\text{C}
    \label{eq33}
\end{equation}

Kerugian dari metode interpolasi linier adalah bahwa titik-titik lain, kecuali dua titik yang berdekatan dengan titik yang diinginkan, diabaikan sama sekali. Dengan demikian, tren kurva secara kesuluruhan tidaklah tergambar. 

Pada bagian selanjutnya, kita akan berkenalan dengan dua metode interpolasi yang banyak digunakan di sains dan rekayasa, yakni metode interpolasi Lagrange dan Newton.

\section{Metode Lagrange}
Metode ini didasarkan pada pembentukan suku banyak berderajat $n$, di mana derajatnya bergantung pada jumlah titik yang dipertimbangkan pada data, yakni sebanyak $n+1$ titik. Sebagai contoh, untuk polinomial derajat ketiga (kubik), maka $n=3$, sehingga diperlukan empat titik data yang dapat dituliskan dengan persamaan suku banyak sebagai berikut:

\begin{equation}
y(x) = y_1 \ell_1 (x) + y_2 \ell_2 (x) + y_3 \ell_3 (x) + y_4 \ell_4 (x)
    \label{eq34}
\end{equation}

Persamaan \ref{eq34} dapat diringkas ke dalam notasi sebagai berikut:

\begin{equation}
y(x) = \sum_{i=1}^{n+1} y_i \ell_i (x)
    \label{eq35}
\end{equation}

, di mana:

\begin{subequations}
    \begin{equation}
        \ell_1 (x) = \frac{(x - x_2) (x - x_3) (x - x_4)}{(x_1 - x_2)(x_1 - x_3) (x_1 - x_4 )}
    \end{equation}
    \begin{equation}
        \ell_2 (x) = \frac{(x - x_1) (x - x_3) (x - x_4)}{(x_2 - x_1)(x_2 - x_3) (x_2 - x_4 )}
    \end{equation}
        \begin{equation}
        \ell_3 (x) = \frac{(x - x_1) (x - x_2) (x - x_4)}{(x_3 - x_1)(x_3 - x_2) (x_3 - x_4 )}
    \end{equation}
        \begin{equation}
        \ell_4 (x) = \frac{(x - x_1) (x - x_2) (x - x_3)}{(x_4 - x_1)(x_4 - x_2) (x_4 - x_3 )}
    \end{equation}
    \label{eq36}
\end{subequations}

Ringkasnya adalah sebagai berikut:

\begin{equation}
    \ell_i = \prod_{\substack{j = 1 \\ j \neq i}}^{n + 1} \left(\frac{x - x_j}{x_i - x_j}\right)
    \label{eq37}
\end{equation}


Maka, secara lebih umum metode Lagrange dapat dituliskan menjadi:

\begin{equation}
    y(x) = \sum_{i = 1}^{n + 1} \left(\prod_{\substack{j = 1 \\ j \neq i}}^{n + 1} \left(\frac{x - x_j}{x_i - x_j}\right)\right)
    \label{eq38}
\end{equation}

Berikut ini merupakan implementasi kode Python dari persamaan \ref{eq38} untuk menyelesaikan permasalahan interpolasi pada Tabel \ref{tab31}:

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

Pada waktu 50 detik, temperatur-nya adalah:

\nolinenumbers
\begin{verbatim}
    Masukkan Waktu : 50
    Untuk t = 50.0 detik, T = 66.9 Celcius
\end{verbatim}
\linenumbers

Gambar \ref{fig33} menunjukkan perbedaan antara interpolasi linier dengan metode Lagrange dengan menggunakan suku banyak berderajat lima. Nampak, perbedaan antar keduanya tidak begitu terlihat ketika data tersedia, yakni pada selang waktu 20 - 60 detik (bandingkan dengan perbedaan pada detik ke-10).

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{gambar/gambar033.png}
    \caption{Perbandingan antara interpolasi linier dan metode Lagrange (suku banyak berderajat lima).}
    \label{fig33}
\end{figure}

Pada contoh ini, kita menerapkan metode Lagrange pada kasus selang waktu yang seragam (\textit{equally-spaced time interval}), namun metode ini juga dapat diterapkan pada kasus selang waktu yang tidak seragam. Hal ini sangat bermanfaat pada penelitian di bidang - bidang kelimuan yang memiliki sedikit data, seperti paleoklimatologi dan stratigrafi.

\section{Metode Newton}
Metode Newton bertujuan untuk menghasilkan suku banyak sebagai berikut, berdasarkan titik - titik data yang tersedia:

\begin{equation}
y(x) = \alpha_0 + \alpha_1 (x - x_1) + \alpha_2 (x-x_1) (x-x_2) + \cdots + \alpha_n (x-x_1)(x-x_2)\cdots(x-x_n)
    \label{eq39}
\end{equation}

Terdapat dua langkah untuk mengubah data ke dalam bentuk tesebut. Langkah pertama dinamakan sebagai prosedur pembeda terbagi (\textit{divided difference}), yang digunakan untuk menghitung nilai koefisien suku banyak $\alpha_0, \cdots, \alpha_n$. Langkah kedua adalah substitusi sederhana pada nilai $x$ yang diberikan ke suku banyak tersebut guna menghasilkan nilai $y$ yang telah diinterpolasi.

Prosedur ini diterapkan untuk membuat suatu tabel yang tersusun atas data yang hendak diinterpolasi dan kolom berjumlah $n$ yang mana merupakan pembeda. $n$ dalam konteks ini merupakan derajat suku banyak dari titik - titik data yang berjumlah $n+1$. Untuk lebih jelasnya dapat dilihat pada Tabel \ref{tab32} yang merepresentasikan prosedur pembeda untuk empat titik data.

\begin{table}[H]
\begin{center}
\begin{tabular}{|c| c| c| c|c|}
\hline
(0) & (1)  & (2) &  (3)  & (4) \\ \hline
$x_1$ & $y_{1}^{(1)} = y_1$ &   &  & \\ \hline
$x_2$ & $y_{2}^{(1)} = y_2$ & $y_{2}^{(2)}$   & & \\ \hline
$x_3$ & $y_{3}^{(1)} = y_3$ & $y_{3}^{(2)}$ & $y_{3}^{(3)}$ & \\ \hline
$x_4$ & $y_{4}^{(1)} = y_4$ & $y_{4}^{(2)}$ & $y_{4}^{(3)}$ & $y_{4}^{(4)}$\\ \hline
\end{tabular}
\end{center}
\caption{Contoh tabel prosedur pembeda terbagi.}
\label{tab32}
\end{table}

Pada tabel tersebut, kolom (0) merupakan nilai $x$ dari data dan kolom (1) merupakan nilai $y$ dari data. Angka yang dituliskan di atas $y$ merujuk pada nomor kolom-nya.

Kolom (2) merupakan perbedaan antara kolom kedua jika dibandingkan dengan nilai - nilai $x$ berkorespondensi dengannya:

\begin{equation}
y_{i}^{(2)} = \frac{y_{i}^{(1)} - y_{1}^{(1)}}{x_i - x_1}, \quad \text{untuk } i=2,3,4
    \label{eq310}
\end{equation}

Pada kolom (3):

\begin{equation}
y_{i}^{(3)} = \frac{y_{i}^{(2)} - y_{2}^{(2)}}{x_i - x_2}, \quad \text{untuk } i=3,4
    \label{eq311}
\end{equation}

Pada kolom (4) hanya terdapat nilai tunggal, yakni:

\begin{equation}
y_{i}^{(4)} = \frac{y_{4}^{(3)} - y_{3}^{(3)}}{x_4 - x_3}
    \label{eq312}
\end{equation}

Secara umum, prosedur pembeda terbagi ini dapat diformulasikan melalui persamaan sebagai berikut:

\begin{equation}
y_{i}^{(j+1)} = \frac{y_{i}^{(j)} - y_{j}^{(j)}}{x_i - x_j}, \quad \text{untuk } j=1,\cdots, n, \quad \text{dan } i = j+1, \cdots, n+1
    \label{eq313}
\end{equation}

Koefisien suku banyak pada persamaan \ref{eq39} didapatkan dari nilai diagonal utama dari Tabel \ref{tab32}:

\begin{equation}
\alpha_0 = y_{1}^{(1)}, \alpha_1 = y_{2}^{(2)}, \cdots, \alpha_2 = y_{3}^{(3)}, \cdots, \alpha_n = y_{n+1}^{(n+1)}
    \label{eq314}
\end{equation}

Langkah kedua dari metode Newton ini adalah melakukan perhitungan nilai $y$ berdasarkan nilai $x$ dan koefisien suku banyak yang diberikan. Secara matematis, metode Newton ini dapat dituliskan sebagai berikut:

\begin{equation}
y(x) = \alpha_0 + \sum_{i=1}^{n} \left(\prod_{j=1}^{j=i} (x - x_j) \right)\alpha_i
    \label{eq315}
\end{equation}

Atau:

\begin{equation}
y(x) = y_{1}^{(1)} + \sum_{i=1}^{n} \left(\prod_{j=1}^{j=i} (x - x_j) \right) y_{i+1}^{(i+1)}
    \label{eq316}
\end{equation}

Guna mendapatkan pemahaman yang lebih praktikal, kita akan mencoba menerapkan metode Newton ini ke dalam kode Python sebagai berikut:

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

Berikut adalah beberapa hasil nilai $y$ untuk beberapa nilai $x$:

\nolinenumbers
\begin{verbatim}
    Masukkan x : 3.2
    Untuk x = 3.2, y = 3.5

    Masukkan x : 6.7
    Untuk x = 6.7, y = 7.0

    Masukkan x : 8.5
    Untuk x = 8.5, y = 12.0
\end{verbatim}
\linenumbers

\section{Pencocokan Kurva}
Pencocokan kurva (\textit{curve fitting}) merupakan prosedur untuk mencari persamaan yang dapat merangkum hubungan antar variabel pada data dengan meminimalkan deviasinya dari data tersebut. Jadi, perbedaan utama antara interpolasi dan pencocokan kurva adalah bahwa pencocokan kurva tidak harus melewati semua titik data yang diberikan. Teknik yang digunakan untuk mencari persamaan kurva dikenal sebagai metode kuadrat terkecil (\textit{least square}), di mana selisih kuadrat antara titik-titik data dan nilai fungsi kurva diminimalkan.

\subsection{Regresi Linier}
Jika data dari suatu eksperimen mempunyai sifat linier, maka kita dapat melakukan pencocokan fungsi kurva-nya ke dalam garis lurus:

\begin{equation}
f(x) = \alpha_0 + \alpha_1 x
    \label{eq317}
\end{equation}

Koefisien $\alpha_0$ dan $\alpha_1$ didapatkan melalui persamaan berikut ini:

\begin{subequations}
    \begin{equation}
        \alpha_0 = \frac{\bar{y} \sum x_{i}^{2} - \bar{x} \sum x_i y_i}{\sum x_{i}^{2} - n \bar{x}^2}
        \label{eq318a}
    \end{equation}
    \begin{equation}
        \alpha_1 = \frac{\sum x_i y_i - \bar{x} \sum y_i}{\sum x_{i}^{2} -n \bar{x}^2}
        \label{eq318b}
    \end{equation}
\end{subequations}

$\bar{x}$ dan $\bar{y}$ merupakan nilai rata - rata dari masing - masing $x$ dan $y$:

\begin{subequations}
    \begin{equation}
    \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i
        \label{eq319a}
    \end{equation}
    \begin{equation}
    \bar{y} = \frac{1}{n} \sum_{i=1}^{n} y_i
        \label{eq319b}
    \end{equation}
\end{subequations}

Untuk memahaminya secara lebih praktis, perhatikanlah contoh kode Python berikut ini:

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

Luarannya adalah sebagai berikut (Gambar \ref{fig34}):

\nolinenumbers
\begin{verbatim}
    Persamaan garis regresi linier: 
    f(x) = (-28.305) + (9.086)x
\end{verbatim}
\linenumbers

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{gambar/gambar034.png}
    \caption{Representasi grafis regresi linier.}
    \label{fig34}
\end{figure}


\subsection{Regresi Suku Banyak}

Secara umum, suku banyak dapat didefinisikan secara matematis ke dalam bentuk sebagai berikut: 

\begin{equation}
f(x) = \alpha_0 + \alpha_1x + \alpha_2x^2 + \dots + \alpha_nx^n
    \label{eq320}
\end{equation}

Jika suatu kumpulan data yang berisi $m$ titik akan diestimasi oleh kurva suku banyak berderajat $n$, maka suatu sistem persamaan linear dirumuskan untuk menghitung nilai-nilai koefisien tersebut:

\begin{equation}
\mathbf{A} \boldsymbol{\alpha } = \mathbf{b}
    \label{eq321}
\end{equation}

, di mana:

\begin{subequations}
    \begin{equation}
\mathbf{A} =
\begin{pmatrix}
m & \sum x_i & \sum x_i^2 & \dots & \sum x_i^n \\
\sum x_i & \sum x_i^2 & \sum x_i^3 & \dots & \sum x_i^{n+1} \\
\vdots & \vdots & \vdots & \ddots & \vdots \\
\sum x_i^n & \sum x_i^{n + 1} & \sum x_i^{n+2} & \dots & \sum x_i^{2n}
\end{pmatrix}
        \label{eq322a}
    \end{equation}

    \begin{equation}
        \mathbf{b} =
\begin{pmatrix}
\sum y_i \\
\sum x_i y_i \\
\vdots \\
\sum x_i^n y_i
\end{pmatrix}
\label{eq322b}
    \end{equation}
\end{subequations}

Notasi sigma dalam konteks ini didefinisikan sebagai operasi penjumlahan dari $i=1$ hingga $m$:

\begin{equation}
\sum := \sum_{i=1}^{m}
    \label{eq323}
\end{equation}

Setelah semua koefisien dihitung, sistem persamaan ini dapat diselesaikan dengan menggunakan teknik penyelesaian sistem linear seperti eliminasi Gauss. Kami menggunakan fungsi \verb|solve()| dari modul \verb|numpy.linalg| pada contoh ini. Modul ini berisi fungsi-fungsi aljabar linier.

Sebagai contoh, sistem suku banyak berderajat tiga akan didefinisikan melalui persamaan sebagai berikut:

\begin{subequations}
    \begin{equation}
    \mathbf{A} =
\begin{pmatrix}
m & \sum x_i & \sum x_i^2 & \sum x_i^3\\ 
\sum x_i & \sum x_i^2 & \sum x_i^3 & \sum x_i^4 \\
\sum x_i^2 & \sum x_i^3 & \sum x_i^4 & \sum x_i^5 \\
\sum x_i^3 & \sum x_i^4 & \sum x_i^5 & \sum x_i^6 \\
\end{pmatrix}
        \label{eq324a}
    \end{equation}
    \begin{equation}
\mathbf{b} =     \begin{pmatrix}
\sum y_i \\
\sum x_i y_i \\
\sum x_i^2 y_i \\
\sum x_i^3 y_i \\
\end{pmatrix}
        \label{eq3324b}
    \end{equation}
\end{subequations}

Berikut adalah implementasinya di Python:

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

Luarannya dapat dilihat sebagai berikut ini (Gambar \ref{fig35}):

\nolinenumbers
\begin{verbatim}
    Suku Banyak:
    f(x) = 	 1.928571
	    +5.678571 x^1
	    -0.000000 x^2
	    +0.250000 x^3
\end{verbatim}
\linenumbers

\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{gambar/gambar035.png}
    \caption{Representasi grafis regresi suku banyak berderajat tiga.}
    \label{fig35}
\end{figure}

\section{Interpolasi Menggunakan SciPy}
Terdapat berbagai fungsi interpolasi, baik satu mupun multidimensi, pada modul \verb|scipy.interpolate|. Pada bagian ini, kami hanya membahas penggunaan fungsi interpolasi \verb|interp1d()| dan \verb|lagrange()| untuk diaplikasikan pada data di Tabel \ref{tab31} dengan menggunakan Python Shell:

\nolinenumbers
\begin{verbatim}
    >>> from scipy.interpolate import interp1d, lagrange
    >>> x = [0, 20, 40, 60, 80, 100]
    >>> y = [26.0, 48.6, 61.6, 71.2, 74.8, 75.2]
    >>> f = interp1d(x,y) # fungsi interpolasi
    >>> print(f(20)) # x = 20
    48.6
    >>> print(f(80)) # x = 80
    74.8
    >>> print(f(50)) # x = 50
    66.4
    >>> f = interp1d(x,y,'quadratic') # interpolasi kuadratik 
    >>> print(f(50)) # x = 50
    66.95208333333333
    >>> f = interp1d(x,y,'cubic') # interpolasi kubik
    >>> print(f(50)) # x = 50
    66.945
\end{verbatim}
\linenumbers

Hasil dari interpolasi kubik ini mempunyai kemiripan dengan interpolasi dengan metode Lagrange untuk suku banyak berderajat lima:

\nolinenumbers
\begin{verbatim}
    >>> L = lagrange(x, y) # polinomial Lagrange
    >>> print(L)
                5             4             3           2
    3.698e-08 x - 9.688e-06 x + 0.0009219 x - 0.04463 x + 1.725 x + 26
    >>> print(L(50))
    66.94765624999957
\end{verbatim}
\linenumbers

Untuk dapat lebih memahami terkait modul ini, kalian dapat berkunjung pada situs ini: \url{https://docs.scipy.org/doc/scipy/reference/interpolate.html#module-scipy.interpolate}.

\section{Pencocokan Kurva Menggunakan SciPy}

Kita dapat menggunakan fungsi \verb|lineregress()| pada modul \verb|scipy.stats| untuk menyelesaikan permasalahan regresi linier. Berikut adalah implementasinya di Python Shell:

\nolinenumbers
\begin{verbatim}
    >>> from scipy.stats import linregress
    >>> x = [3, 4, 5, 6, 7, 8]
    >>> y = [0, 7, 17, 26, 35, 45]
    >>> L = linregress(x,y)
    >>> L.slope
    9.085714285714285
    >>> L.intercept
    -28.3047619047619
\end{verbatim}
\linenumbers

Untuk informasi lebih lanjut terkait dengan fungsi ini, kalian dapat berkunjung ke dokumentasi resmi-nya: \url{https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html#scipy.stats.linregress}.

Sementara itu, untuk mengimplementasikan regresi suku banyak pada SciPy, kita dapat menggunakan fungsi \verb|curve_fit()| pada modul \verb|scipy.optimize|. Modul ini menggunakan metode kuadrat terkecil yang bersifat non-linier untuk mencocokan data dengan fungsi. Berikut adalah contohnya di Python Shell:

\nolinenumbers
\begin{verbatim}
    >>> from scipy.optimize import curve_fit
    >>> f = lambda x, a0, a1, a2: a0 + a1*x + a2*x**2 # fungsi kuadrat
    >>> x = [0, 1, 2, 3, 4, 5]
    >>> y = [2, 8, 14, 28, 39, 62]
    >>> a, b = curve_fit(f, x, y)
    >>> print(a) # tampilkan koefisien
    [2.67857143 2.25357143 1.875     ]
\end{verbatim}
\linenumbers

Variabel \verb|b| merupakan \textit{array} 2D yang merupakan estimasi kovarian dari koefisien regresi \verb|a|. Kita juga dapat mengimplementasikan regresi kubik sebagai berikut ini:

\nolinenumbers
\begin{verbatim}
    >>> f = lambda x, a0, a1, a2, a3: a0 + a1*x + a2*x**2 + a3*x**3
    >>> a,_ = curve_fit(f, x, y)
    >>> print(a)
    [ 1.92857143e+00  5.67857143e+00 -2.17847962e-12  2.50000000e-01]
\end{verbatim}
\linenumbers

Pada contoh ini, kita menempatkan variabel \verb|b| pada \textit{placeholder} \verb|_| karena tidak membutuhkan estimasi kovarian tersebut. Untuk memahami secara lebih mendetail tentang fungsi \verb|curve_fit()|, kalian dapat berkunjung ke situs ini: \url{https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html}.