Migliore risposta
Intendi una funzione che valuta \ frac {\ sin x} {x} per x \ ne 0 e 1 per x = 0?
Ovviamente sarebbe facile programmare qualcosa con unistruzione come
function result = mySinc(x)
\% My implementation of the sinc function.
if x == 0
result = 1;
else
result = sin(x)/x;
end
end
Ma in realtà potrebbe essere meno che ideale. Certo, evita la singolarità e ha la struttura matematica corretta, ma ovviamente dobbiamo ricordare che i valori in x
non sono numeri: sono modelli di bit rappresentati da interruttori in hardware e solo approssimativo numeri. Funzionano abbastanza bene la maggior parte del tempo, ma ci sono circostanze in cui le cose semplicemente non funzionano correttamente. Ad esempio quando si valuta a + log(1+x)
per x
o quando si valuta a-b
quando a
e b
hanno valori molto simili. può perdere un lotto di precisione se valuti questultima in modo ingenuo (anche se a volte potresti non avere scelta, ahimè). Anche la divisione per piccoli numeri può causare problemi, sebbene fortunatamente sia \ sin x che x sono confrontabili quando | x | \ ll 1. Forse non sarebbe un problema, ma quando si ha a che fare con aritmetica in virgola mobile è raramente buona pratica avere codice come if x == foo
.
Cosa fare in questo caso? Considera la serie di Taylor di \ frac {\ sin x} {x} centrata su x = 0. Non la scriverò, ma sicuramente sai come calcolarlo.
Quindi sostituisci il test if x == 0
con if abs(x) < sqrt(eps)
, dove in Matlab eps
restituisce la macchina epsilon (paragonabile a 10 ^ {- 16} sulla maggior parte dei sistemi oggigiorno) e sostituisce la riga result = 1;
di result = ...;
, dove ...
sarà il calcolo della serie di Taylor troncata dopo un ordine appropriato (di solito circa 2 dovrebbero fallo, ma dovresti controllare tu stesso la scala del termine di ordine più elevato che scegli per x \ sim 10 ^ {- 8} e se il risultato sarà accurato o meno).
la cosa bella qui è che quello che perdi in velocità eseguendo questo codice probabilmente guadagnerai in accuratezza, specialmente quando valuti il seno-integrale \ operatorname {Si} (x) = \ int\_0 ^ xf (t) dt, dove f (t ) è lestensione continua della funzione \ operatorname {sinc} a tutti i reali come suo dominio.