(define-syntax dual-op
;; https://en.wikipedia.org/wiki/Chain_rule#Case_of_scalar-valued_functions_with_multiple_inputs
;; dF(x,y,z...)/dx = sum (df/di * f(x,y,z...))
(syntax-rules ()
[(_ fn df ...)
(lambda args
(let ((reals (map dual-number-real args ))
(infinitesimals (map dual-number-infinitesimal args ))
(partial-derivs (list df ...)))
(make-dual
(apply fn reals)
(apply +
(map (lambda (eps partial)
(* eps (apply partial reals)))
infinitesimals partial-derivs)))))]))
(define (dual-div d1 d2)
;; F(x,y) = x * 1/y
;; df/dx = 1/y
;; df/dy = -x/y^2
((dual-op / (lambda (x y) (/ 1 y)) (lambda (x y) (/ (- x) (expt y 2))))
d1 d2))
chain rule for my autodiff thing