# Gyakorlat 2019. 04. 10.
close all
output_precision(15)

disp("Gyakorlat 2019. 04. 10.");

disp("\n\
Nemlinaris egyenlet numerikus megoldasa: f(x) = 0, x = ?")

disp("\n\
A bezaro algoritmusok mindig mukodnek.\n\
A fixpont iteracio egyszeru.\n\n\
Alapvetoen ezek a modszerek lassu konvergenciahoz vezetnek.\n\n\
A gyakorlatban Newton(-Raphson) modszeret hasznaljuk az f(x) = 0\n\
egyenlet megoldasara.")

disp("\n\n\
Newton modszere f(x) = 0 megoldasara")
disp("------------------------------------")
disp("x_{k+1} = x_{k} - f(x_k) / f'(x_k)\n")

disp("\n\n\
A modszer jelentese: az f(x) fuggveny grafikonjahoz az (x0, f(x0))\n\
pontba huzott erinto x tengellyel vett metszespontja lesz a kovetkezo\n\
becsles.\n\n\
A modszer keplete ennek a metszespontnak a kiszamolasabol kovetkezik.")

disp("\n\
Newton modszeret alkalmazva oldjuk meg a kovetkezo problemakat:")

###########################################################################

disp("\n\n\
1. Feladat\n\
Talaljuk meg x^2 - sin(x) = 0 megoldasait")
f = @(x) x.^2 - sin(x)

figure (1);
x = -100 : 0.1 : 100;
plot(x, f(x));
title("x^2 - sin(x)");
grid on;

disp("\n\
Ranagyitva a kepre latjuk, hogy ket megoldas varhato: 0 es ~0.8")

disp("\n\
Ha ezt meglatjuk akar itt is kirajzolhatjuk a fuggvenyt")

figure (2);
x = -0.5 : 0.01 : 1;
plot(x, f(x));
title("x^2 - sin(x)");
grid on;

df = @(x) 2 * x - cos(x)

disp("\n\
Kezzel x0 = -0.5-bol indulva:")

-0.5
for i = 1:7
  ans - f(ans)/df(ans)
endfor

disp("\n\
Latjuk a gyors konvergenciat 0-hoz")

disp("\n\
Kezzel x0 = 1-bol indulva:")

1
for i = 1:7
  ans - f(ans)/df(ans)
endfor

disp("\n\
Latjuk a gyors konvergenciat ~0.87672621-hez")

###########################################################################

disp("\n\n\
A Newton modszer jol mukodik, ha jo a kezdeti becsles:\n\
- kelloen kozel van a megoldashoz\n\
- itt, kozel a megoldashoz a fuggveny nem laposodik el,\n\
  azaz f' nincs kozel 0-hoz (ezzel osztunk a formulaban,\n\
                             kicsi szammal osztas nagy\n\
                             elterest eredmenyez)\n\
- itt, kozel a megoldashoz a fuggvenynek jo kozelitese\n\
  az erintoje, azaz f'' nem tul nagy (Taylor sorfejtes,\n\
                                      1. foku Taylor = erinto\n\
                                      f'' kicsi -> erinto jo\n\
                                      kozelites)")
                                      
disp("\n\
Gyakorlatilag ez azt jelenti, hogy a jo kezdeti becsleshez\n\
egy meredek ""lejtot"" / ""emelkedot"" kell talalnunk\n\
ami a megoldas fele mutat")

disp("\n\
Ha a Newton modszer megtalalja a megoldast, akkor amint\n\
rakerul egy ilyen lejtore nagyon gyorsan konvergal.\n\n\
Ez pontosan fogalmazva azt jelenti, hogy negyzetes sebeseggel\n\
tartanak az iteraltak a megoldashoz.\n\
Az eddig latott modszerekhez kepest ez hatvanyozottan gyorsabb.\n\n\
Gyakorlatban azt latjuk, hogy amint a modszer konvergal,\n\
minden lepesben duplazodik a pontos tizedesjegyek szama.\n\n\
Ez nagyon gyors! Pl: 1 pontos jegy utan -> 2 -> 4 -> 8 -> 16\n\
pontos tizedesjegy, azaz 5 lepesen belul a gepi pontossag\n\
hatarahoz erhetunk.")

###########################################################################

disp("\n\
Nezzuk most az elozo ket iteraciot grafikusan abrazolva:\n\
(newton.m-et toltsetek le)")

figure (3);
newton(f, df, -0.5, 0.1, -0.5, 7);
title("Newton modszer x0 = -0.5");

figure (4);
newton(f, df, 0.8, 1, 1, 7);
title("Newton modszer x0 = 1");

###########################################################################

disp("\n\n\
2. Feladat\n\
Talaljuk meg x^3 + 2 x + 2 = 0 megoldasait")
f = @(x) x.^3 + 2 * x + 2

figure (5);
x = -100 : 0.01 : 100;
plot(x, f(x));
title("x^3 + 2x + 2");
grid on;

disp("\n\
Latszik, hogy 0 kornyeken lesz megoldas. Rakozelitessel:");

figure (6);
x = -2 : 0.01 : 2;
plot(x, f(x));
title("x^3 + 2x + 2");
grid on;

