12

Ho sentito che una delle motivazioni originali di McCarthy per l'invenzione di Lisp era scrivere un sistema per la differenziazione automatica. Nonostante questo, le mie ricerche su Google non hanno prodotto librerie/macro per fare ciò. Ci sono delle librerie Scheme/Common Lisp/Clojure (macro) là fuori per prendere una funzione F e restituire una funzione dF/dx che calcola la derivata di F?Libreria di differenziazione automatica in Schema/Common Lisp/Clojure

Vorrei che supporti F con più argomenti. L'utente dovrebbe scegliere quale di questi è la x da differenziare rispetto a. Idealmente, il differenziatore funzionerebbe anche per F e x di valore vettoriale.

EDIT: Diverse persone hanno menzionato la differenziazione simbolica. La differenza tra differenziazione simbolica e differenziazione automatica è sottile, ma è sintetizzata bene in Wikipedia e in particolare in this picture. Questa distinzione non è così forte in lisp, dove le espressioni simboliche possono essere trasformate in programmi di lavoro così come sono, ma rimane una potenziale difficoltà:

La differenziazione simbolica richiede che l'espressione sia differenziata per essere composta di operazioni con derivate note. Ad esempio, qualcuno ha citato l'esempio di SICP di una macro che agisce attraverso semplici sexps come (+ y (* (x y))), e usa la regola della catena, insieme alla conoscenza di come differenziare + e *, per restituire un sexp che rappresenta la derivata. Avrei bisogno di questo per lavorare con espressioni come (* (foo x y) (bar x)), dove foo e bar possono a loro volta chiamare altre funzioni i cui derivati ​​non sono noti al momento della differenziazione.

Questo sarebbe bene se c'è un modo per prendere un'espressione come (foo x y) e sostituirlo con il suo corpo funzione, sostituendo qualsiasi menzione degli argomenti con x e y in modo igienico. È lì?

Inoltre, nessuno dei problemi di cui sopra riguarda le complicazioni che si verificano quando si differenziano le funzioni con valori vettoriali rispetto agli argomenti con valori vettoriali ... che è ciò per cui sono implementate la maggior parte delle implementazioni di autodifferenziazione.

+2

Il tag "numeriche-metodi" non è adeguata per la tua domanda , perché ciò che stai chiedendo è la differenziazione simbolica. Trovare la derivata di una funzione f in x per differenziazione numerica sarebbe semplicemente un calcolo di (f (x + dx) -f (x))/dx per qualche piccolo valore di dx. – Curd

+3

@ curd: aggiungendo il tag numerical-methods, non intendevo implicare che stavo cercando un modo per eseguire la differenziazione numerica, che, chiaramente, non lo sono. Volevo solo dire che la domanda riguarda le funzioni relative al calcolo numerico (ad esempio, valutare le espressioni simboliche che implementano metodi numerici). – SuperElectric

+2

Sono con te. È frustrante il modo in cui ogni volta che accenno alla differenziazione automatica le persone lo confondono con la differenziazione simbolica e spesso si rifiutano di sentire che c'è una differenza. È sicuramente un "metodo numerico", e certamente non è una "differenziazione numerica". – sigfpe

risposta

3

Se stai cercando un sistema simbolico, potresti provare maxima (o here). Funziona su una serie di combinazioni di piattaforme Common-Lisp/OS, ma è più di un sistema completo di una libreria.

L'output della console è OK, ma può produrre un output dall'aspetto piacevole se accoppiato con .

Maxima 5.23.2 http://maxima.sourceforge.net 
using Lisp GNU Common Lisp (GCL) GCL 2.6.8 (a.k.a. GCL) 
Distributed under the GNU Public License. See the file COPYING. 
Dedicated to the memory of William Schelter. 
The function bug_report() provides bug reporting information. 
(%i1) diff(sin(1/x),x); 
             1 
            cos(-) 
             x 
(%o1)        - ------ 
             2 
             x 

EDIT

OK, sembra che ho capito male la domanda. Un po 'di googling suggerisce che ci sono alcuni strumenti per questo in SCMUTILS here, download here, manuale utente here (vedi p24 in poi).

+0

Grazie, ma gli strumenti esterni per la differenziazione simbolica non sono quello che sto cercando. Ho modificato la domanda per chiarire questo. – SuperElectric

+0

