| // Copyright ©2016 The Gonum Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package mathext |
| |
| import ( |
| "math" |
| ) |
| |
| // Digamma returns the logorithmic derivative of the gamma function at x. |
| // ψ(x) = d/dx (Ln (Γ(x)). |
| func Digamma(x float64) float64 { |
| // This is adapted from |
| // http://web.science.mq.edu.au/~mjohnson/code/digamma.c |
| var result float64 |
| switch { |
| case math.IsNaN(x), math.IsInf(x, 1): |
| return x |
| case math.IsInf(x, -1): |
| return math.NaN() |
| case x == 0: |
| return math.Copysign(math.Inf(1), -x) |
| case x < 0: |
| if x == math.Floor(x) { |
| return math.NaN() |
| } |
| // Reflection formula, http://dlmf.nist.gov/5.5#E4 |
| _, r := math.Modf(x) |
| result = -math.Pi / math.Tan(math.Pi*r) |
| x = 1 - x |
| } |
| for ; x < 7; x++ { |
| // Recurrence relation, http://dlmf.nist.gov/5.5#E2 |
| result -= 1 / x |
| } |
| x -= 0.5 |
| xx := 1 / x |
| xx2 := xx * xx |
| xx4 := xx2 * xx2 |
| // Asymptotic expansion, http://dlmf.nist.gov/5.11#E2 |
| result += math.Log(x) + (1.0/24.0)*xx2 - (7.0/960.0)*xx4 + (31.0/8064.0)*xx4*xx2 - (127.0/30720.0)*xx4*xx4 |
| return result |
| } |