module Numeric.Digamma (digamma) where
import Math.Polynomial
digamma :: RealFloat a => a -> a
digamma 0 = 1/0
digamma x | x < 0 = let x' = 1*x in digamma (x'+1) + pi / tan (pi*x')
digamma 1 = 0.5772156649015328606065121
digamma 2 = pi**2 / 6
digamma x | x <= small = digamma 1 1/x + digamma 2 * x
| x > small && x < large = digamma (x+1) 1/x
where small = 1e-6
large = 9.5
digamma x = let r = 1/x
in log x p `evalPoly` (1/x)
where p = poly LE [ 0, 1/2, 1/12, 1/120, 1/252, 1/240, 1/132, 691/32760, 1/12, 3617/8160 ]