-
Notifications
You must be signed in to change notification settings - Fork 1
/
special-functions.rkt
43 lines (36 loc) · 1.59 KB
/
special-functions.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#lang racket/base
(require "misc.rkt"
"arithmetic.rkt"
(prefix-in rkt: math/special-functions))
(provide gamma psi0 erf erfc lambert lambert- zeta eta
Fresnel-S Fresnel-C Fresnel-RS Fresnel-RC)
;; TODO: a mechanism to add matchers for different functions and useful identities,
;; for example (+ (^ (cos x) 2) (^ (sin x) 2) reduces to 1,
;; or (* X (gamma Y) (^ (gamma (+ 1 Y)) -1) = (* X (^ Y -1)),
;; or (log (gamma x)) is calculated with rkt:log-gamma
;;
;; The matcher would be on the main operator, here '+ or '*.
;; But we need something fast such that adding many rules doesn't slow down
;; everything.
;; https://en.wikipedia.org/wiki/Gamma_function
(define-simple-function gamma rkt:gamma)
(define-simple-function psi0 rkt:psi0)
(define-simple-function erf rkt:erf)
(define-simple-function erfc rkt:erfc)
(define-simple-function lambert rkt:lambert)
(define-simple-function lambert- rkt:lambert-)
(define-simple-function zeta rkt:zeta)
(define-simple-function eta rkt:eta)
(define-simple-function Fresnel-S rkt:Fresnel-S)
(define-simple-function Fresnel-C rkt:Fresnel-C)
(define-simple-function Fresnel-RS rkt:Fresnel-RS)
(define-simple-function Fresnel-RC rkt:Fresnel-RC)
(register-derivative 'gamma (λ (v) (* (gamma v) (psi0 v))))
;; TODO: Special values for gamma: 1/2, 3/2, ...
(module+ test
(require rackunit
"automatic-simplify.rkt")
(check-false (number? (log (gamma 3/2))))
(check-pred number? (->inexact (log (gamma 3/2))))
(check-false (number? (psi0 3)))
(check-pred number? (->inexact (psi0 3))))