Domanda

Ho sentito che una delle motivazioni originali di McCarthy per inventare Lisp era scrivere un sistema per la differenziazione automatica.Nonostante ciò, le mie ricerche su Google non hanno prodotto librerie/macro per farlo.Esistono librerie Scheme/Common Lisp/Clojure (macro) per prendere una funzione F e restituire una funzione dF/dx che calcola la derivata di F?

Vorrei che supportasse F con più argomenti.L'utente sceglierà quale di queste è la x rispetto a cui differenziarsi.Idealmente, il differenziatore funzionerebbe anche per F e x con valori vettoriali.

MODIFICARE:Molte persone hanno menzionato la differenziazione simbolica.La differenza tra differenziazione simbolica e differenziazione automatica è sottile, ma è ben riassunta Wikipedia, e in particolare in questa immagine.Questa distinzione non è così forte in Lisp, dove le espressioni simboliche possono essere trasformate in programmi funzionanti così come sono, ma rimane una potenziale difficoltà:

La differenziazione simbolica richiede che l'espressione da differenziare sia composta da operazioni con derivati ​​noti.Ad esempio, qualcuno ha menzionato l'esempio SICP di una macro che sforna semplici sexps come (+ y (* (x y))), e utilizza la regola della catena, insieme alla conoscenza di come differenziare + E *, per restituire un sexp che rappresenta la derivata.Ne avrei bisogno per funzionare con espressioni come (* (foo x y) (bar x)), Dove foo E bar può a sua volta chiamare altre funzioni le cui derivate non sono note al momento della differenziazione.

Questo andrebbe bene se ci fosse un modo per prendere un'espressione come (foo x y) e sostituirlo con il corpo della sua funzione, sostituendo ogni menzione degli argomenti con x E y in modo igienico.È lì?

Inoltre, nessuna delle soluzioni precedenti affronta le complicazioni che si verificano quando si differenziano le funzioni con valori vettoriali rispetto agli argomenti con valori vettoriali...che è ciò a cui è destinata la maggior parte delle implementazioni di autodifferenziazione.

È stato utile?

Soluzione

Esistono altri due pacchetti, entrambi per la differenziazione automatica in Scheme.Il secondo è basato sul primo, ma rielaborato come un uovo di gallina.Supportano sia la modalità avanti che quella inversa.

Altri suggerimenti

Alexey Radul scrive:

Bene, c'è il sistema di differenziazione automatica in Scmutils

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

(che per coincidenza fa anche la differenziazione simbolica).Non conosco altre implementazioni rilasciate, anche se potresti controllare http://autodiff.org/ .

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

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

così come nella letteratura accademica.In particolare, la modalità in avanti non è così difficile, anche se devi stare attento a evitare la confusione di perturbazione.È possibile consultare le pubblicazioni di Barak Pearlmutter e Jeffrey Mark Siskind, che stanno collaborando con una variante LISP ad alte prestazioni che incorpora l'AD e hanno pubblicato su questioni circostanti.

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

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

L'output della console è OK, ma può produrre un output dall'aspetto piuttosto gradevole se abbinato texmacs.

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

MODIFICARE

OK, sembra che io abbia frainteso la domanda.Un po' di ricerche su Google suggeriscono che ci sono alcuni strumenti per questo in SCMUTILS Qui, scaricamento Qui, Manuale d'uso Qui (vedi p.24 in poi).

Potrebbe interessarti scmutlis è stato ora portato a Clojure.C'è ancora molto lavoro da fare, ma il codice nei primi capitoli del libro SICM sembra funzionare bene.

Anche le routine e gli operatori di differenziazione sembrano OK con i pochi test che ho fatto, ed è anche esente da alcuni bug che sembrano essersi insinuati nelle versioni successive di scmutils.

Penso che scmutils copra i requisiti di differenziazione di OP, poiché gestirà correttamente i derivati ​​​​di funzioni (letterali) note e sconosciute.Questa pagina fornisce i dettagli necessari per vedere se si adatta ai requisiti:SICM - Derivati ​​- Notazione

Uno dei vantaggi dell'esecuzione su JVM è che funzionerà in modo autonomo se necessario, senza nemmeno bisogno di installare Clojure!

È molto vicino allo schema originale, con minime concessioni alla sintassi di Clojure.

Potete vederlo 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 da differenziare è

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

Dopo averlo clojurificato un po', lo 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

Qui è un'implementazione di AD nel lisp comune.

Vale la pena dare un'occhiata a Deriva, che esegue la differenziazione automatica sia per Clojure che per Java:

Potresti anche essere interessato a expresso, che riguarda più la manipolazione delle espressioni numeriche ma ha ancora alcune caratteristiche di differenziazione e potrebbe probabilmente essere adattato alla maggior parte dei casi d'uso di AD:

Google per "differenziazione simbolica LISP" e troverai molti esempi, ad es.

http://mitpress.mit.edu/sicp/full-text/sicp/book/node39.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top