Derivati ​​numerici e coefficienti di differenza finita: qualche aggiornamento del metodo Fornberg?


11

Quando si vogliono calcolare derivati ​​numerici, il metodo presentato da Bengt Fornberg qui (e riportato qui ) è molto conveniente (sia preciso che semplice da implementare). Alla data del documento originale del 1988, vorrei sapere se esiste un'alternativa migliore oggi (come (o quasi) semplice e più precisa)?


1
Difficile dirlo senza sapere cosa si desidera differenziare. Hai preso in considerazione la differenziazione automatica ?
Biswajit Banerjee,

@BiswajitBanerjee: per i coefficienti di differenza finita, la differenziazione automatica non si applica.
Geoff Oxberry,

@GeoffOxberry: mi riferivo al vero problema fisico, cioè alla parte scientifica della "scienza computazionale".
Biswajit Banerjee,

@Vincent: stai provando a differenziare una funzione o una tabella? Se i dati della tabella, i dati della tabella sono rumorosi? Stai cercando di discretizzare un PDE?
user14717

Risposte:


9

Panoramica

Buona domanda. C'è un documento intitolato "Migliorare l'accuratezza del metodo di differenziazione della matrice per i punti di collocazione arbitrari" di R. Baltensperger. A mio avviso non è un grosso problema, ma ha un punto (che era già noto prima dell'apparizione nel 2000): sottolinea l'importanza di una rappresentazione accurata del fatto che la derivata della funzione costante f(x)=1 dovrebbe essere zero (questo vale esattamente in senso matematico, ma non necessariamente nella rappresentazione numerica).

È semplice vedere che ciò richiede che le somme delle righe delle n-esime matrici derivate D(n) siano zero. È comune applicare questo vincolo regolando la diagonale, ovvero impostando

(1)Djj(n):=i=1ijNDij.
È chiaro che questa funzione non è valida quando si lavora su un computer a causa di errori di arrotondamento nei calcoli in virgola mobile. La cosa più sorprendente è che questi errori sono ancora più gravi quando si usano le formule analitiche per la matrice derivativa (che sono disponibili per molti punti di collocazione classici, ad esempio Gauss-Lobatto).

Ora, il documento (e i riferimenti in esso) afferma che l'errore della derivata è nell'ordine della deviazione della riga somma da zero. L'obiettivo è quindi di renderli numericamente i più piccoli possibili.

Test numerici

Il punto positivo è che la procedura di Fornberg sembra essere abbastanza buona in questo senso. Nell'immagine seguente ho confrontato il comportamento della prima matrice derivativa, analitica, esatta e quella derivata dall'algoritmo di Fornberg, per un numero variabile di punti di collocazione di Chebyshev-Lobatto.

Ancora una volta, credendo alla dichiarazione nel documento citato, questo implica che l'algoritmo di Fornberg produrrà risultati più accurati per il derivato.

(2)f(x)=11+x2.
(3)En=maxi{0,,n}|f(xi)j=1nDijf(xj)|.
(4)D~jj=Djj(i=1nDji),for all j.

Conclusione

In conclusione, il metodo di Fornberg sembra essere abbastanza accurato, nel caso anche di circa 3 ordini di grandezza più accurati dei risultati delle formule analitiche. Questo dovrebbe essere abbastanza preciso per la maggior parte delle applicazioni. Inoltre, questo è notevole perché Fornberg non sembra includere esplicitamente questo fatto nel suo metodo (almeno non c'è menzione nei due articoli di Fornberg).N=512

Un altro ordine di grandezza può essere ottenuto per questo esempio attraverso una semplice inclusione dell'Eq. (4). Poiché si tratta di un approccio abbastanza semplice e applicato una sola volta per ogni derivata, non vedo alcun motivo per non utilizzarlo.

Il metodo dal documento Baltensperger - che utilizza un approccio più sofisticato per valutare la somma nell'Eq. (1) al fine di ridurre gli errori di arrotondamento - produce circa lo stesso ordine di grandezza per l'errore. Quindi, almeno per questo esempio, è approssimativamente equivalente al metodo "Adjusted Fornberg" sopra.


4

Supponendo che si stia tentando di differenziare un'implementazione numerica di una funzione continua, esistono numerosi metodi:

1) Differenziazione automatica. Il metodo più accurato e generale. Doloroso codificare, richiede un sovraccarico dell'operatore e una ricerca dipendente dall'argomento. Mette a carico l'utente la comprensione di questi concetti. Lotta anche con singolarità rimovibili, come la differenziazione di sinc in .x=0

