Tűszerű háromszögek területének számítása

Egy oldalaival meghatározott háromszög területének kiszámítására a Heron képletet szoktuk használni. Ez a gyakorlati alkalmazások többségében jól használható. Vannak azonban olyan esetek, amikor a Heron képlet a lebegőpontos számábrázolás korlátozott pontossága miatt nem ad helyes eredményt. Ilyen eset, amikor az úgynevezett tűszerű háromszögek (needle-like triangle) területét szeretnénk megkapni. A tűszerű háromszög olyan háromszög, amelynek két oldala sokkal hosszabb, mint a harmadik. Erre mutat példát az alábbi ábra tetején megrajzolt háromszög.

A tűszerű háromszögek területének pontosabb kiszámítására William Kahan matematikus – aki többek között a lebegőpontos számítások IEEE 754-1985 szabványának fő megalkotója volt – adott egy képletet, amelyet szintén az előbbi ábrán látható. Ehhez két kikötés tartozik. Az egyik, hogy a képlet használata előtt az oldalakat rendezni kell, hogy az „a” oldal legyen a legnagyobb és a „c” a legkisebb. A másik, hogy a négyzetgyök alatti szorzat tényezőiben a zárójelek lényegesek, azokat meg kell hagyni. Ennek oka, hogy a float típusú számok esetében az eredmény pontossága függhet a műveletvégzési sorrendtől. Erről egyszerűen meggyőződhetünk egy példával. Írassuk ki először azt, hogy print(0.1+0.2+0.3). Ennek eredménye 0.6000000000000001 lesz. Most tegyük zárójelbe a két utolsó tagot és írjuk ki így az eredményt: print(0.1+(0.2+0.3)). Ekkor az egzakt 0.6 érték jelenik meg.

A következőkben azt fogjuk vizsgálni, hogy tűszerű háromszögek esetén valóban pontosabb eredményt ad-e a Kahan képlet, mint a Heron képlet, és a pontosságbeli különbség mindig fennáll-e. Ehhez első lépésben egy-egy függvényt készítettünk az ábrán feltüntetett Heron és a Kahan képlet szerinti területszámításhoz.

A függvények által szolgáltatott eredmények pontosságának megítéléséhez a tesztekben a háromszöget nem a három oldalával, hanem az ábrán látható jelölések szerinti x, y és m szakaszokkal adjuk meg. Ebben az esetben a háromszög területét az egyszerű alap*magasság/2 képlettel tudjuk felírni, ami a közös összehasonlítási alap lesz. Másrészt a háromszög keskenységét, tűszerűségét az m értékével tudjuk egyszerűen beállítani.

A tesztprogramot alább látjuk. Ennek elve, hogy az x értékét széles határok között növeljük és megnézzük, hogy az egyes x értékekhez tartozó háromszögekre melyik képlet pontosabb. Amelyik pontosabb eredményt ad, az ahhoz tartozó esetszámláló értékét eggyel növeljük. Ha az összes háromszögre a terület ki lett számolva, akkor a végén a számlálók értéke, viszonyítva az összes vizsgált háromszög számával megadja, hogy összeségében melyik képlet bizonyult pontosabbnak.

A tesztadatok meglehetősen keskeny, tűszerű háromszögeket definiálnak, és a végeredményből levonhatjuk a következtetést, hogy a Kahan képlet összességében pontosabb eredményt ad. Ha kicsit tovább elemezzük az eredményeket, akkor az is megállapítható, hogy a Heron képlet a kevésbé keskeny esetekben produkál csak picit nagyobb pontosságot, de minél keskenyebb lesz a háromszög a Kahan képlet fog pontosabb területértékeket adni. A tesztünkben szereplő legkeskenyebb háromszögre számszerűen is láthatjuk az eltérést.

A float típus számábrázolási pontosságáról és vonatkozásairól a Python tudásépítés lépésről lépésre című e-könyvben a „Műveletek” fejezet „Számítási pontosság float típus esetén” című szakaszában, valamint a „Készétel fogyasztás – a szabványos könyvtár moduljainak használata” fejezet „Matematikai számítások támogatása” alfejezetben van kiemelten szó.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.