\chapter{Turunan Numerik}

Turunan mempunyai banyak berguna di dalam bidang sains dan teknik karena sebagian besar hubungan antar variabel di dalam persamaan - persamaan fisis, serta data observasi umumnya mencakup perubahan variabel tersebut terhadap posisi dan/atau waktu. Meskipun sebagian besar persamaan - persamaan tesebut dapat diturunkan secara analitis, terdapat banyak kurva dan kumpulan data yang diperoleh dari hasil observasi, sehingga turunannya, mau tidak mau, harus diselesaikan secara numerik untuk memperoleh analisis yang akurat.

\section{Pendekatan Beda Hingga}
Pendekatan beda hingga digunakan untuk mengaproksimasi turunan dari suatu persamaan atau data dengan mengambil perbedaan nilai $y(x)$ terhadap perbedaan $x$. Dalam kasus perbedaan $x$ yang sama, perbedaan \(\Delta x\) umumnya dinamakan sebagai $h$, yang dikenal sebagai \textit{step size}, seperti yang ditunjukkan dalam Gambar \ref{fig41}.

\begin{figure}[H]
    \centering
    \includegraphics[width=.85\textwidth]{gambar/gambar041.png}
    \caption{Representasi grafis pendekatan beda hingga.}
    \label{fig41}
\end{figure}

Bentuk aproksimasi beda hingga yang paling sederhana adalah dengan menemukan kemiringan garis $AB$ yang mana dapat dianggap setara dengan kemiringan kurva antara titik $x_i$ dan $x_{i + 1}$. Semakin kecil \textit{step size} yang kita gunakan, akan semakin akurat pula aproksimasi kemiringan kurva yang kita dapatkan. Urutan nilai kemiringan ini akan menghasilkan aproksimasi turunan pertama dari data yang diberikan.

Secara teoritis, pendekatan beda hingga berasal dari ekspansi deret Taylor dari \(f(x)\), yang mana telah kita pelajari semenjak tingkat 1 perkuliah di mata kuliah Kalkulus 1. Ekspansi dari \(f(x_{i+1})\) dapat dituliskan sebagai berikut:

\begin{equation}
f(x_{i+1}) = f(x_i) + f'(x_i)h + \frac{f''(x_i)}{2!}h^2 + \frac{f'''(x_i)}{3!}h^3 + \dots
    \label{eq41}
\end{equation}

Sehingga $f'(x_i)$ dapat dituliskan ke dalam bentuk:

\begin{equation}
f'(x_i) = \frac{f(x_{i+1}) - f(x_i)}{h} - \frac{f''(x_i)}{2!}h - \frac{f'''(x_i)}{3!}h^2 + \dots
    \label{eq42}
\end{equation}

Dengan menghilangkan suku - suku yang mengandung turunan kedua dan yang lebih tinggi, $f'(x_i)$ dapat dituliskan sebagai:

\begin{equation}
f'(x_i) = \frac{f(x_{i+1}) - f(x_i)}{h} + \mathcal{O}(h)
    \label{eq43}
\end{equation}

Persaman \ref{eq43} dikenal sebagai metoode beda maju (\textit{forward difference}). Hal ini dikarenakan titik kedua yang terpilih sesudah $x_i$ berada pada arah sumbu $x$ positif. Suku $\mathcal{O}(h)$ dikenal sebagai galat yang timbul sebagai akibat pemotongan suku - suku deret Taylor yang dilbatkan. 

Berikut adalah beberapa aproksimasi turunan dengan metode beda maju, tengah, dan mundur hingga turunan keempat-nya:

\begin{itemize}
    \item Metode beda maju dengan galat $\mathcal{O}(h)$:
    
    \begin{subequations}
\begin{equation}
    f'(x_i) = \frac{f(x_{i+1}) - f(x_i)}{h}
    \label{eq44a}
\end{equation}

\begin{equation}
    f''(x_i) = \frac{f(x_{i+2}) - 2f(x_{i+1}) + f(x_i)}{h^2}
    \label{eq44b}
\end{equation}

\begin{equation}
    f'''(x_i) = \frac{f(x_{i+3}) - 3f(x_{i+2}) + 3f(x_{i+1}) - f(x_i)}{h^3}
    \label{eq44c}
\end{equation}

\begin{equation}
    f''''(x_i) = \frac{f(x_{i+4}) - 4f(x_{i+3}) + 6f(x_{i+2}) - 4f(x_{i+1}) + f(x_i)}{h^4}
    \label{eq44d}
\end{equation}
\end{subequations}

\item  Metode beda tengah (\textit{central difference}) dengan galat $\mathcal{O}(h^2 )$:

\begin{subequations}
    \begin{equation}
        f'(x_i) = \frac{f(x_{i+1}) - f(x_{i-1})}{2h}
        \label{eq45a}
    \end{equation}
    \begin{equation}
        f''(x_i) = \frac{f(x_{i+1}) - 2f(x_i) + f(x_{i-1})}{h^2}
        \label{eq45b}
    \end{equation}

    \begin{equation}
        f'''(x_i) = \frac{f(x_{i+2}) - 2f(x_{i+1}) + 2f(x_{i-1}) - f(x_{i-2})}{2h^3}
        \label{eq45c}
    \end{equation}

    \begin{equation}
        f''''(x_i) = \frac{f(x_{i+2}) - 4f(x_{i+1}) + 6f(x_i) - 4f(x_{i-1}) + f(x_{i-2})}{h^4}
        \label{eq46d}
    \end{equation}
\end{subequations}

\item  Metode beda mundur (\textit{backward difference}) dengan galat $\mathcal{O}(h)$:

