Bedste svar
Du mener en funktion, der evaluerer \ frac {\ sin x} {x} for x \ ne 0 og 1 for x = 0?
Det ville naturligvis være let at bare programmere noget med en erklæring som
function result = mySinc(x)
\% My implementation of the sinc function.
if x == 0
result = 1;
else
result = sin(x)/x;
end
end
Men det kunne faktisk være mindre end ideel. Sikker på, det undgår singularitet og har den korrekte matematiske struktur, men vi skal selvfølgelig huske, at værdierne i x
ikke er tal: de “er mønstre af bits repræsenteret af kontakter i hardware og kun omtrentlige numre. De fungerer temmelig godt det meste af tiden, men der er omstændigheder, hvor ting bare ikke fungerer rigtigt. F.eks. Når man vurderer a + log(1+x)
for små x
, eller når du vurderer a-b
når a
og b
har meget ens værdier. kan miste et parti af præcision, hvis du vurderer sidstnævnte naivt (selvom du undertiden måske ikke har noget valg, desværre). Opdeling med små tal kan også give problemer, selvom heldigvis er både \ sin x og x sammenlignelige, når | x | \ ll 1. Måske ville det ikke være et problem, men når det drejer sig om flydende aritmetik, er det sjældent god praksis at have kode som if x == foo
.
Hvad skal jeg gøre i dette tilfælde? Overvej Taylor-serien af \ frac {\ sin x} {x} centreret ved x = 0. Jeg vil ikke skrive det ned, men du ved helt sikkert, hvordan du beregner det.
Udskift derefter testen if x == 0
med if abs(x) < sqrt(eps)
, hvor i Matlab eps
returnerer maskinens epsilon (kan sammenlignes med 10 ^ {- 16} på de fleste systemer i disse dage), og erstatt linjen result = 1;
af result = ...;
, hvor ...
bliver din beregning af Taylor-serien trunkeret efter en passende ordre (normalt skal ca. 2 gør, men du skal selv kontrollere størrelsen på det højeste ordsudtryk, du vælger for x \ sim 10 ^ {- 8}, og om resultatet bliver så nøjagtigt, som du har brug for eller ej).
god ting her er, at hvad du mister i hastighed ved at køre denne kode, vil du sandsynligvis vinde i nøjagtighed, især når du vurderer sinusintegralt \ operatornavn {Si} (x) = \ int\_0 ^ xf (t) dt, hvor f (t ) er den kontinuerlige udvidelse af \ operatorname {sinc} -funktionen til alle realer som dets domæne.