Legjobb válasz
Olyan függvényre gondol, amely kiértékeli \ frac {\ sin x} {x} x \ ne esetén 0 és 1 x = 0 esetén?
Nyilvánvaló, hogy könnyű egyszerűen programozni valamit egy olyan állítással, mint például
function result = mySinc(x)
\% My implementation of the sinc function.
if x == 0
result = 1;
else
result = sin(x)/x;
end
end
De ez valójában lehet kevesebb, mint ideális. Persze, elkerüli a szingularitást és a megfelelő matematikai felépítésű, de természetesen emlékeznünk kell arra, hogy az x
értékek nem “t” számok: kapcsolók által reprezentált bitminták. hardverben és csak hozzávetőleges számokat. A legtöbbször elég jól működnek, de vannak olyan körülmények, amikor a dolgok egyszerűen nem működnek jól. Például a a + log(1+x)
értékelésekor a kis x
, vagy a a-b
értékelésekor, amikor a
és b
értéke nagyon hasonló. sok pontosságot elveszíthet, ha utóbbit naivan értékeli (bár néha lehet, hogy nincs más választása, sajnos). A kis számokkal való felosztás szintén problémákat okozhat, bár szerencsére mind a \ sin x, mind az x összehasonlítható, ha | x | \ ll 1. Lehet, hogy ez nem jelent problémát, de lebegőpontos aritmetikával foglalkozva ritkán jó gyakorlat, ha olyan kód van, mint if x == foo
.
Mit kell tenni ebben az esetben? Tekintsük a Taylor \ frac {\ sin x} {x} sorozatot, amelynek középpontja x = 0. Nem fogom leírni, de biztosan tudja, hogyan kell kiszámítani.
Ezután cserélje le az if x == 0
tesztet if abs(x) < sqrt(eps)
, ahol a Matlab-ban eps
visszatér a gép epsilonjához (manapság a legtöbb rendszeren összehasonlítható a 10 ^ {- 16} értékkel), és cserélje le a result = 1;
által result = ...;
, ahol a ...
lesz a Taylor-sorozat számítása a megfelelő sorrend után csonkítva (általában kb. 2 tegye, de ellenőrizze magának az x \ sim 10 ^ {- 8} számára kiválasztott legmagasabb sorrendű tag skáláját és azt, hogy az eredmény olyan pontos lesz-e, mint amire szüksége van, vagy sem).
A Szép dolog itt az, hogy amit elvesztesz a kód futtatásával, valószínűleg pontosabb lesz, különösen akkor, ha a szinuszintegrál \ operátornév értékelése {Si} (x) = \ int\_0 ^ xf (t) dt, ahol f (t ) az \ operatorname {sinc} függvény folyamatos kiterjesztése az összes valós tartományra.