2) Una trasformazione di Chebyshev. Proietta la tua funzione su un arco di polinomi di Chebyshev e differenzia i tre termini ricorrenti. Super veloce, molto preciso. Ma richiede di avere un dominio di interesse supportato in modo compatto; al di fuori del dominio selezionato , la ricorrenza a tre termini è instabile.[a,b]

3) Differenziazione finita. Sottovalutato in 1D; vedere i suggerimenti e i trucchi di Nick Higham nel calcolo numerico . L'idea è che se si bilanciano l'errore di troncamento e l'errore di arrotondamento, non è necessario selezionare una dimensione; può essere scelto automaticamente. In Boost, questa idea viene utilizzata per recuperare (per impostazione predefinita) il 6/7 delle cifre corrette per il tipo. (Higham mostra solo l'idea per il caso più semplice di 1/2 delle cifre corrette, ma l'idea è facilmente ampliabile.) I coefficienti sono tratti dalla tabella corretta di Fornberg, ma il passo è scelto partendo dal presupposto che la funzione può essere valutata a 1ULP precisione. Lo svantaggio è che richiede 2 valutazioni di funzione per recuperare metà delle cifre del tipo, 4 per recuperare 3/4 delle cifre, ecc. In 1D, non è un cattivo affare. In dimensioni superiori, è catastrofico.

4) La derivata complessa del passaggio. Usa . Prendi come unità di arrotondamento e questo recupererà quasi ogni bit corretto. Tuttavia, è un po 'imbroglione, perché è generalmente più difficile implementare una funzione nel piano complesso che codificare a mano la sua derivata reale. Ancora un'idea interessante e utile in determinate circostanze.f(x)(f(x+ih))h


1

Io non sono a conoscenza di tutti coloro che hanno migliorato l'algoritmo di Fornberg (si veda anche la sua un po 'più recente della carta ). A parte questo, mi sembra che guardare il suo algoritmo come un modo per calcolare le derivate numeriche non sia giusto. Tutto quello che ha fatto è derivare un algoritmo efficiente per calcolare pesi per metodi a differenza finita. Il vantaggio del suo metodo è che ti dà i pesi per tutti i derivati ​​fino alla derivata desiderata in una volta sola.


Non sarei d'accordo con l'affermazione "guardare il suo algoritmo come un modo per calcolare le derivate numeriche non è giusto". Dopo aver valutato i pesi per il punto , è possibile calcolare direttamente la derivata numerica di qualsiasi funzione tramite . wizf(x)f(z)=iwif(xi)
davidhigh

@davidhigh: se leggi gli articoli di Fornberg, parlano del calcolo dei pesi per approssimazioni alle differenze finite, non del calcolo delle approssimazioni stesse. Naturalmente è possibile utilizzare anche l'algoritmo per calcolare le derivate, ma ha più senso calcolare i pesi, memorizzarli e quindi utilizzarli ripetutamente per calcolare le derivate approssimative. Altrimenti stai calcolando i pesi ripetutamente quando non è necessario.
Brian Zatapatique,

1

Uno schema più semplice

Oltre all'altra mia risposta che riguarda più un'estensione del metodo Fornberg, affronterò qui la domanda per alternative più semplici.

Per questo disegno uno schema alternativo che produce più direttamente i coefficienti derivati ​​dell'interpolazione lagrangiana. La sua implementazione richiede solo poche righe di codice, funziona con griglie arbitrarie e, secondo i miei primi esperimenti, è accurata come quella di Fornberg.

