Diferenciando funções

Cálculo de derivadas, uma implementação da função diff de John McCarthy em Emacs Lisp

Ora aqui está um exemplo muito útil, baseada na definição de diff de John McCarthy, que calcula a derivada de um polinómio (funciona em Emacs Lisp e Common Lisp).

(defun differentiate (y x)
  "Calculates the derivative of y as a function of x. Only for polynomials y=P(x)
written in prefix notation."
  (cond ((atom y)
         (cond ((eq x y)
                1)
               (t
                0)))
        ((eq (car y) '+)
         (cons '+ (maplist (lambda (z)
                             (differentiate (car z) x))
                           (cdr y))))
        ((eq (car y) '*)
         (cons '+ (maplist (lambda (z)
                             (cons '* (maplist (lambda (w) (if (not (eq z w))
                                                               (car w)
                                                             (differentiate (car w) x)))
                                               (cdr y))))
                           (cdr y))))))

Alguns exemplos

> (differentiate  'x 'x)

1

> (differentiate '(* 2 x) 'x)

(+ (* 0 x) (* 2 1))

> (differentiate '(* x (+ 1 x))  'x)

(+ (* 1 (+ 1 x)) (* x (+ 0 1)))
> (differentiate '(* x (+ 1 y))  'x)

(+ (* 1 (+ 1 y)) (* x (+ 0 0)))

Uma procura na net revela muitas outras funções que fazem o mesmo que a anterior. Estranho é que aquela definida por John McCarthy não aparece em mais lado nenhum (para além das páginas de JMC) e, note-se, é bastante curta e directa. Basta apenas escrever uma outra função que simplifica o output para ficar completa. Claro que y pode ser escrito em ambas as formas

> (differentiate '(+ x (* 1 x) (+ 3 x)) 'x)

(+ 1 (+ (* 0 x) (* 1 1)) (+ 0 1))
ou
> (differentiate '(+ 3 (* 3 x)) 'x)

(+ 0 (+ (* 0 x) (* 3 1)))
Palavras chave/keywords: Emacs Lisp, diff, John McCarthy, Common Lisp

Última actualização/Last updated: 2014-02-20 [14:37]


1999-2014 (ç) Tiago Charters de Azevedo

São permitidas cópias textuais parciais/integrais em qualquer meio com/sem alterações desde que se mantenha este aviso.

Verbatim copying and redistribution of this entire page are permitted provided this notice is preserved.