LanczosApproximation.java

  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.  * <a href="http://mathworld.wolfram.com/LanczosApproximation.html">
  20.  * Lanczos approximation</a> to the Gamma function.
  21.  *
  22.  * It is related to the Gamma function by the following equation
  23.  * \[
  24.  * \Gamma(x) = \sqrt{2\pi} \, \frac{(g + x + \frac{1}{2})^{x + \frac{1}{2}} \, e^{-(g + x + \frac{1}{2})} \, \mathrm{lanczos}(x)}
  25.  *                                 {x}
  26.  * \]
  27.  * where \( g \) is the Lanczos constant.
  28.  *
  29.  * See equations (1) through (5), and Paul Godfrey's
  30.  * <a href="http://my.fit.edu/~gabdo/gamma.txt">Note on the computation
  31.  * of the convergent Lanczos complex Gamma approximation</a>.
  32.  */
  33. public final class LanczosApproximation {
  34.     /** \( g = \frac{607}{128} \). */
  35.     private static final double LANCZOS_G = 607d / 128d;
  36.     /** Lanczos coefficients. */
  37.     private static final double[] LANCZOS = {
  38.         0.99999999999999709182,
  39.         57.156235665862923517,
  40.         -59.597960355475491248,
  41.         14.136097974741747174,
  42.         -0.49191381609762019978,
  43.         .33994649984811888699e-4,
  44.         .46523628927048575665e-4,
  45.         -.98374475304879564677e-4,
  46.         .15808870322491248884e-3,
  47.         -.21026444172410488319e-3,
  48.         .21743961811521264320e-3,
  49.         -.16431810653676389022e-3,
  50.         .84418223983852743293e-4,
  51.         -.26190838401581408670e-4,
  52.         .36899182659531622704e-5,
  53.     };

  54.     /** Private constructor. */
  55.     private LanczosApproximation() {
  56.         // intentionally empty.
  57.     }

  58.     /**
  59.      * Computes the Lanczos approximation.
  60.      *
  61.      * @param x Argument.
  62.      * @return the Lanczos approximation.
  63.      */
  64.     public static double value(final double x) {
  65.         double sum = 0;
  66.         for (int i = LANCZOS.length - 1; i > 0; i--) {
  67.             sum += LANCZOS[i] / (x + i);
  68.         }
  69.         return sum + LANCZOS[0];
  70.     }

  71.     /**
  72.      * Return the Lanczos constant \( g = \frac{607}{128} \).
  73.      *
  74.      * @return the Lanczos constant.
  75.      */
  76.     public static double g() {
  77.         return LANCZOS_G;
  78.     }
  79. }