\begin{subequations}
    \begin{equation}
        f'(x_i) = \frac{f(x_i) - f(x_{i-1})}{h}
        \label{eq46a}
    \end{equation}

    \begin{equation}
        f''(x_i) = \frac{f(x_i) - 2f(x_{i-1}) + f(x_{i-2})}{h^2}
        \label{eq36b}
    \end{equation}

    \begin{equation}
        f'''(x_i) = \frac{f(x_i) - 3f(x_{i-1}) + 3f(x_{i-2}) - f(x_{i-3})}{h^3}
        \label{eq36c}
    \end{equation}
\begin{equation}
f''''(x_i) = \frac{f(x_i) - 4f(x_{i-1}) + 6f(x_{i-2}) - 4f(x_{i-3}) + f(x_{i-4})}{h}
\label{eq36d}
\end{equation}
\end{subequations}
\end{itemize}

Seperti yang dapat diperhatikan dari persamaan - persamaan tersebut, metode beda tengah mempertimbangkan jumlah titik yang sama di sebelah kiri dan kanan dari \(x_i\), sedangkan pada metode beda mundur titik - titik diambil dari sebelah kiri \(x_i\). Hal ini dapat mempengaruhi hasil secara signifikan.

Guna memperoleh pemahaman praktikal tentang metode - metode ini, maka kita akan menerapkannya untuk memperoleh turunan pada suku banyak berikut ini pada titik $x=0.1$:

\begin{equation}
    f(x) = 0.1x^5 - 0.2 x^3 + 0.1x - 0.2
    \label{eq37}
\end{equation}

Kita dapat memperoleh solusi analitis-nya adalah sebagai berikut:

\begin{subequations}
    \begin{equation}
        f'(x) = 0.5x^4 - 0.6x^2 + 0.1
        \label{eq38c}
    \end{equation}
    \begin{equation}
        f''(x) = 2.0x^3 - 1.2x
        \label{eq38d}
    \end{equation}
\end{subequations}

Dengan mensubstitusikan nilai $x=0.1$, maka kita mendapatkan $f'(0.1) = 0.09405$ dan $f"(0.1) = -0.118$.

Berikut ini adalah implementasi numerik-nya di Python:

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

Hasil-nya adalah:

\nolinenumbers
\begin{verbatim}
    Solusi dari beda maju:
    f'(0.100000) = 0.090632
    f''(0.100000) = -0.172875

    Solusi dari beda tengah:
    f'(0.100000) = 0.093576
    f''(0.100000) = -0.117750

    Solusi dari beda mundur:
    f'(0.100000) = 0.096519
    f''(0.100000) = -0.059625
\end{verbatim}
\linenumbers

Dengan membandingkan nilai yang diperoleh dari solusi analitis, kita perhatikan bahwa metode beda tengah memberikan solusi paling akurat pada turunan pertama (galat 0,5\%), sementara metode beda maju dan mundur kurang akurat (masing - masing galat-nya 3,6\% dan 2,6\%). Kesimpulan serupa dapat diambil untuk turunan kedua juga.

Beriku adalah kode Python yang dapat kita terapkan untuk mengilustrasikan turunan pertama dan kedua dengan menggunakan beda tengah:

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


\begin{figure}[H]
    \centering
    \includegraphics[width=\textwidth]{gambar/gambar042.png}
    \caption{Representasi grafis turunan numerik menggunakan metode beda tengah pada domain [0, 1].}
    \label{fig42}
\end{figure}

Ketika fungsi \(f(x)\) diterjemahkan ke dalam kode Python, kenaikan nilai \(x\) tidak selalu sama dengan \textit{step size} turunan. Pada kode Python di atas, nilai-nilai \(x\) berkisar dari 0 hingga 1 dengan kenaikan 0,1, sementara \textit{step size} \(h\) adalah 0,05 (Gambar \ref{fig42}). Kenaikan \(x\) menentukan jumlah titik di mana turunan dikalkulasikan, sementara ukuran langkah memengaruhi akurasi turunan di setiap titik.

Bandingkan dengan fungsi \(f(x)\), jika kita diberikan suatu himpunan data dalam bentuk titik \( (x, y)\), interpolasi atau pencocokan kurva dapat diterapkan untuk menghasilkan suku banyak yang sesuai dengan titik - titik yang diberikan. Selanjutnya, suku banyak yang dihasilkan dapat dihitung turunannya secara analitis atau numerik untuk mendapatkan turunan yang diperlukan.

\section{Turunan Numerik Menggunakan SciPy}

Fungsi turunan numerik \verb|derivative()| dari modul \verb|scipy.misc| dapat digunakan untuk menghitung turunan ke-\verb|n| dari suatu fungsi pada \verb|x0| dengan menggunakan metode beda tengah dengan \textit{step size} \verb|dx|. Berikut adalah penerapannya di Python Shell:

\nolinenumbers
\begin{verbatim}
    >>> from scipy.misc import derivative
    >>> f = lambda x: 0.1*x**5 - 0.2*x**3 + 0.1*x - 0.2
    >>> y = derivative(f, 0.1, 0.05) # x0=0.1, dx=0.05, n=1 (default)
    >>> print(y)
    0.093575625
    >>> y2 = derivative(f, 0.1, 0.05,2) # n=2 untuk turunan kedua
    >>> print(y2)
    -0.11774999999999422
\end{verbatim}

Hasil ini sama dengan apa yang kita peroleh ketika menghitungnya dengan metode beda tengah secara manual sebelumnya. Untuk mengetahui lebih jauh tentang modul ini, kalian dapat berkunjung ke situs ini: \url{https://docs.scipy.org/doc/scipy/reference/generated/scipy.misc.derivative.html}.
\linenumbers

