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="https://mathworld.wolfram.com/RegularizedGammaFunction.html"> 21 * Regularized Gamma functions</a>. 22 * 23 * <p>By definition, the lower and upper regularized gamma functions satisfy: 24 * 25 * <p>\[ 1 = P(a, x) + Q(a, x) \] 26 * 27 * <p>This code has been adapted from the <a href="https://www.boost.org/">Boost</a> 28 * {@code c++} implementation {@code <boost/math/special_functions/gamma.hpp>}. 29 * 30 * @see 31 * <a href="https://www.boost.org/doc/libs/1_77_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html"> 32 * Boost C++ Incomplete Gamma functions</a> 33 */ 34 public final class RegularizedGamma { 35 /** Private constructor. */ 36 private RegularizedGamma() { 37 // intentionally empty. 38 } 39 40 /** 41 * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> 42 * Lower regularized Gamma function</a> \( P(a, x) \). 43 * 44 * <p>\[ P(a,x) = 1 - Q(a,x) = \frac{\gamma(a,x)}{\Gamma(a)} = \frac{1}{\Gamma(a)} \int_0^x t^{a-1}\,e^{-t}\,dt \] 45 */ 46 public static final class P { 47 /** Prevent instantiation. */ 48 private P() {} 49 50 /** 51 * Computes the lower regularized gamma function \( P(a, x) \). 52 * 53 * @param a Argument. 54 * @param x Argument. 55 * @return \( P(a, x) \). 56 * @throws ArithmeticException if the continued fraction fails to converge. 57 */ 58 public static double value(double a, 59 double x) { 60 return BoostGamma.gammaP(a, x); 61 } 62 63 /** 64 * Computes the lower regularized gamma function \( P(a, x) \). 65 * 66 * @param a Argument. 67 * @param x Argument. 68 * @param epsilon Tolerance in series evaluation. 69 * @param maxIterations Maximum number of iterations in series evaluation. 70 * @return \( P(a, x) \). 71 * @throws ArithmeticException if the series evaluation fails to converge. 72 */ 73 public static double value(double a, 74 double x, 75 double epsilon, 76 int maxIterations) { 77 return BoostGamma.gammaP(a, x, new Policy(epsilon, maxIterations)); 78 } 79 80 /** 81 * Computes the derivative of the lower regularized gamma function \( P(a, x) \). 82 * 83 * <p>\[ \frac{\delta}{\delta x} P(a,x) = \frac{e^{-x} x^{a-1}}{\Gamma(a)} \] 84 * 85 * <p>This function has uses in some statistical distributions. 86 * 87 * @param a Argument. 88 * @param x Argument. 89 * @return derivative of \( P(a,x) \) with respect to x. 90 * @since 1.1 91 */ 92 public static double derivative(double a, 93 double x) { 94 return BoostGamma.gammaPDerivative(a, x); 95 } 96 } 97 98 /** 99 * <a href="http://mathworld.wolfram.com/RegularizedGammaFunction.html"> 100 * Upper regularized Gamma function</a> \( Q(a, x) \). 101 * 102 * <p>\[ Q(a,x) = 1 - P(a,x) = \frac{\Gamma(a,x)}{\Gamma(a)} = \frac{1}{\Gamma(a)} \int_x^{\infty} t^{a-1}\,e^{-t}\,dt \] 103 */ 104 public static final class Q { 105 /** Prevent instantiation. */ 106 private Q() {} 107 108 /** 109 * Computes the upper regularized gamma function \( Q(a, x) \). 110 * 111 * @param a Argument. 112 * @param x Argument. 113 * @return \( Q(a, x) \). 114 * @throws ArithmeticException if the series evaluation fails to converge. 115 */ 116 public static double value(double a, 117 double x) { 118 return BoostGamma.gammaQ(a, x); 119 } 120 121 /** 122 * Computes the upper regularized gamma function \( Q(a, x) \). 123 * 124 * @param a Argument. 125 * @param x Argument. 126 * @param epsilon Tolerance in series evaluation. 127 * @param maxIterations Maximum number of iterations in series evaluation. 128 * @return \( Q(a, x) \). 129 * @throws ArithmeticException if the series evaluation fails to converge. 130 */ 131 public static double value(final double a, 132 double x, 133 double epsilon, 134 int maxIterations) { 135 return BoostGamma.gammaQ(a, x, new Policy(epsilon, maxIterations)); 136 } 137 138 /** 139 * Computes the derivative of the upper regularized gamma function \( Q(a, x) \). 140 * 141 * <p>\[ \frac{\delta}{\delta x} Q(a,x) = -\frac{e^{-x} x^{a-1}}{\Gamma(a)} \] 142 * 143 * <p>This function has uses in some statistical distributions. 144 * 145 * @param a Argument. 146 * @param x Argument. 147 * @return derivative of \( Q(a,x) \) with respect to x. 148 * @since 1.1 149 */ 150 public static double derivative(double a, 151 double x) { 152 return -BoostGamma.gammaPDerivative(a, x); 153 } 154 } 155 }