La base dell'implementazione è la derivata del passo immaginario dove è una variabile nell'ordine di precisione della macchina. È noto che la derivata del passo immaginario produce stabilmente valori derivati ​​e non soffre dell'instabilità numerica di un'implementazione della differenza finita con .

f(x) = 1hIm(f(x+ih)),
hh0

Il secondo ingrediente è il polinomio di interpolazione Lagrange sulla griglia valutato con una delle forme baricentriche, ad esempio dove Per usare la derivata a passo complesso, bisogna assicurarsi che queste formule funzionino anche per complessi argomenti . Inoltre, per una data funzione f (x) e vettore dei coefficienti , denotiamo il polinomio di interpolazione attraverso con Li(x){x1,,xN}

Li(z) = {1if z=xi μizxkkμkzxkotherwise.
μi=1ki(xixk)zfi=f(xi)(x1,fi)
P(x;f)=i=1NfiLi(x).


Algoritmo

L'algoritmo è illustrato di seguito. Ha gli stessi parametri di input e output di quello di Fornberg, ma è molto più semplice.

Ingresso:

  • x : una griglia con N punti griglia distinti
  • ord : ordine derivato
  • z: un punto in cui la derivata deve essere valutata
  • Possibilmente: una funzione o i suoi valori di funzione ai punti della griglia (richiesto solo per la variante di output 2)f(x)fi

Inizializzazione

  • Inizializzazione dei polinomi di Lagrange tramite interpolazione baricentrica.L
  • Inizializza una matrice di -matrices , perN×ND(o)o=0,,ord
  • Impostare , ovvero la matrice unitaria della dimensioneD(0):=INN×N
  • Impostareo:=0

Algoritmo

Mentre :o<ord

  • Calcola dal derivato a passaggi complessi per tutti e . Qui, indica la fila -esimo .Dik(o+1)=CSD(P(xk;Di(o)))CSDik
    Di(o)iD(o)

  • Impostare o = o + 1;

Decidi cosa produrre :

  1. Il vettore dei coefficienti di differenza finita nel punto , dove . Questo è quello che fa Fornberg.d(ord)zdi=P(z;Di(ord))

  2. La funzione di interpolazione al derivato dell'ordine . Per questo, devi inserire una funzione resp. la funzione valori in all'algoritmo.p(ord)(x)=i=1Nf(xi)P(x;Di(ord))f(ord)(x)ordfixi

  3. Una meta-funzione che restituisce la funzione di interpolazione della variante 2., ma per una funzione arbitraria che deve essere interpolata ai punti della griglia.diff(int ord,function g)g

Personalmente, mi piace di più la variante 3.


Analisi dell'algoritmo

Come Fornberg, questo algoritmo è . Pubblicherò risultati più empirici riguardo l'accuratezza, la stabilità, ecc. Se trovo il tempo.O(ordN2)


0

Per aumentare la precisione della differenziazione numerica, procedere come segue:

1) Scegli il tuo metodo "standard" preferito di alta precisione basato su un passo h .

2) Calcola il valore del derivato con il metodo scelto in 1) molte volte con passi diversi ma ragionevoli h . Ogni volta che puoi scegliere h come numero casuale dall'intervallo (0,5 * H / 10, 1,5 * H / 10) in cui H è una dimensione del gradino appropriata per il metodo che usi.

3) Media dei risultati.

Il risultato può guadagnare 2-3 ordini di grandezza nell'errore assoluto. il risultato non medio.

https://arxiv.org/abs/1706.10219


3
Benvenuti su SciComp.SE! Questa risposta sarebbe ancora migliore se riassumessi brevemente il metodo.
Christian Clason,

2
Anche il tuo nome utente suggerisce che hai creato quel documento. Leggi le nostre linee guida sull'autopromozione e modifica il tuo post di conseguenza.
Wrzlprmft,

Onestamente, penso che il voto negativo sia ingiusto se la mia risposta indica effettivamente una risposta valida.
F. Jatpil,

1
Anch'io ... quindi prendi il mio +1 ... :-)
davidhigh il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.