Cel mai bun răspuns
Adică o funcție care evaluează \ frac {\ sin x} {x} pentru x \ ne 0 și 1 pentru x = 0?
Evident, ar fi ușor să programați doar ceva cu o afirmație precum
function result = mySinc(x)
\% My implementation of the sinc function.
if x == 0
result = 1;
else
result = sin(x)/x;
end
end
Dar asta ar putea fi, de fapt, mai puțin decât ideal. Sigur, evită singularitatea și are structura matematică corectă, dar, desigur, trebuie să ne amintim că valorile din x
nu sunt „numere”: ele sunt modele de biți reprezentate de comutatoare în hardware și numai numere aproximative . Funcționează destul de bine de cele mai multe ori, dar există circumstanțe în care lucrurile nu funcționează corect. De exemplu, atunci când se evaluează a + log(1+x)
pentru x
, sau când evaluați a-b
când a
și b
au valori foarte similare. poate pierde un lot de precizie dacă îl evaluați cu naivitate pe acesta din urmă (deși uneori s-ar putea să nu aveți de ales, din păcate). Împărțirea după numere mici poate provoca și probleme, deși din fericire, ambele \ sin x și x sunt comparabile atunci când | x | \ ll 1. Poate că nu ar fi o problemă, dar atunci când avem de-a face cu aritmetica în virgulă mobilă, rareori este o bună practică să avem codul ca if x == foo
.
Ce trebuie făcut în acest caz? Luați în considerare seria Taylor a \ frac {\ sin x} {x} centrată la x = 0. Nu am scris-o, dar sigur știți cum să îl calculați.
Apoi înlocuiți testul if x == 0
cu if abs(x) < sqrt(eps)
, unde în Matlab eps
returnează epsilonul mașinii (comparabil cu 10 ^ {- 16} în majoritatea sistemelor zilelor acestea) și înlocuiți linia result = 1;
de result = ...;
, unde ...
va fi calculul tău al seriei Taylor trunchiat după o comandă adecvată (de obicei aproximativ 2 ar trebui faceți, dar ar trebui să verificați singur scala pentru termenul de comandă cel mai mare pe care o alegeți pentru x \ sim 10 ^ {- 8} și dacă rezultatul va fi la fel de precis cât aveți nevoie sau nu).
un lucru frumos aici este că ceea ce pierdeți în viteza care rulează acest cod, veți câștiga probabil în acuratețe, mai ales atunci când evaluați sinus-integral \ operatorname {Si} (x) = \ int\_0 ^ xf (t) dt, unde f (t ) este extensia continuă a funcției \ operatorname {sinc} la toate realele ca domeniu al acesteia.