Mencari Akar Persamaan Non-Linear Satu Variabel
Contents
Mencari Akar Persamaan Non-Linear Satu Variabel¶
Diberikan suatu fungsi bernilai real dan nonlinear \(f(x)\). Cari suatu akar \(p\) dari \(f(x)\) sedemikian sehingga \(f(p)=0\).
Contoh 1: Polinomial kuadratik: \(f(x)=x^2+5x+6\). \(𝑓(x)=(x+2)(x+3)=0⇒p_1=−2, p_2=−3\).
Contoh 2: \(f(x)=x^2+4x+10=(x+2)^2+6\). Tidak ada akar \(𝑝\) bernilai real yang memenuhi \(f(p)=0\).
Contoh 3: \(f(x)=x^2+\cos{x}+e^x+\sqrt{x+1}\). Akar bisa saja sulit untuk ditemukan secara analitik.
Fokus: menggunakan metode numerik untuk mengaproksimasi akar.
import matplotlib.pyplot as plt
import numpy as np
Metode Bisection¶
Diberikan \(f(x)\) kontinu di interval \([a,b]\) dengan \(f(a)\) dan \(f(b)\) memiliki tanda yang berlawanan. Tujuan: Cari \(a,b\) sedemikian sehingga \(f(a).f(b)<0\). Ini berarti terdapat akar \(p∈(a,b)\) sedemikian sehingga \(f(r)=0\).
Misalkan \(c=(a+b)/2\), titik tengah. Jika \(f(c)=0\), selesai. Jika tidak, periksa jika \(f(c).f(c)<0\) atau \(f(c).f(c)<0\). Pilih interval \([a,c]\) atau \([c,b]\), dan ulangi prosedur ini sampai memenuhi kriteria pemberhentian.
Kriteria Pemberhentian:
Interval cukup kecil
\(|f(c_n )|\) hampir \(0\)
Sudah mencapai iterasi maksimum
Kombinasi dari yang di atas.
Contoh 1:
Diberikan \(f(x) = x^3 + 4x^2 - 10\). Cari akar dari \(f(x)\) di interval \([1,2]\) menggunakan metode Bisection dengan \(\varepsilon = 10^{-4}\)
x = np.linspace(0, 10, 100)
fungsi = x**3 + 4*x**2 - 10.
g = np.zeros(x.size)
plt.figure(figsize=(8,6))
plt.plot(x, fungsi, x, g, 'r--')
plt.xlabel("$x$", fontsize=16)
plt.ylabel("$f$", fontsize=16)
plt.ylim([-1., 10])
plt.xlim([1., 2.])
plt.grid()
plt.legend("f", loc='best');
def bisection(func, a, b, epsilon=1e-4, N=1000):
f = func
FA = f(a)
for i in range(N):
p = a + (b-a)/2
FP = f(p)
print("iterasi {:2d}\t p = {:2.4f}\t f(p) = {:2.4f}\t a = {:2.4f}\t b = {:2.4f}".format(i, p, FP, a, b))
if np.abs(FP) <= epsilon or (b-a)/2 <= epsilon:
break
else:
if FA*FP > epsilon:
a = p
FA = FP
else:
b = p
return p,FP,a,b,i
f = lambda x: x**3 + 4*x**2 - 10
hasil = bisection(f, a=1, b=2, epsilon=1e-4, N=100)
print("p = {}, f(p) = {}, a = {}, b = {}, Total iterasi = {}".format(hasil[0], hasil[1], hasil[2], hasil[3], hasil[4]+1))
iterasi 0 p = 1.5000 f(p) = 2.3750 a = 1.0000 b = 2.0000
iterasi 1 p = 1.2500 f(p) = -1.7969 a = 1.0000 b = 1.5000
iterasi 2 p = 1.3750 f(p) = 0.1621 a = 1.2500 b = 1.5000
iterasi 3 p = 1.3125 f(p) = -0.8484 a = 1.2500 b = 1.3750
iterasi 4 p = 1.3438 f(p) = -0.3510 a = 1.3125 b = 1.3750
iterasi 5 p = 1.3594 f(p) = -0.0964 a = 1.3438 b = 1.3750
iterasi 6 p = 1.3672 f(p) = 0.0324 a = 1.3594 b = 1.3750
iterasi 7 p = 1.3633 f(p) = -0.0321 a = 1.3594 b = 1.3672
iterasi 8 p = 1.3652 f(p) = 0.0001 a = 1.3633 b = 1.3672
p = 1.365234375, f(p) = 7.202476263046265e-05, a = 1.36328125, b = 1.3671875, Total iterasi = 9
Contoh 2:
Diberikan \(f(x) = x^2 + 4x - 4\). Cari akar dari \(f(x)\) di interval \([0,5]\) menggunakan metode Bisection dengan \(\varepsilon = 10^{-4}\)
x = np.linspace(-20, 10, 100)
fungsi = x**2 + 4*x - 4.
g = np.zeros(x.size)
plt.figure(figsize=(8,6))
plt.plot(x, fungsi, x, g, 'r--')
plt.xlabel("$x$", fontsize=16)
plt.ylabel("$f$", fontsize=16)
plt.ylim([-1., 10])
plt.xlim([0, 5])
plt.grid()
plt.legend("f", loc='best');
f = lambda x: x**2 + 4*x - 4
hasil = bisection(f, a=0, b=5, epsilon=1e-4, N=100)
print("p = {}, f(p) = {}, a = {}, b = {}, Total iterasi = {}".format(hasil[0], hasil[1], hasil[2], hasil[3], hasil[4]+1))
iterasi 0 p = 2.5000 f(p) = 12.2500 a = 0.0000 b = 5.0000
iterasi 1 p = 1.2500 f(p) = 2.5625 a = 0.0000 b = 2.5000
iterasi 2 p = 0.6250 f(p) = -1.1094 a = 0.0000 b = 1.2500
iterasi 3 p = 0.9375 f(p) = 0.6289 a = 0.6250 b = 1.2500
iterasi 4 p = 0.7812 f(p) = -0.2646 a = 0.6250 b = 0.9375
iterasi 5 p = 0.8594 f(p) = 0.1760 a = 0.7812 b = 0.9375
iterasi 6 p = 0.8203 f(p) = -0.0458 a = 0.7812 b = 0.8594
iterasi 7 p = 0.8398 f(p) = 0.0647 a = 0.8203 b = 0.8594
iterasi 8 p = 0.8301 f(p) = 0.0093 a = 0.8203 b = 0.8398
iterasi 9 p = 0.8252 f(p) = -0.0183 a = 0.8203 b = 0.8301
iterasi 10 p = 0.8276 f(p) = -0.0045 a = 0.8252 b = 0.8301
iterasi 11 p = 0.8264 f(p) = -0.0114 a = 0.8252 b = 0.8276
iterasi 12 p = 0.8270 f(p) = -0.0079 a = 0.8264 b = 0.8276
iterasi 13 p = 0.8267 f(p) = -0.0096 a = 0.8264 b = 0.8270
iterasi 14 p = 0.8269 f(p) = -0.0088 a = 0.8267 b = 0.8270
iterasi 15 p = 0.8268 f(p) = -0.0092 a = 0.8267 b = 0.8269
p = 0.8267974853515625, f(p) = -0.009215976810082793, a = 0.82672119140625, b = 0.826873779296875, Total iterasi = 16
Analisis Kekonvergenan Metode Bisection¶
Diberikan suatu fungsi nonlinear \(f(x)\) kontinu di \([a,b]\) dan \(\text{sgn}(f(a)) \neq \text{sgn}(f(b))\). Kita misalkan \(a_0 = a\) dan \(b_0=b\) sebagai interval pada iterasi ke 0 dari metode bisection, sehingga terdapat \(c_0 = \frac{a_0+b_0}{2}\) adalah nilai tengah dari \([a_0, b_0]\). Maka kita definisikan error untuk iterasi ke-0 dari metode bisection, yaitu:
dimana \(p\) adalah akar dari \(f(x)\). Kemudian kita tuliskan \(c_n = \frac{a_n + b_n}{2}\) adalah nilai tengah dari \([a_n, b_n]\) pada iterasi ke-\(n\), maka error yang dihasilkannya adalah
Jika diberikan toleransi error \(\varepsilon \rightarrow 0\), maka haruslah \(e_n \leq \varepsilon\). Sehingga
Jadi, iterasi minimum yang dibutuhkan metode bisection untuk konvergen ke solusi (akar) adalah
\[n \geq \frac{\log{(b-a)} - \log{2\varepsilon}}{\log{2}}.\]
Iterasi Minimum Bisection
Jika diberikan \(f(x)\) kontinu di \([a,b]\) dan \(\text{sgn}(f(a)) \neq \text{sgn}(f(b))\), maka iterasi minimum yang dibutuhkan oleh Metode Bisection untuk mendapatkan solusi adalah
Contoh 3
Dari contoh 2, kita ingin melihat berapa iterasi minimum yang dibutuhkan metode bisection untuk mendapatkan akar/solusi menggunakan analisis kekonvergenan yang sudah dituliskan sebelumnya.
Jawaban:
\(n \geq \frac{\log{(5-0)} - \log{2\cdot 10^{-4}}}{\log{2}}\)
\(\Rightarrow n \geq \frac{4.398}{0.301} = 14.611 \approx 14.\)
Jadi iterasi minimum yang dibutuhkan adalah 14 iterasi.
Iterasi Fixed Point¶
Definisi: Suatu bilangan \(p\) adalah fixed point untuk suatu fungsi \(g\) jika \(g(p) = p\). Diberikan suatu fungsi \(f(x)\) kontinu, untuk suatu \(p\) maka \(f(p) = 0\). Kemudian kita definisikan fungsi \(g\) dan kita tuliskan $\( \begin{array}{cc} x = x + f(x) = g(x) & & x=x-f(x)=g(x) \end{array} \)$
Terdapat akar \(p = g(p)\), dimana \(p\) adalah fixed point. Kemudian dengan tebakan awal \(x_0\), hitung \(g(x_0)\), dan harapannya untuk setiap iterasi \(x_k = g(x_{k-1})\) menuju ke \(p\).
Stopping criteria:
\(|x_k - x_{k-1}| \leq \varepsilon\) atau \(|g(x_k) - x_{k-1}| \leq \varepsilon\)
Iterasi maksimum terpenuhi.
def iterasi_fixed_point(func, p0, N=100, epsilon=1e-5):
print(' p\t\t g(p) \tresidual')
print('------------------------------------------------')
g = func
for i in range(N):
p = g(p0)
if (np.abs(p-p0) < epsilon):
break
print('{:8.4f}\t{:10.4f}\t{:10.4f}\t'.format(p, g(p), np.abs(p-p0)))
p0 = p
return p
Contoh 1¶
Carilah akar dari \(f(x)=x−\cos{(x)}\) dengan akurasi 4-digit
x = np.linspace(0, 1.2, 100)
g = np.cos(x)
plt.figure(figsize=(8,6))
plt.plot(x, g, x, x, 'r--')
plt.xlabel('x', fontsize=16)
plt.ylabel("$f$, $g$", fontsize=16)
# plt.ticklabel_format(axis='y', style='sci', scilimits=(-1,1))
plt.ylim([0.1, 1.1])
plt.xlim([0.1, 1.2])
plt.grid()
plt.legend(["$f$", "$g$"], loc='best');
g = lambda x: np.cos(x)
iterasi_fixed_point(g, p0=0)
p g(p) residual
------------------------------------------------
1.0000 0.5403 1.0000
0.5403 0.8576 0.4597
0.8576 0.6543 0.3173
0.6543 0.7935 0.2033
0.7935 0.7014 0.1392
0.7014 0.7640 0.0921
0.7640 0.7221 0.0626
0.7221 0.7504 0.0419
0.7504 0.7314 0.0283
0.7314 0.7442 0.0190
0.7442 0.7356 0.0128
0.7356 0.7414 0.0086
0.7414 0.7375 0.0058
0.7375 0.7401 0.0039
0.7401 0.7384 0.0026
0.7384 0.7396 0.0018
0.7396 0.7388 0.0012
0.7388 0.7393 0.0008
0.7393 0.7389 0.0005
0.7389 0.7392 0.0004
0.7392 0.7390 0.0002
0.7390 0.7391 0.0002
0.7391 0.7391 0.0001
0.7391 0.7391 0.0001
0.7391 0.7391 0.0001
0.7391 0.7391 0.0000
0.7391 0.7391 0.0000
0.7391 0.7391 0.0000
0.7391 0.7391 0.0000
0.7390822985224023
Contoh 2¶
Selesaikan \(f(x)=e^{-2x}\cdot (x-1)\)
Kita pilih: \(g(x) = e^{-2x}\cdot (x-1) + x\)
x = np.linspace(0.1, 1., 1000)
f = np.exp(-2*x) * (x-1)
g = np.exp(-2*x) * (x-1) + x
plt.figure(figsize=(8, 6))
plt.plot(x, g, 'b', x, x, 'g--')
plt.xlabel('x', fontsize=16)
plt.ylabel("$f$, $g$", fontsize=16)
plt.ylim([0.99999, 1.0])
plt.xlim([0.99999, 1.0])
plt.grid()
plt.legend(["$f$", "$g$"], loc='best');
import sympy
sympy.init_printing(pretty_print=True)
x = sympy.symbols('x')
g_simbol = sympy.exp(-2*x) * (x-1) + x
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
-2*(x - 1)*exp(-2*x) + 1 + exp(-2*x)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
1.1353352832366128
g = lambda x: np.exp(-2*x) * (x-1) + x
iterasi_fixed_point(g, 0)
p g(p) residual
------------------------------------------------
-1.0000 -15.7781 1.0000
-15.7781 -850035804379802.7500 14.7781
-850035804379802.7500 -inf 850035804379787.0000
-inf -inf inf
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
-inf -inf nan
/var/folders/d8/_nrt2sy9567f87n08gxx0xc00000gn/T/ipykernel_2476/3427404320.py:1: RuntimeWarning: overflow encountered in exp
g = lambda x: np.exp(-2*x) * (x-1) + x
/var/folders/d8/_nrt2sy9567f87n08gxx0xc00000gn/T/ipykernel_2476/1089591089.py:7: RuntimeWarning: invalid value encountered in double_scalars
if (np.abs(p-p0) < epsilon):
/var/folders/d8/_nrt2sy9567f87n08gxx0xc00000gn/T/ipykernel_2476/1089591089.py:9: RuntimeWarning: invalid value encountered in double_scalars
print('{:8.4f}\t{:10.4f}\t{:10.4f}\t'.format(p, g(p), np.abs(p-p0)))
Analisis Kekonvergenan Iterasi Fixed Point¶
Misalkan \(p\) adalah akar sedemikian sehingga \(p=g(p)\). Kemudian, kita tulis iterasi fixed point \(x_k = g(x_{k-1})\) dan definisikan error
maka
Berdasarkan Teorema Nilai Rataan, maka didapat
Kemudian, kedua ruas kita mutlakan
atau berdasarkan pertidaksamaan segitiga, maka dapat ditulis sebagai
Observasi:
Jika \(|g'(\xi)|< 1\), maka error akan berkurang.
Jika \(|g'(\xi)|> 1\), maka error akan bertambah.
Dengan demikian, kita pilih \(|g'(\xi)|< 1\) sedemikian sehingga
\[|e_k| \leq |g'(\xi)||(e_{k-1})|, \hspace{10mm} \xi \in (x_{k-1}, p).\]
Dan dapat disimpulkan tingkat konvergensi dari iterasi fixed point adalah linear.
Remark. Jika diketahui untuk suatu \(g(x)\), terdapat akar di \(p\in[a,b]\), maka nilai \(|g'(\xi)|\) dapat kita tentukan dengan cara memilih interval \(\xi \in [a,b]\) sedemikian sehingga
Perbaikan
Pilih: \(g(x) = -e^{-2x}\cdot (x-1) + x\)
x = sympy.symbols('x')
g_simbol = -sympy.exp(-2*x) * (x-1) + x
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
-2*(1 - x)*exp(-2*x) + 1 - exp(-2*x)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
0.8646647167633873
g = lambda x: -np.exp(-2*x) * (x-1) + x
iterasi_fixed_point(g, 0)
p g(p) residual
------------------------------------------------
1.0000 1.0000 1.0000
Dari Contoh 2 maka dapat disimpulkan bahwa pemilihan \(g(x)\) berpengaruh terhadap solusi.
Contoh 3:¶
Diberikan \(f(x) = x^3 + 4x^2 - 10\) terdapat akar tunggal untuk \(f(x) = 0\) di \([1,2]\). Kita dapat membuat beberapa bentuk \(g(x)\) menggunakan manipulasi aljabar dari persamaan \(x^3 + 4x^2 - 10 = 0\). Sehingga kita mendapatkan
Berikut adalah beberapa variasi bentuk \(g(x)\) yang mungkin untuk persamaan \(x^3 + 4x^2 - 10 = 0\):
\(g_1(x) = x - x^3 - 4x^2 + 10\)
\(g_2(x) = \sqrt{ \frac{10}{x} - 4x}\) (hati-hati!)
\(g_3(x) = \frac{1}{2} \sqrt{10-x^3}\) (hati-hati!)
\(g_4(x) = \sqrt{\frac{10}{4+x}}\)
\(g_5(x) = x - \frac{x^3 + 4x^2 - 10}{3x^2 + 8x}\)
x = np.linspace(1, 2, 100)
g1 = x - x**3 - 4*x**2 + 10
#g2 = np.sqrt((10/4) - 4*x)
g3 = 0.5 * np.sqrt(10 - x**3)
g4 = np.sqrt(10/(4+x))
g5 = x - ((x**3 + 4*x**2 - 10)/(3*x**2 + 8*x))
plt.figure(figsize=(8,6))
plt.plot(x, g5, x, x, 'r--')
plt.xlabel('x', fontsize=16)
plt.ylabel("$f$, $g$", fontsize=16)
# plt.ticklabel_format(axis='y', style='sci', scilimits=(-1,1))
plt.ylim([-2, 2.5])
plt.xlim([1, 2])
plt.grid()
plt.legend(["$f$", "$g$"], loc='best');
Cek nilai \(|g'(x)|\) untuk masing-masing \(g_1, g_2, g_3, g_4, g_5\).
# g1
x = sympy.symbols('x')
g_simbol = x - x**3 - 4*x**2 + 10
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
-3*x**2 - 8*x + 1
10
# g3
x = sympy.symbols('x')
g_simbol = 0.5 * sympy.sqrt(10 - x**3)
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
-0.75*x**2/sqrt(10 - x**3)
0.25
# g4
x = sympy.symbols('x')
g_simbol = sympy.sqrt(10/(4+x))
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
-sqrt(10)*sqrt(1/(x + 4))/(2*(x + 4))
0.1414213562373095
# g5
x = sympy.symbols('x')
g_simbol = x - ((x**3 + 4*x**2 - 10)/(3*x**2 + 8*x))
g_aksen = sympy.diff(g_simbol, x)
print(g_aksen)
ksi = 1
g_aksen_eval = sympy.lambdify(x, g_aksen, "numpy")
print(np.abs(g_aksen_eval(ksi)))
-(-6*x - 8)*(x**3 + 4*x**2 - 10)/(3*x**2 + 8*x)**2
0.5785123966942148
Hasil iterasi fixed point untuk \(g_1, g_2, g_3, g_4, g_5\):
g1 = lambda x: x - x**3 - 4*x**2 + 10
g3 = lambda x: 0.5 * np.sqrt(10 - x**3)
g4 = lambda x: np.sqrt(10/(4+x))
g5 = lambda x: x - ((x**3 + 4*x**2 - 10)/(3*x**2 + 8*x))
iterasi_fixed_point(g1, 1)
p g(p) residual
------------------------------------------------
6.0000 -344.0000 5.0000
-344.0000 40233906.0000 350.0000
40233906.0000 -65129333514558058266624.0000 40234250.0000
-65129333514558058266624.0000 276267566256213176812460591377636390697531392742540224134413008502784.0000 65129333514558100209664.0000
276267566256213176812460591377636390697531392742540224134413008502784.0000 -21085781678484218373029710589143631921317875000289319058960190154839362740347082366049129581190236367284319210288916507514866804543042709750411734218555823868097599405777061398665815022859218193480385822720.0000 276267566256213176812460591377636390697531392742540224134413008502784.0000
---------------------------------------------------------------------------
OverflowError Traceback (most recent call last)
Input In [23], in <module>
3 g4 = lambda x: np.sqrt(10/(4+x))
4 g5 = lambda x: x - ((x**3 + 4*x**2 - 10)/(3*x**2 + 8*x))
----> 6 iterasi_fixed_point(g1, 1)
Input In [7], in iterasi_fixed_point(func, p0, N, epsilon)
7 if (np.abs(p-p0) < epsilon):
8 break
----> 9 print('{:8.4f}\t{:10.4f}\t{:10.4f}\t'.format(p, g(p), np.abs(p-p0)))
10 p0 = p
11 return p
OverflowError: int too large to convert to float
iterasi_fixed_point(g4, 1)
p g(p) residual
------------------------------------------------
1.4142 1.3590 0.4142
1.3590 1.3660 0.0552
1.3660 1.3651 0.0070
1.3651 1.3652 0.0009
1.3652 1.3652 0.0001
1.3652 1.3652 0.0000
iterasi_fixed_point(g5, 1)
p g(p) residual
------------------------------------------------
1.4545 1.3689 0.4545
1.3689 1.3652 0.0856
1.3652 1.3652 0.0037
Metode Newton¶
Metode Newton atau yang lebih dikenal sebagai Newton-Raphson adalah salah satu metode yang powerful untuk menyelesaikan masalah pencarian akar pada persamaan nonlinear.
Metode ini dibentuk dengan memanfaatkan polinomial Taylor order pertama untuk merepresentasikan suatu fungsi \(f(x)\).
Definisi: Diberikan \(f\in C^2[a,b]\) dan terdapat \(p_0 \in [a,b]\) sebagai nilai aproksimasi untuk akar \(p\) sedemikian sehingga \(f'(p_0) \neq 0\) dan \(|p-p_0|\) kecil. Perhatikan polinomial Taylor order pertama untuk suatu \(f(x)\) terhadap titik \(p_0\) dan \(x = p\),
Karena \(p\) adalah akar maka \(f(p)=0\),
Karena diasumsikan \(|p-p_0|\) kecil, maka \((p-p_0)^2 \approx 0\), sehingga
atau
Dengan tebakan awal \(p_0\), kita dapatkan suatu barisan solusi \(\{p_k\}_{k=0}^{\infty}\), sehingga bentuk iteratif untuk metode Newton dapat kita tuliskan
untuk \(k = 1,2,\cdots\).
Stopping Criteria:
\(|p_k - p_{k-1}| < \varepsilon\)
\(\frac{|p_k - p_{k-1}|}{|p_k|} < \varepsilon\)
\(|f(p_k)| < \varepsilon\)
iterasi maksimum sudah terpenuhi.
Implementasi Metode Newton¶
def newton(func, dfunc, p0, N=100, epsilon=1e-5):
print(' p\t\t f(p) \tresidual')
print('------------------------------------------------')
f = func
df = dfunc
for i in range(N):
p = p0 - f(p0)/df(p0)
if (np.abs(p-p0) < epsilon):
break
print('{:8.4f}\t{:10.4f}\t{:10.5E}\t'.format(p, f(p), np.abs(p-p0)))
p0 = p
return p
Contoh 1:
Tentukan akar dari fungsi \(f(x)=\cos(x) - x\).
f = lambda x: np.cos(x) - x
X = np.linspace(-10,10, 100)
g = np.zeros(X.size)
plt.plot(X,g);
plt.plot(X, f(X), label='$f(x)$');
plt.legend();
Implementasikan metode newton untuk mencari akar dari \(f(x)\). Pertama, kita cari \(f'(x)\) terlebih dahulu
x = sympy.symbols('x')
f_simbol = sympy.cos(x) - x
f_diff = sympy.diff(f_simbol, x)
f_aksen = sympy.lambdify(x, f_diff, "numpy")
Kemudian pilih tebakan awal, misal \(p_0=1\) dan cari akar menggunakan metode Newton
p0 = 1
p = newton(f, f_aksen, p0, epsilon=1e-10)
p f(p) residual
------------------------------------------------
0.7504 -0.0189 2.49636E-01
0.7391 -0.0000 1.12510E-02
0.7391 -0.0000 2.77575E-05
0.7391 0.0000 1.70123E-10
X = np.linspace(-10,10, 100)
g = np.zeros(X.size)
plt.plot(X,g);
plt.plot(X, f(X), label='$f(x)$');
plt.annotate('p = {:4.4f}'.format(p),(p+0.5,0.5))
plt.scatter(p, 0, color='red');
plt.legend();
Analisis Kekonvergenan Metode Newton¶
Misalkan \(p\) adalah akar sehingga \(f(p)=0\) dan \(p=g(p)\). Definisikan error
Berdasarkan Ekspansi Taylor untuk \(g(p_{k-1})\) di \(x=p\), maka
Pandang sebagai fixed point yang ‘optimal’
maka
Jika kita asumsikan \(p\) adalah akar maka \(f(p) = 0\) sehingga
Dengan demikian, karena \(g'(p)=0\) maka
Subtitusikan bentuk \(g(p_{k-1})\) ke persamaan \(e_k\), maka didapat
Jika kita misalkan \(M = \left| \frac{g''(\xi)}{2} \right|\) maka
\[ e_k \leq M e_{k-1}^{2} \]
Jadi, tingkat konvergensi dari metode Newton adalah kuadratik.
Metode Secant¶
Kelemahan dari metode Newton adalah kita perlu untuk mencari turunan dari \(f(x)\). Hal ini dapat menimbulkan masalah jika kita menemukan bentuk \(f(x)\) yang kompleks atau dengan kata lain turunannya sulit ditemukan. Berdasarkan definisi dari turunan,
kita dapat mengaproksimasi turunan dari \(f(x)\) yaitu
Panggil skema iterasi Newton:
Jika terdapat \(p_{k-2}\) yang dekat dengan \(p_{k-1}\), maka
Kemudian subtitusikan \(f'(p_{k-1})\) ke skema iterasi Newton, maka kita dapatkan skema iterasi untuk Metode Secant
Catatan: Metode Secant membutuhkan dua tebakan awal \(p_0\) dan \(p_1\) yang dekat.
Implementasi Metode Secant¶
def secant(func, p0, p1, N=100, epsilon=1e-5):
print(' p\t\t f(p) \tresidual')
print('------------------------------------------------')
q0 = func(p0)
q1 = func(p1)
for i in range(N):
p = p1 - q1*(p1-p0)/(q1-q0)
if (np.abs(p-p1) < epsilon):
break
print('{:8.4f}\t{:10.4f}\t{:10.5E}\t'.format(p, f(p), np.abs(p-p0)))
p0 = p1
q0 = q1
p1 = p
q1 = func(p)
return p
Contoh 1
Tentukan akar dari fungsi \(f(x)=\cos(x) - x\)
f = lambda x: np.cos(x) - x
p0 = 0
p1 = 1
p = secant(f, p0, p1, epsilon=1e-10)
p f(p) residual
------------------------------------------------
0.6851 0.0893 6.85073E-01
0.7363 0.0047 2.63701E-01
0.7391 -0.0001 5.40460E-02
0.7391 0.0000 2.78611E-03
0.7391 0.0000 3.42287E-05