06 - numerikus integrálás¶
Láttuk előadáson, hogy hogyan lehet olyan függvényt írni, mely egy másik függvényt vár paraméterben. Most azt nézzük meg, hogy hogyan tudunk ilyennel dolgozni.
függvénygörbe alatti terület¶
Alapvetően a határozott integrál nem más, mint területszámítás:
a lenti képen pl. azt látjuk, hog ha az x^2 - 2x + 1 függvény határozott
integrálját akarjuk kiszámolni a [0,3] intervallumon, akkor arra vagyunk kíváncsiak,
hogy mekkora a függvény görbéje alatti, a képen narancssárgával sraffozott terület.
(Azzal, hogy ami a 0 alatt van, az mínuszban számít, ilyen most a képen nincs.)

Ilyesmire szükség lehet pl. fizikai mennyiségek számolásakor, pl. ha az x
tengely az idő (fizikában sokszor az szokott lenni), a függvény maga meg valami
holminak a pillanatnyi sebességét írja le (feltéve, hogy az irány állandó),
akkor két időpont közti határozott integrálja ennek a függvénynek megadja a
megtett utat.
numerikusan¶
Kalkulusból tanultunk komplikált módszereket és trükköket arra, hogy ha adott a függvényünk valami zárt képlettel (a képen pl egy polinom van, ami jónak, könnyen integrálhatónak számít), akkor szimbolikusan is ki tudjuk számolni az integrált, megkapjuk a primitív függvényt, stb.
A valóság ennyire nem szokott a kezünkre játszani: inkább az a jellemző, hogy az
integrálandó f
függvényre nem ismerünk zárt képletet (vagy ha igen, akkor azt nem tudjuk kiintegrálni
szimbolikusan),
csak mérési pontjaink vannak néhány értékkel, vagy behelyettesíteni tudunk a függvénybe,
kapunk számokat, de ennél több adatunk nincs.
Ha ,,elég sűrűn'' mintavételezzük a függvényt, akkor a határozott integrál értékét
egy [a,b] szakaszon (azaz ott a függvénygörbe alatti területet) tudjuk közelíteni
pl. az úgynevezett trapéz módszerrel:
- választunk (vagy kapunk egy
negész számot) - ennyi egyforma kis részre osztjuk az
[a,b]intervallumot - minden részen egy-egy trapézzal közelítjük a területet:
- ha a kis intervallum az
[x,y], akkor f(x)lesz a trapéz egyik oldalának a hossza,f(y)a másik,- az intervallum hossza meg a magassága
- ha a kis intervallum az
- és ezeket a trapéz területeket összeadjuk.
Pl. ha a fenti kép függvényében n=3 egyforma részre vágjuk az intervallumot, akkor
ilyesmit kapunk:

A képen van három trapéz, mind ,,oldalra van fordítva'', a jobb oldalinak pl azt egyik oldala 4
hosszú, a másik 1, a magassága pedig 1 (ez a [2,3] intervallumon levő trapéz).
A másik kettő meg egy-egy háromszög, olyan trapéz, aminek a rövid oldala 0 hosszú.
a feladat¶
Implementáljunk egy trapez függvényt, ami paraméterben megkapja az integrálandó függvényt,
az intervallum két végpontját, a-t és b-t, meg egy n intet, ami azt mondja meg, hogy
az intervallumot hány részre osszuk fel, és visszaadja a határozott integrál trapéz módszeres
közelítését!
a megoldás¶
Az első kérdés, hogy mi legyen a függvény fejléce?
1 | |
Válasz mutatása
A függvényen belül implementáljunk egy olyan függvényt, ami egy [x,y] részintervallumon
számolja ki egy trapéz területét és ezt adja vissza!
1 2 3 4 5 6 | |
Válasz mutatása
Itt azt érdemes megfigyelni, hogy ha kapunk egy f függvényt paraméterben, abba a
megfelelő típusú értékeket simán behelyettesíthetjük és a kifejezés értéke persze
olyan típusú lesz, mint f kimenetének a típusa. Így pl. most hogy f: Double => Double,
és a: Double, azaz megfelel f inputjának, írhatjuk, hogy f(a).
Érdemes lehet először is kiszámolni egy kicsi intervallum hosszát. Tegyük ezt meg, de
hibakezeléssel: ha 0 vagy kisebb az input n-ünk, akkor számoljunk 1-gyel!
Tegyük el a kis intervallumok hosszát egy (mondjuk) h nevű értékbe.
1 2 3 4 5 6 7 8 9 | |
Válasz mutatása
Így is lehet, de ismerkedjünk meg a max függvénnyel, ami a Math objektumon belül van deklarálva,
ezért Math.max-ként tudjuk meghívni (ahogy korábban a tesztekben Gyakorlat.fib(..)-ként hívtuk
a Fibonacci függvényt): ő kap két (mondjuk) Intet és visszaadja a maximumukat.
Az a belső if ha belegondolunk, nem más, mint Math.max( n, 1 ): ha n legalább 1, akkor
annyi marad, ha pedig nem, akkor 1 lesz. Tehát kicserélhetjük:
1 2 3 4 5 6 7 8 9 | |
Válasz mutatása
Most írjuk meg az ,,adjuk össze a kis trapézok területét'' függvényt. Ha nem megy elsőre, gondoljuk át: hogy írnánk meg imperatív nyelven ezt?
1 2 3 4 5 | |
Válasz mutatása
Ebből kiindulva, a for ciklus tailrecbe való átírásával milyen tailrec kódot kapunk?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Válasz mutatása
hogy hívjuk meg?¶
Tesztelni is kéne a kódunkat, hogyan integráljuk ki pl. a rajzolt példánkat a [0,3] intervallumon,
azt 3 részre osztva?
1 | |
Válasz mutatása
Amit innen látunk: ha ismert, hogy mi a függvény paraméterünk szignatúrája (most igen:
a trapez függvény paraméterként egy Double => Double függvényt vár),
akkor egyszerűen input => érték formában (ha a számítás összetettebb, akkor persze
az érték részt kapcsosban) meg tudunk adni egy függvényt.
(egyébként ha n=100-zal hívjuk meg, akkor a visszaadott érték 3.00045, egész közel
lesz a tényleges értékhez, ami 3 - ez a függvény ,,konvex'', ami azt jelenti, hogy ha
szakaszokat huzigálunk két pontja közé, az nem fog lemenni a függvény görbéje alá, ezért
a trapéz módszer mindig fölélövi valamennyivel egy konvex függvény integrálját. De ha elég
sok a pontunk, ahol kiértékelünk, akkor elég közel tudunk menni a tényleges integrálhoz.)
Futtassuk le a teszteseteket is, hogy lássuk, valóban stimmel az előre elvárt függvények és osztás számok esetén a területszámítás.
mini upgrade¶
Kicsit kevesebb lehet a kerekítési hiba és pontosabb az eredmény, ha nem azt csináljuk, hogy a kis trapézok területeit osztogatjuk kettővel, és ezt adjuk össze, hanem csak a végén osztjuk kettővel az összeget. Hogy néz ki úgy a kód, ha ezt megtesszük?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |