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
1º
> (differentiate 'x 'x) 1
2º
> (differentiate '(* 2 x) 'x) (+ (* 0 x) (* 2 1))
3º
> (differentiate '(* x (+ 1 x)) 'x) (+ (* 1 (+ 1 x)) (* x (+ 0 1)))
4º
> (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]
(c) Tiago Charters de Azevedo