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

Criado/Created: NaN

Última actualização/Last updated: 10-10-2022 [14:25]


Voltar à página inicial.


GNU/Emacs Creative Commons License

(c) Tiago Charters de Azevedo