View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.numbers.gamma;
18  
19  /**
20   * <a href="http://mathworld.wolfram.com/LanczosApproximation.html">
21   * Lanczos approximation</a> to the Gamma function.
22   *
23   * It is related to the Gamma function by the following equation
24   * \[
25   * \Gamma(x) = \sqrt{2\pi} \, \frac{(g + x + \frac{1}{2})^{x + \frac{1}{2}} \, e^{-(g + x + \frac{1}{2})} \, \mathrm{lanczos}(x)}
26   *                                 {x}
27   * \]
28   * where \( g \) is the Lanczos constant.
29   *
30   * See equations (1) through (5), and Paul Godfrey's
31   * <a href="http://my.fit.edu/~gabdo/gamma.txt">Note on the computation
32   * of the convergent Lanczos complex Gamma approximation</a>.
33   */
34  public final class LanczosApproximation {
35      /** \( g = \frac{607}{128} \). */
36      private static final double LANCZOS_G = 607d / 128d;
37      /** Lanczos coefficients. */
38      private static final double[] LANCZOS = {
39          0.99999999999999709182,
40          57.156235665862923517,
41          -59.597960355475491248,
42          14.136097974741747174,
43          -0.49191381609762019978,
44          .33994649984811888699e-4,
45          .46523628927048575665e-4,
46          -.98374475304879564677e-4,
47          .15808870322491248884e-3,
48          -.21026444172410488319e-3,
49          .21743961811521264320e-3,
50          -.16431810653676389022e-3,
51          .84418223983852743293e-4,
52          -.26190838401581408670e-4,
53          .36899182659531622704e-5,
54      };
55  
56      /** Private constructor. */
57      private LanczosApproximation() {
58          // intentionally empty.
59      }
60  
61      /**
62       * Computes the Lanczos approximation.
63       *
64       * @param x Argument.
65       * @return the Lanczos approximation.
66       */
67      public static double value(final double x) {
68          double sum = 0;
69          for (int i = LANCZOS.length - 1; i > 0; i--) {
70              sum += LANCZOS[i] / (x + i);
71          }
72          return sum + LANCZOS[0];
73      }
74  
75      /**
76       * @return the Lanczos constant \( g = \frac{607}{128} \).
77       */
78      public static double g() {
79          return LANCZOS_G;
80      }
81  }