Skip to content

Instantly share code, notes, and snippets.

@RenaissanceBug
Created December 7, 2014 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RenaissanceBug/94e9e92c5af3430b963c to your computer and use it in GitHub Desktop.
Save RenaissanceBug/94e9e92c5af3430b963c to your computer and use it in GitHub Desktop.
Functions & derivatives, symbolically
#lang racket
#|
Symbolic differentiation:
An example of higher-order functions in math. Includes:
* Basic function constructors:
- identity
- constant functions for several small numbers
- power-functions (x^n for given n)
* Functions of functions, or function combinators:
- d/dx : given function, produce derivative
- f+, f*, f/ : given functions f & g, produce functions (f + g), etc
- of : compose given functions f & g
* Examples showing how to define exponential and trig functions.
jmj, 2012.
|#
(require test-engine/racket-tests)
(provide (all-defined-out))
;; Func = (func (Num -> Num) (Num -> Num))
;; Represents a pair of functions, f(x) and f'(x).
(define-struct func (f df/dx)
#:property prop:procedure 0)
;; The identity function, f(x) = x:
(define id (func (lambda (x) x) (lambda (x) 1)))
;; d/dx : Func -> (Num -> Num)
;; Obtains the function's derivative
(check-expect ((d/dx id) 5) 1)
(define (d/dx f) (func-df/dx f))
;; const : Num -> Func
;; Returns a constant function
(check-expect ((const 5) 2) 5)
(check-expect ((d/dx (const 5)) 2) 0)
(define (const n) (func (lambda (x) n) (lambda (x) 0)))
;; Constants:
(define one (const 1))
(define two (const 2))
(define three (const 3))
(define four (const 4))
(define five (const 5))
;; f+ : Func Func -> Func
;; Given f(x) and g(x), returns (f+g)(x).
(check-expect ((f+ id four) 3) 7)
(check-expect ((d/dx (f+ id id)) 3) 2)
(define (f+ f g)
(func (lambda (x) (+ (f x) (g x)))
(lambda (x) (+ ((d/dx f) x) ((d/dx g) x)))))
; Ex:
(define x*2 (f+ id id))
;; f* : Func Func -> Func
;; Given f(x) and g(x), returns (f*g)(x).
(check-expect ((f* id id) 3) 9)
(check-expect ((d/dx (f* id id)) 3) 6)
(define (f* f g)
(func (lambda (x) (* (f x) (g x)))
(lambda (x) (+ (* (f x) ((d/dx g) x))
(* ((d/dx f) x) (g x))))))
; Ex:
(define x^2 (f* id id))
;; f/ : Func Func -> Func
;; Given f(x) and g(x), returns (f/g)(x)
(define (f/ f g)
(func (lambda (x) (/ (f x) (g x)))
(lambda (x)
(local [(define gx (g x))]
(/ (- (* gx ((d/dx f) x)) ;; quotient rule
(* (f x) ((d/dx g) x)))
(* gx gx))))))
;; of : Func Func -> Func
;; Using the chain rule -- if h = fg, then dh/dx = df/dg * dg/dx --
;; this returns f(g(x)).
(define (of f g)
(func (lambda (x) (f (g x)))
(lambda (x)
(* ((d/dx g) x)
((d/dx f) (g x))))))
;; power : Nat -> Func
;; Returns f(x) = x^n.
(define (power n)
(cond
[(zero? n) (const 1)]
[else
(func (lambda (x) (expt x n))
(lambda (x) (* n (expt x (- n 1)))))]))
;;;; Logs and exponentials.
(define e 2.718281828459045)
(define ln (func log (power -1)))
(define e^x (func (lambda (x) (expt e x))
(lambda (x) (expt e x))))
;;;; Trig functions.
(define sinf (func sin cos))
(define cosf (func cos
(lambda (x) (- (sin x)))))
(define tanf (func tan
(lambda (x) (sqr (/ 1 (cos x))))))
(define cotf (func (lambda (x) (/ 1 (tan x)))
(lambda (x) (- (sqr (/ 1 (sin x)))))))
(define secf (func (lambda (x) (/ 1 (cos x)))
(lambda (x) (* (/ 1 (cos x)) (tan x)))))
(define cscf (func (lambda (x) (/ 1 (sin x)))
(lambda (x)
(* -1
(/ 1 (sin x))
(/ 1 (tan x))))))
(test)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment