# PRAKTIKUM 9
`Turunan Numerik`

<hr style="border:2px solid black"> </hr>


```julia
using Plots
```

# Definisi Limit Turunan dan Hampiran Turunan
Diberikan suatu fungsi $f(x)$. Turunan fungsi $f$ pada suatu titik $x=a$ disimbolkan sebagai $f'(a)$, didefinisikan sebagai :

$$ f'(a)=\lim_{h\to 0}⁡ \frac{f(a+h)-f(a)}{h} $$

Untuk menghampiri nilai turunan numerik dari $ f(x) $, akan dipilih barisan $ {h_k} $ sedemikian sehingga $ h_k\to 0 $ dan hampiran $ f'(x) $ adalah

\begin{equation}\label{eq:9 lim2}
D_k = \dfrac{f(x+h_k)-f(x)}{h_k} \ \ \ \ \ \ \text{untuk}\ \ \ k = 1, 2, \dots, n, \dots \text{dan } h_k = 10^{-k}
\end{equation}

Proses komputasi hanya akan menghitung nilai $ D_1 $, $ D_2 $, $\dots$, $ D_N $ dan menggunakan nilai $ D_N $ sebagai nilai turunan numerik $ f'(x) $. Pertanyaan yang muncul dalam proses numerik ini adalah berapa nilai $ h_N $ yang harus dipilih, sehingga $ D_N $ menjadi nilai hampiran turunan $ f'(x) $ yang baik.

### Contoh 1

Berikut merupakan hampiran $D_k$ dari turunan $f'(x)$ dengan $f(x)=\exp(x)$ ketika $x=1$. Secara analitik nilai $f'(x) = \exp(x)$ sehingga $f'(1)=e$.

|$h_k$|$D_k$|$ \mid D_k-e \mid $|
|--|--|------|
| 1e-1 | 2.85884195 | 0.14056013 |
| 1e-2 | 2.73191866 | 0.01363683 |
| 1e-3 | 2.71964142 | 0.00135959 |
| 1e-4 | 2.71841775 | 0.00013592 |
| 1e-5 | 2.71829542 | 0.00001359 |
| 1e-6 | 2.71828319 | 0.00000136 |
| 1e-7 | 2.71828197 | 0.00000014 |
| 1e-8 | 2.71828182 | 0.00000001 |
| 1e-9 | 2.71828204 | 0.00000022 |
| 1e-10 | 2.71828338 | 0.00000155 |

Akan tetapi semakin kecil nilai $h_k$ tidak menjamin hampiran turunan semakin baik. Dengan demikian, tujuan dari turunan numerik adalah mencari nilai $h_k$ sedemikian sehingga galat yang dihasilkan sekecil mungkin.


```julia
k = 1:10
h = 10.0 .^ -k
f(x) = exp.(x);
a = 1;
Dk = (f(a.+h) .- f(a))./h;
M = [k Dk abs.(Dk.-exp(a))]
```

#### Contoh lain:
Bagaimana dengan turunan $f(x)=\sin(x)$ ketika $x=\pi/3$?


```julia
k = 0:10
h = 10.0.^-k;
f(x) = sin.(x);
a = pi/3;
Dk = (f(a.+h).-f(a))./(h);
M = [k Dk abs.(Dk.-cos(a))]
```

# Hampiran Beda Pusat
Penghitungan turunan numerik menggunakan definisi turunan membutuhkan iterasi yang
cukup banyak karena hanya memiliki kompleksitas komputasi $ O(h) $. Oleh karena itu, diperlukan pengembangan formula yang dapat memberikan nilai akurasi yang baik dengan nilai $ h $ yang lebih besar. Jika fungsi $ f(x) $ dapat dievalusi pada nilai yang terletak disebelah kanan dan kiri dari $ x $, maka formula beda-pusat dapat digunakan untuk menghitung nilai turunan $ f'(x) $.
## Teorema
Asumsikan bahwa $ f\in C^3[a,b] $ dan $ x-h,x,x+h\in [a,b] $, maka
\begin{equation}\label{eq:9 beda1}
f'(x)\approx \dfrac{f(x+h)-f(x-h)}{2h}
\end{equation}
Selain itu, terdapat nilai $ c=c(x)\in [a,b] $ yang menyebabkan 
\begin{equation}\label{eq:9 beda2}
f'(x)= \dfrac{f(x+h)-f(x-h)}{2h}+E_{trunc}(f,h)
\end{equation}
dengan
\begin{equation}\label{eq:9 beda3}
E_{trunc}(f,h)=-\dfrac{h^2f^{(3)}(c)}{6}=O(h^2)
\end{equation}
Bentuk $ E(f,h) $ disebut sebagai _truncation error_.

### Contoh 2
Seperti sebelumnya, berikut hampiran $D_k$ dari turunan $f'(x)$ dengan $f(x)=\sin(x)$ ketika $x=\pi/3$ menggunakan beda-pusat.


```julia
k = 1:10
h = 10.0 .^-k;
f(x) =  sin.(x);
a = pi/3;
Dk = (f(a.+h).-f(a.-h))./(2*h);
M = [k Dk abs.(Dk.-cos(a))]
```

Akan tetapi cara tersebut menjadi tidak praktis karena nilai turunan ditentukan secara manual. Dengan demikian, untuk menentukan nilai $h_k$ dapat dicari menggunakan iterasi dengan 2 kriteria penghentian yaitu
1. galat telah memenuhi toleransi
2. galat sekarang lebih besar daripada galat sebelumnya


```julia
function bedaPusat(f, a; delta=10^-9)
  # Definisikan nilai maksimum iterasi dan toleransi
  maxi = 15;
  flag = 1;
  # Hitung nilai awal turunan numerik ketika h=1, galat awal tidak ada.
  h = 1;
  D = (f(a+h)-f(a-h))/(2*h);
  E = NaN;
  sol = NaN
  # Mulai proses iterasi untuk mencari nilai turunan numerik.
  for k = 1:maxi
    h = h/10;
    D = [D (f(a+h)-f(a-h))/(2*h)]
    E = [E abs(D[k+1]-D[k])]
    # Cek apakah nilai galat telah memenuhi toleransi.
    if E[k+1]<delta
      flag = 0;
      sol = D[end];
      break
    end
    # Cek apakah galat sekarang lebih besar daripada galat sebelumnya.
    if E[k+1]>E[k]
      sol  = D[k];
      flag = 2;
      break
    end
  end
  L = [D' E'];
  return sol, flag, L
end
```

### Contoh 3
#### 1 Turunan pada suatu titik fungsi kontinu

Diberikan fungsi $f(x)=\sin(x)$. Hitung hampiran $D_k$ dari turunan $f'(x)$ ketika $x=\pi/3$ menggunakan beda-pusat


```julia
f(x) = sin(x);
a = pi/3;
sol,flag,L = bedaPusat(f,a)
@show sol
L
```


```julia
f(x) = sin(x);
a = pi/3;
sol,flag,L = bedaPusat(f,a,delta = 10^-12)
@show sol
L
```

#### 2 Turunan pada suatu titik fungsi diskret

Diberikan data yaitu $I(t)$ bergantung pada $t$ sebagai berikut.

|$t$	| 1.0 	 |1.1 	 |1.2	 |1.3 	 |1.4   |
|--|--|--|--|--|--|
|$I(t)$ | 8.2277 |7.2428 |5.9908 |4.5260 |2.9122|

Berapa nilai $I'(1.2)$ yang dihasilkan oleh metode beda-pusat $ h=0.1 $ dan $ h=0.2 $

$$i1 = \frac{f(1.2+0.1)-f(1.2-0.1)}{2 (0.1)} = \frac {f(1.3) - f(1.1)}{ 0.2} $$


```julia
i1 = (4.5260 - 7.2428)/0.2
```

$$i2 = \frac{f(1.2+0.2)-f(1.2-0.2)}{2 (0.2)} = \frac {f(1.4) - f(1.0)}{ 0.4} $$


```julia
i2 = (2.9122 - 8.2277)/0.4
```

#### 3 Turunan numerik dari fungsi pada interval tertentu

Diberikan fungsi $f(x)=\sin(x)$. Hitung hampiran $D_k$ dari turunan $f'(x)$ ketika $x=[0,2\pi]$ menggunakan beda-pusat


```julia
f(x) = sin.(x);
a = 0:0.01:2*pi
y = Array{Number}(undef,length(a),1)
for i in 1:length(a)
    sol,flag,L = bedaPusat(f,a[i]);
    y[i] = sol;
end
plt=plot(a,y,legend=:false)
```

## Beda Pusat Ordo $O(h^4)$
Asumsikan bahwa $ f\in C^5[a,b] $ dan $ x-2h,x-h,x,x+h,x+2h \in [a,b] $, maka

\begin{equation}
	f'(x)\approx \dfrac{-f(x+2h)+8f(x+h)-8f(x-h)+f(x-2h)}{12h}
\end{equation}


```julia
k = 1:10
h = 10.0 .^-k;
f(x) = sin.(x);
a = pi/3;
Dk = (-f(a.+2*h).+8*f(a.+h).-8*f(a.-h).+f(a.-2*h))./(12*h);
M = [k Dk abs.(Dk.-cos(a))]
```

# Ekstrapolasi Richardson
Metode alternatif lain yang dapat digunakan untuk mencari nilai turunan numerik adalah menggunakan ekstrapolasi Richardson. Metode ini merupakan modifikasi dari metode beda-pusat untuk menghasilkan kompleksitas yang lebih baik. Dengan memanfaatkan kompleksitas beda-pusat yaitu $ O(h^2) $, ekstrapolasi Richardson dapat menghitung solusi numerik dengan kompleksitas $ O(h^4) $, $ O(h^6) $, dan seterusnya.
### Teorema
Misalkan bahwa terdapat dua hampiran $ f'(x_0) $ dengan ordo $ O(h^{2k}) $ yaitu $ D_{k-1}(h) $ dan $ D_{k-1}(2h) $, sehingga memenuhi 