Dovrebbe essere possibile utilizzare Maxima come libreria da qualsiasi programma lisp comune (e quindi può essere utilizzato dall'interno di una macro), quindi non è quella "esterna" dopo tutto. –

+0

È la simbolicità che è un problema. Sto cercando una macro che accetta una funzione F e restituisce una funzione F '. Intendo una funzione valutabile, che accetta argomenti numerici, non un'espressione simbolica. – SuperElectric

7

Alexey Radul scrive:

Beh, c'è il sistema di differenziazione automatica Scmutils

http://groups.csail.mit.edu/mac/users/gjs/6946/linux-install.htm

(che fa a caso anche la differenziazione simbolica). Non conosco altre implementazioni rilasciate, sebbene sia possibile effettuare il controllo http://autodiff.org/.

C'è anche una bella spiegazione di come implementare da soli in un appendice della struttura e di interpretazione della meccanica classica

http://mitpress.mit.edu/sicm/

così come nella letteratura accademica. La modalità particolarmente avanzata è non così difficile, anche se devi fare attenzione ad evitare la perturbazione dello confusione. È possibile consultare le pubblicazioni di Barak Pearlmutter e Jeffrey Mark Siskind, che stanno collaborando su una variante Lisp ad alte prestazioni che incorpora l'annuncio pubblicitario e sono state pubblicate sui problemi relativi a .

http://scholar.google.com/scholar?q=Barak+Pearlmutter+and+Jeffrey+Mark+Siskind

+0

Grazie! Un'ultima cosa: potresti definire o forse fornire un riferimento al termine "confusione perturbativa"? Non ho familiarità con il termine. – SuperElectric

+1

Ok ho trovato la risposta da solo, da questo documento: http://eprints.nuim.ie/archive/00000566/01/Perturbation.pdf "queste implementazioni (...) possono calcolare risultati grossolanamente errati quando l'operatore di differenziazione viene applicato a una funzione che a sua volta usa quell'operatore: la causa alla base di questo problema è la confusione perturbativa, l'incapacità di distinguere tra distinte perturbazioni introdotte da distinte invocazioni dell'operatore di differenziazione, e poi discutere su come evitare la confusione delle perturbazioni ". – SuperElectric

1

Here è un'implementazione di AD in lisp comune.

1

Vale la pena di verificare Deriva, che fa differenziazione automatica sia per Clojure e Java:

Si può anche essere interessato espresso, che è più sulla manipolazione espressione numerica ma ha ancora alcune caratteristiche di differenziazione e probabilmente potrebbe essere adattato alla maggior parte dei casi di utilizzo AD:

2

Può essere di interesse che scmutlis ora è stato portato su Clojure. C'è ancora molto lavoro da fare, ma il codice nei primi capitoli del libro SICM sembra funzionare bene.

Le routine di differenziazione e gli operatori sembrano anche OK con quel piccolo test che ho fatto, ed è anche privo di alcuni bug che sembrano essersi introdotti nelle versioni successive di scmutils.

Penso che gli scmutils coprano le esigenze dell'OP per la differenziazione, dal momento che gestirà correttamente i derivati ​​sia delle funzioni conosciute che di quelle sconosciute (letterali). Questa pagina fornisce i dettagli necessari per vedere quanto bene si adatta ai requisiti: SICM - Derivatives - Notation

Uno dei vantaggi di esecuzione sulla JVM, è che verrà eseguito come un autonomo in caso affermativo richiesto, non c'è bisogno nemmeno di installare Clojure!

È molto vicino allo Schema originale, concessioni minime fatte per la sintassi di Clojure.

Potete vedere qui: https://github.com/littleredcomputer/sicmutils#sicmutils

===

Addendum: Ecco un esempio di differenziazione automatica nel pacchetto SicmUtils Clojure. Questo è un esempio comune che circola su vari siti Internet, il codice deve essere differenziato è

function f(x) 
     y = x; 
     for i=1...100 
     y = sin(x+y); 
     return y 

Dopo Clojurifying un po 'abbiamo

> (defn inner [y] (fn[x] (sin (+ x y)))) 
    > (defn f100 [x] (nth (iterate (inner x) x) 100)) 
    ;; value of derivative at 6 
    > ((D f100) 6) 
    => 0.51603111348625 
    ;; value of the 4th derivative at 1 
    > (((expt D 4) f100) 1) 
    => -1.7853200839806143 
Problemi correlati