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 }