2012-05-24 19 views
6

Sono appena riusciti a utilizzare un approccio a forza bruta o c'è un algoritmo nel farlo?Come sono programmati i logaritmi?

+3

'forza bruta' e 'algoritmo' non si escludono a vicenda, la tua domanda pone una falsa dicotomia. E la risposta è, SÌ, c'è un algoritmo nel farlo. –

+0

Ah, mi sento sciocco aver dimenticato che la forza bruta era in realtà un algoritmo. Grazie. – Taffer

+0

"brute force" è una proprietà degli algoritmi, in cui si applica più potenza di calcolo per farla franca con meno pensiero (che si sarebbe potuto usare per trovare un algoritmo meno brutale). – starblue

risposta

14

L'implementazione di una funzione come il logaritmo naturale in qualsiasi libreria matematica decente manterrà l'errore sotto un ulp (unità di minima precisione). L'obiettivo dell'implementatore di una funzione di libreria matematica è trovare un'approssimazione ottimale, quella che raggiunge l'accuratezza desiderata con il minor numero possibile di calcoli. Le serie di Taylor sono in genere una scelta sbagliata perché sono necessari troppi termini per ottenere la precisione desiderata.

Le armi tipiche di scelta sono ridurre l'intervallo da tutti i numeri reali rappresentabili a una regione molto piccola, quindi utilizzare un'approssimazione ottimale che fornisca un'accurata approssimazione della funzione desiderata su questo intervallo ristretto. Le armi tipiche di scelta per questa approssimazione ottimale sono un polinomio o un polinomio razionale (rapporto di due polinomi). L'implementazione contiene solo i coefficienti polinomiali. Questi coefficienti sono costruiti con una tecnica di ottimizzazione come l'algoritmo di Remes Exchange.

Nel caso del logaritmo naturale, esiste un modo semplice per ridurre l'intervallo. I numeri reali sono quasi universalmente rappresentate in termini di una mantissa e dell'esponente: x = m * 2 p, dove p é un intero ed m è compreso tra 1 e 2. Così log (x ) = log ( m) + p * log (2). Quest'ultimo termine, p * log (2), è solo una moltiplicazione per una costante conosciuta. Il problema si riduce quindi alla ricerca del logaritmo di un numero compreso tra 1 e 2 (o tra 1/2 e 1). Un'ulteriore riduzione del raggio può essere fatta usando il fatto che √2 è logaritmicamente nel mezzo di [1,2). Quindi tutto ciò che serve è un modo per calcolare il logaritmo di un numero compreso tra 1 e √2. Questo è tipicamente fatto con un polinomio razionale. Il rapporto tra un polinomio di secondo ordine e un terzo ordine funziona abbastanza bene per questo.

+4

.5 L'ULP è un obiettivo ambizioso; è uguale a arrotondato correttamente, ovvero deve essere restituito il numero rappresentabile più vicino al risultato matematicamente esatto. Il progetto CRlibm (http://lipforge.ens-lyon.fr/www/crlibm/) cerca di farlo, ma è incompleto (ad es. Non vengono fornite funzioni iperboliche inverse). L'arrotondamento fedele (meno di 1 ULP) è un obiettivo più raggiungibile e le librerie tipiche consentono errori di diversi ULP. Le funzioni razionali vengono evitate poiché la divisione è lenta nei processori comuni. Ad esempio, una tangente potrebbe utilizzare una funzione razionale, ma il seno e il logaritmo useranno semplici polinomi. –

+0

Buon commento. 0,5 L'ULP è eccessivamente ambizioso.Riguardo ai polinomi razionali rispetto a quelli semplici: i razionali possono essere migliori se la riduzione del grado compensa di più l'aumento del costo di una divisione rispetto a una moltiplicazione. Ho trovato molteplici implementazioni di 'log' che usano un polinomio razionale. Log è una funzione molto bella per quanto riguarda l'approssimazione. Gli errori peggiori si verificano con numeri vicini all'unità, e anche qui l'errore può essere mantenuto all'interno di un ULP. –

+1

Ridurre l'intervallo a [1.0, 2.0) produce errori di grandi dimensioni vicino al registro (0.999 ...), come ha commentato David Hammen. Le implementazioni che conosco evitano questo problema riducendo ad un intervallo che ha 1.0 all'interno, come [2/3, 4/3) o [sqrt (0.5), sqrt (2.0)). In termini di programmazione, ci sono solo un paio di istruzioni extra per farlo: if (m> constant) {p + = 1; m * = 0,5;} –

2

Esistono diversi modi per calcolare i logaritmi. Vedi this.

+5

-1. Non sono "per lo più calcolati dalle approssimazioni della serie Taylor". –

+0

Ho aggiornato la risposta per non dirlo più. – Oleksi

+1

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. - [Dalla revisione] (/ recensione/post di bassa qualità/18788146) – Syfer