07 - húrmódszer¶
Ismét tail rekurziót és paraméterként átadott függvényt gyakorlunk: ezúttal egy függvény zérushelyét szeretnénk megkeresni egy intervallumon, méghozzá az úgynevezett húrmódszert használva, ami szintén egy numerikus módszer, tehát elég hozzá, ha ki tudjuk értékelgetni a függvényünket.
Persze nem találunk feltétlenül olyan pontot, ahol pontosan 0
a függvény értéke,
de ha ,,majdnem nulla'', akkor visszajövünk azzal.
a módszer¶
A módszer inputként kap
- egy
f
függvényt, - egy
a
és egyb
pontot, méghozzá úgy, hogy az egyikben negatív, a másikban pozitív a függvény, - meg egy
e > 0
valós szám, ennyi hibát megengedünk, - és a következőt csinálja ciklusban:
- kiszámolja az aktuális pontjai közt félúton lévő
x
pontot, - ha
|f(x)| < e
, akkor leállunk, ez jó lesz zérushelynek, elég közel van nullához, - különben ha
f(x)
negatív, akkorx
-szel és a két eredeti pontunk közül a pozitívval, - ha pedig pozitív, akkor
x
-szel és a két eredeti pontunk közül a negatívval haladunk tovább.
- kiszámolja az aktuális pontjai közt félúton lévő
Ha a függvény nem túl ronda (mondjuk folytonos és ráadásul ,,egyenletesen'', van valami felső korlát arra h mennyire meredek ezen az intervallumon), akkor ez a módszer előbb-utóbb talál egy zérushelyet.
példa¶
Nézzük ezt a képet példaként: a kék a függvény, megkapjuk az a
és b
pontokat, melyek
naranccsal vannak jelölve, f(a)
pozitív, f(b)
pedig negatív.
Ekkor
a
ésb
közt félúton ott azx1
pont, ahol az érték negatív. Messze van a nullától, ezért mosta
-val ésx1
-gyel megyünk tovább, mert haf(x1)
negatív, akkorx1
melléa
t visszük tovább, mertf(a)
volt a pozitív a két eredeti pontunk közül.a
ésx1
közt félútonx2
van, ott is mondjukf(x2)
negatív és mondjuk még messze a nullától. Akkorx2
melléa
-t visszük tovább, mertf(a)
volt a pozitív azf(x1)
és azf(a)
közül.a
ésx2
közt félúton vanx3
, itt mondjukf(x3)
pozitív, de messze van a nullától, ígyx3
melléx2
-t visszük tovább, mert az aktuális két pontunk közülf(x2)<0
ésf(a)>0
volt.x2
ésx3
közt félúton vanx4˙, ahol a függvény értéke elég közel van nullához, visszaadjuk
x4`-et.
a feladat¶
Implementáljuk a húrmódszert: kapja meg a hurmodszer
függvény magát a függvényt, aminek
keressük a zérushelyét, valamint két pontot, a
-t és b
t azzal az ígérettel, hogy az egyikben
f
pozitív, a másikban pedig negatív (ha nem így lenne, mondjuk egyelőre adjunk vissza ???
-et),
és egy e
valós hibakorlátot (mondjuk ha e
negatív, akkor állítsuk be inkább 0.001
-re)!
a megoldás¶
Hogy nézzen ki a függvényünk fejléce?
1 |
|
Válasz mutatása
Kezdetnek mondjuk érdemes lenne úgy rendezni az a
és b
értékeket, hogy f(a) <= f(b)
mindig
igaz legyen; ha nem így jön be az input, cseréljük meg! Ezt hogy érhetjük el?
1 2 3 4 5 |
|
Válasz mutatása
A következő logikus lépés talán az e
hibatag korrekciója lenne a leírt módon. Ezt hogy érhetjük
el?
1 2 3 4 5 6 |
|
Válasz mutatása
Most, hogy f(a) <= f(b)
, talán ez az a pont, ahol jó ötlet lenne ellenőrizni, vajon
f(a) <= 0
és f(b) >= 0
is teljesül-e (nyilván ez kell legyen a sorrendjük). Ha nem,
akkor jöjjünk vissza mondjuk a ???
értékkel, egyébként pedig most már, hogy minden
argumentumot ellenőriztünk, hívhatjuk a módszernek egy checked változatát (lehetne
persze úgy is megoldani ezt, hogy minden hívásnál ellenőrizzük a paramétereket, de
fölösleges időpocsékolás: ha mi csináljuk a rekurzív hívást a saját függvényünkből, azt
jól fogjuk tenni). Hogyan ellenőrzünk negatív - pozitívot?
1 2 3 4 5 6 7 8 9 10 |
|
Válasz mutatása
Menjünk rá a checked függvényre: először is jó ötletnek tűnik kiszámolni a felezőpontot,
mondjuk egy z
értékbe. Hogyan?
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Válasz mutatása
Mi van még hátra? Ha f(z)
már jó, akkor visszaadhatjuk z
-t, ha meg nem, akkor ha pozitív,
y
-t kell z
-re cserélni, ha negatív, akkor meg x
-et. Implementáljuk le! Ehhez
érdemes lehet felhasználni a Math.abs
függvényt, ami az input (mondjuk) Double szám
abszolútértékét adja vissza.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Válasz mutatása
Tudunk valamit javítani a fenti kódon, hogy kevesebbet számoljon?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Válasz mutatása
Ha mondjuk az x^2=2
egyenletet akarjuk megoldani numerikusan, azaz az x*x-2
függvény
zérushelyét keressük, mondjuk 1e-10
pontossággal (ez ugye a 0.0000000001
érték),
azt hogy tehetjük meg? A húrmódszer alkalmazásához persze kell egy olyan pont, ahol ez
a függvény negatív (erre pl x=0
jó lesz, mert ott -2
), és egy olyan, ahol pozitív
(erre meg akár x=10
is jó lesz, mert ott 98
). Hogy futtatjuk a húrmódszert erre
a függvényre ezekből a pontokból ezzel a pontossággal?
1 |
|
Válasz mutatása
Persze ???
hagyása a kódban az nem az idiomatikus megoldás, majd később látni fogjuk, hogy
ilyenkor mit illik inkább tenni.