5

Che tipo di problemi di stabilità si presentano o si risolvono usando std::pow()?Qual è la stabilità numerica di std :: pow() rispetto alla moltiplicazione iterata?

  • Sarà più stabile (o più veloce, o affatto diverso) in generale per implementare una funzione semplice effettuare log(n) moltiplica iterati se l'esponente è noto per essere un numero intero?

  • In che modo confronta std::sqrt(x), in base alla stabilità, con qualcosa del formato std::pow(x, k/2)? Avrebbe senso scegliere il metodo preferito per quanto sopra per aumentare ad un potere intero, quindi moltiplicare in una radice quadrata, o dovrei supporre che std::pow() sia veloce e preciso per precisione macchina per questo? Se k = 1, c'è una differenza da std::sqrt()?

  • In che modo std::pow(x, k/2) o il metodo sopra riportato confrontano, in base alla stabilità, con un numero intero di esponenziazione di std::sqrt(x)?

E come bonus, quali saranno le differenze di velocità?

+8

Stai facendo una domanda su quali parti sono suscettibili di sperimentazione e analisi. Quali sono i risultati dei tuoi esperimenti e analisi? –

+0

La risposta di Pascal Cuoq è eccellente, ma vorrei aggiungere che molte implementazioni tradizionali e popolari di 'pow' sono scandalosamente schifose. – tmyklebu

+0

@tmyklebu, quali? – trbabb

risposta

7

Sarà più stabile (o più veloce, o del tutto diverso) in generale, implementare una semplice funzione per eseguire log (n) iterato moltiplica se l'esponente è noto per essere un numero intero?

Il risultato di exponentiation by squaring per esponente intero è in generale meno accurata pow, ma entrambi sono stabili, nel senso che chiudi ingressi producono risultati vicino. È possibile prevedere l'esponenziazione quadrando per introdurre 0,5 ULP di errore relativo per moltiplicazione (ad esempio, 1 ULP di errore per il calcolo di x come x * x * x).

Quando il secondo parametro n è staticamente noto per essere 2, quindi con tutti i mezzi attuare x n come x * x. In quel caso è più veloce e più preciso di ogni possibile alternativa.

Come funziona std :: sqrt (x) confrontare, stabilità-saggio, a qualcosa di forma std :: pow (x, k/2)

In primo luogo, la precisione di sqrt non può essere battuto per un'implementazione IEEE 754, perché sqrt è una delle operazioni di base che questo standard richiede di essere il più preciso possibile.

Ma non si sta chiedendo circa sqrt, si sta chiedendo (credo) su < calcolo di x n> * sqrt (x) al contrario di pow(x, n + 0.5). Di nuovo, in generale, per un'implementazione di qualità di pow, è possibile aspettarsi che pow(x, n + 0.5) sia più preciso delle alternative. Sebbene sqrt(x) sia calcolato a 0,5 ULP, la moltiplicazione introduce la propria approssimazione fino a 0,5 ULP, e tutto sommato, è meglio ottenere il risultato a cui si è interessati in una singola chiamata a una funzione ben implementata. Un'implementazione di qualità di pow ti darà 1 ULP di precisione per il suo risultato e le migliori implementazioni "garantiranno" 0,5 ULP.

E come bonus, quali saranno le differenze di velocità?

Se si conosce in anticipo che l'esponente sta per essere un piccolo numero intero o multiplo di 0,5, quindi si dispone di informazioni che il realizzatore di pow non ha avuto, in modo da poterli battere di almeno il costo di il test per determinare che il secondo argomento è un numero intero piccolo. Inoltre, l'implementatore di un'implementazione di qualità mira a ottenere un risultato più accurato di quello fornito da un semplice esponenziamento mediante squadratura. D'altra parte, l'implementatore di pow può utilizzare tecniche estremamente sofisticate per ridurre al minimo il tempo di esecuzione medio nonostante la precisione migliore: vedere ad esempio CRlibm's implementation. Metto il verbo "garanzia" sopra le virgolette interne quando parlo delle migliori implementazioni di pow perché pow è una funzione per cui la garanzia di precisione 0,5 ULP di CRlibm è only “with astronomical probability”.