Diferenciando funções
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: Emacs Lisp, diff, John McCarthy, Common Lisp
Última actualização/Last updated: 2012-02-26 [15:48]
1999-2011 (c) 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.