\begin{align} 
f'(x_0)&=D_{k-1}(h)+Ch^{2k}+\dots
\end{align}

dan

\begin{align} 
f'(x_0)&=D_{k-1}(2h)+4^kCh^{2k}+\dots
\end{align}

Selanjutnya, hampiran dengan ordo $ O(h^{2k+2}) $ dapat diperoleh dengan formula

\begin{equation}\label{eq:9 rich7}
f'(x_0)=D_k(h)+O(h^{2k+2})=\dfrac{4^kD_{k-1}(h)-D_{k-1}(2h)}{4^k-1}+O(h^{2k+2})
\end{equation}

Dari contoh sebelumnya bagian 2, diperoleh $D_1(1)$ dan $D_1(2)$, maka $D_2(1)$ adalah


```julia
i1 = -13.584 # Beda Pusat O(h^2) dengan h = 0.1
i2 = -13.289 # Beda Pusat O(h^2) dengan h = 0.2
(4*i1-i2)/3  # Beda Pusat O(h^4) dengan h = 0.1
```


```julia
function richardson(f, a; delta = 1e-9)
  # Definisikan nilai maksimum iterasi dan toleransi
  maxi = 50;
  flag = 1;
  # Hitung nilai awal matriks richardson ketika h=1
  h = 1;
  D = (f(a+h)-f(a-h))/(2*h);
  err = NaN;
  # Mulai iterasi richardson
  for j=1:maxi
    # Perkecil h menjadi 1/2 h sebelumnya, kemudian hitung kolom ke-1
    # richardson dengan beda-pusat.
    h = h/2;
    D = [D zeros(size(D,1),1); 
        (f(a.+h).-f(a.-h))./(2*h) zeros(1, size(D,1))];
    # Hitung nilai kolom selanjutnya menggunakan rumus richardson.
    for k = 1:j
      D[j+1,k+1] = D[j+1,k] + (D[j+1,k]-D[j,k])/(4^k-1);
    end
    # Hitung nilai galat, jika galat telah memenuhi toleransi, maka 
    # iterasi dihentikan.
    err = abs(D[j+1,j+1]-D[j,j]);
    if err<delta
      flag=0;
      break
    end
  end
  sol = D[end,end];
  return sol, flag, err, D 
end
```

### Contoh 4
#### Turunan pada suatu titik fungsi kontinu

Diberikan fungsi $f(x)=\sin(x)$. Hitung hampiran dari turunan $f'(x)$ ketika $x=\pi/3$ menggunakan ekstrapolasi Richardson.


```julia
using BenchmarkTools
```


```julia
f(x) = sin.(x);
a = pi/3;
@btime sol,flag,err,D = richardson(f,a)
@show sol
@show err
D
```


```julia
f(x) = sin.(x);
a = pi/3;
@btime sol,flag,err,D = richardson(f,a,delta=10^-16)
@show sol
@show err
;
```

<hr style="border:2px solid black"> </hr>

# Soal Latihan
Kerjakan soal berikut pada saat kegiatan praktikum berlangsung.

`Nama: ________`

`NIM: ________`

### Soal 1
Hitung nilai turunan numerik $ f'(1) $ dari $ f(x)=\sin(x) $, yaitu $ D_k $ untuk $ k=1,2,3,\dots,10 $ menggunakan formula beda-maju dan beda-pusat. Tentukan nilai $k$ yang memberikan galat paling minimum.


```julia

```

### Soal 2
Diketahui fungsi $ f(x)=\cos(x) $. Gunakan metode beda pusat menggunakan fungsi `bedaPusat` untuk mencari turunan numerik dari $ f'(0.2) $ dengan galat paling minimum.


```julia

```

### Soal 3
Diketahui fungsi $ f(x)=\cos(x) $. Gunakan metode beda pusat menggunakan fungsi `bedaPusat` untuk mencari solusi turunan numerik pada interval $ [0,2\pi] $. 


```julia

```

### Soal 4
Diketahui fungsi $ f(x)=\cos(x) $. Gunakan ekstrapolasi Richardson pada fungsi `richardson` untuk mencari turunan numerik dari $ f'(0.2) $ dengan mengatur toleransi yaitu $ \delta=10^{-k} $ dan $ k=5,6,7,...,16 $. Bandingkan waktu yang diperlukan untuk mencari turunan tersebut menggunakan `BenchmarkTools`.


```julia

```

9cb616598b33370d6a466bbba7539805127ae904
ipynb
Jupyter Notebook
notebookpraktikum/Praktikum 09.ipynb
mkhoirun-najiboi/metnum.jl
a6e35d04dc277318e32256f9b432264157e9b8f4
MIT
notebookpraktikum/Praktikum 09.ipynb
mkhoirun-najiboi/metnum.jl
a6e35d04dc277318e32256f9b432264157e9b8f4
MIT
notebookpraktikum/Praktikum 09.ipynb
mkhoirun-najiboi/metnum.jl
a6e35d04dc277318e32256f9b432264157e9b8f4
MIT
Qwen/Qwen-72B
1. YES
2. YES