df = @(x) 3 * x.^2 + 2

disp("\n\
Kezzel x0 = 0-bol indulva:")

0
for i = 1:7
  ans - f(ans)/df(ans)
endfor

disp("\n\
Kezzel x0 = -2-bol indulva:")

-2
for i = 1:7
  ans - f(ans)/df(ans)
endfor

disp("\n\
Abrazolva:")

figure (7);
newton(f, df, -2, 0, 0, 7);
title("Newton modszer x0 = 0");

figure (8);
newton(f, df, -2, 0, -2, 7);
title("Newton modszer x0 = -2");

###########################################################################

disp("\n\n\
3. Feladat\n\
Kozelitsuk 10 negyzetgyoket Newton modszerrel")

disp("\n\n\
gyok(10) pozitiv megoldasa az x^2 = 10 egyenletnek,\n\
azaz x^2 - 10 = 0-t keressuk")
f  = @(x) x.^2 - 10
df = @(x) 2 .* x

figure (9);
x = 0 : 0.01 : 4;
plot(x, f(x));
title("gyok(10) keresese: x^2 - 10");
grid on;

disp("\n\
Latjuk, hogy megfelelo a lejto, induljunk pl 2-bol:")

2
for i = 1:10
  ans - f(ans)/df(ans)
endfor

disp("\n\
Figyeljetek meg, hogyan duplazodnak a pontos tizedesjegyek")

###########################################################################

disp("\n\n\
4. Feladat\n\
Kozelitsuk 10 negyzetgyoket Newton modszerrel\n\
igazoljuk, hogy a becslesunk jo, azaz legfeljebb 10^-6 = 0.000001\n\
tavolsagra van gyok(10)-tol")

disp("\n\n\
Az elozo feladatra epitve egy jo kezdeti becslesbol vegezzuk a Newton iteraciokat\n\
amig tobb mint 6 tizedesjegy stabilizalodik a tizedes pont utan.")

2
for i = 1:10
  ans - f(ans)/df(ans)
endfor

disp("\n\
Innen ki tudunk valasztani egy kelloen jonak tuno becslest,\n\
a mi esetunkben a pont utani 6 tizedesjegyet kell igazolni, igy:")
3.162277

disp("\n\
Ugy tudjuk teljesiteni a feladatot ha megmutatjuk, hogy a becslesunk\n\
alatt illetve felett 10^-6-nal a fuggveny kulonbozo elojelu.\n\
Ekkor (emlekezzunk a bezaro modszerekre) a ket ertek kozott biztos\n\
van megoldas es ezt a mi becslesunk legfeljebb 10^-6-nal kozeliti.")

disp("\n\
f( 3.162276 )")
f(3.162276)

disp("\n\
f( 3.162278 )")
f(3.162278)

disp("\n\
Az elojelek kulonbozoek, azaz a fuggvenynek van zerohelye a ket szam kozott.\n\
Tehat a [3.162276, 3.162278] intervallumon belul van gyok(10),\n\
igy a 3.162277 becsles megfelelo.")

###########################################################################

disp("\n\n\
5. Feladat (erdekesseg)\n\
Keressuk meg x^2 + 10 = 0 megoldasait Newton modszerrel")

disp("\n\
Ez nyilvan egy felfele allo parabola ami semely valos szamra sem 0")

f = @(x) x.^2 + 10
df = @(x) 2 .* x

figure (10);
x = -3 : 0.01 : 3;
plot(x, f(x));
title("x^2 + 10");
grid on;

disp("\n\
Nyilvan hiaba inditjuk el a Newton modszert valos kezdeti ertekkel")

2
for i = 1:10
  ans - f(ans)/df(ans)
endfor

disp("\n\
Grafikusan:")

figure (11);
newton(f, df, -4, 8, 2, 5);
title("Newton modszer x0 = 2");

disp("\n\n\
Azonban az egyenletnek pontosan ket megoldasa van: +/- i * gyok(10),\n\
csak ezek complex szamok!\n\n\
x1,2 = (-b +- gyok(b^2 - 4ac)) / 2a a jol ismert megoldo keplet a masodfoku\n\
egyenletekre. Mivel itt a diszkriminans negativ igy mindket gyok komplex.\n\n\
Newton modszere itt is mukodik, csak ha belegondolunk az iteracio\n\
nem kepes elhagyni a valos szamokat, igy ha tudjuk, hogy komplex megoldast\n\
keresunk akkor komplex kezdeti ertek dukal.")

disp("\n\
i -t fentebb hasznaltuk mint ""iteracios"" valtozo a for i ... ciklusukban\n\
hogy ismet hasznalhassuk mint az imagianarius egyseg, azaz gyok(-1),\n\
toroljuk az Octave-bol:\n\n\
clear i")
clear i

disp("\n\
Newton iteracio 2 + i-bol a + i * gyok(10)-et talalja meg")
2 + i
for j = 1:10
  ans - f(ans)/df(ans)
endfor

disp("\n\
Newton iteracio 2 - i-bol a - i * gyok(10)-et talalja meg")
2 - i
for j = 1:10
  ans - f(ans)/df(ans)
endfor