Beste antwoord
Je bedoelt een functie die \ frac {\ sin x} evalueert {x} voor x \ ne 0 en 1 voor x = 0?
Het is duidelijk dat het gemakkelijk zou zijn om gewoon iets te programmeren met een statement als
function result = mySinc(x)
\% My implementation of the sinc function.
if x == 0
result = 1;
else
result = sin(x)/x;
end
end
Maar dat zou in feite kunnen zijn minder dan ideaal. Natuurlijk, het vermijdt de singulariteit en heeft de juiste wiskundige structuur, maar we moeten natuurlijk onthouden dat de waarden in x
geen “getallen” zijn: het zijn patronen van bits die worden weergegeven door schakelaars in hardware en alleen geschatte getallen. Ze werken meestal redelijk goed, maar er zijn omstandigheden waarin dingen gewoon niet goed werken. Zoals bij het evalueren van a + log(1+x)
voor kleine x
, of bij het evalueren van a-b
wanneer a
en b
zeer vergelijkbare waarden hebben. U kan een partij aan precisie verliezen als u de laatste naïef beoordeelt (hoewel u soms helaas geen keus heeft). Delen door kleine getallen kan ook problemen veroorzaken, hoewel gelukkig zijn zowel \ sin x als x vergelijkbaar wanneer | x | \ ll 1. Misschien zou het “geen probleem zijn, maar als het om drijvende-kommaberekeningen gaat, is het zelden een goede gewoonte om code te hebben als if x == foo
.
Wat te doen in dit geval? Beschouw de Taylor-reeks van \ frac {\ sin x} {x} gecentreerd op x = 0. Ik zal het niet opschrijven, maar je weet zeker hoe je het moet berekenen.
Vervang vervolgens de test if x == 0
door if abs(x) < sqrt(eps)
, waarbij in Matlab eps
de machine epsilon retourneert (vergelijkbaar met 10 ^ {- 16} op de meeste systemen tegenwoordig), en de regel result = 1;
door result = ...;
, waarbij de ...
uw berekening van de Taylor-reeks wordt, afgekapt na een passende volgorde doen, maar u moet zelf de schaal controleren van de term van de hoogste orde die u kiest voor x \ sim 10 ^ {- 8} en of het resultaat zo nauwkeurig zal zijn als u nodig heeft of niet).
De Het leuke hier is dat wat je verliest aan snelheid bij het uitvoeren van deze code, je waarschijnlijk aan nauwkeurigheid wint, vooral als je de sinus-integraal \ operatornaam {Si} (x) = \ int\_0 ^ xf (t) dt evalueert, waarbij f (t ) is de continue uitbreiding van de \ operatorname {sinc} -functie naar alle reals als zijn domein.