001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.numbers.gamma;
018
019/**
020 * <a href="https://mathworld.wolfram.com/IncompleteGammaFunction.html">
021 * Incomplete Gamma functions</a>.
022 *
023 * <p>By definition, the lower and upper incomplete gamma functions satisfy:
024 *
025 * <p>\[ \Gamma(a) = \gamma(a, x) + \Gamma(a, x) \]
026 *
027 * <p>This code has been adapted from the <a href="https://www.boost.org/">Boost</a>
028 * {@code c++} implementation {@code <boost/math/special_functions/gamma.hpp>}.
029 *
030 * @see
031 * <a href="https://www.boost.org/doc/libs/1_77_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html">
032 * Boost C++ Incomplete Gamma functions</a>
033 * @since 1.1
034 */
035public final class IncompleteGamma {
036    /** No instances. */
037    private IncompleteGamma() {}
038
039    /**
040     * <a href="http://mathworld.wolfram.com/IncompleteGammaFunction.html">
041     * Lower incomplete Gamma function</a> \( \gamma(a, x) \).
042     *
043     * <p>\[ \gamma(a,x) = \int_0^x t^{a-1}\,e^{-t}\,dt \]
044     * @since 1.1
045     */
046    public static final class Lower {
047        /** No instances. */
048        private Lower() {}
049
050        /**
051         * Computes the lower incomplete gamma function \( \gamma(a, x) \).
052         *
053         * @param a Argument.
054         * @param x Argument.
055         * @return \( \gamma(a, x) \).
056         * @throws ArithmeticException if the series evaluation fails to converge.
057         */
058        public static double value(double a,
059                                   double x) {
060            return BoostGamma.tgammaLower(a, x);
061        }
062
063        /**
064         * Computes the lower incomplete gamma function \( \gamma(a, x) \).
065         *
066         * @param a Argument.
067         * @param x Argument.
068         * @param epsilon Tolerance in series evaluation.
069         * @param maxIterations Maximum number of iterations in series evaluation.
070         * @return \( \gamma(a, x) \).
071         * @throws ArithmeticException if the series evaluation fails to converge.
072         */
073        public static double value(final double a,
074                                   double x,
075                                   double epsilon,
076                                   int maxIterations) {
077            return BoostGamma.tgammaLower(a, x, new Policy(epsilon, maxIterations));
078        }
079    }
080
081    /**
082     * <a href="http://mathworld.wolfram.com/IncompleteGammaFunction.html">
083     * Upper incomplete Gamma function</a> \( \Gamma(a, x) \).
084     *
085     * <p>\[ \Gamma(a,x) = \int_x^{\infty} t^{a-1}\,e^{-t}\,dt \]
086     * @since 1.1
087     */
088    public static final class Upper {
089        /** No instances. */
090        private Upper() {}
091
092        /**
093         * Computes the upper incomplete gamma function \( \Gamma(a, x) \).
094         *
095         * @param a Argument.
096         * @param x Argument.
097         * @return \( \Gamma(a, x) \).
098         * @throws ArithmeticException if the series evaluation fails to converge.
099         */
100        public static double value(double a,
101                                   double x) {
102            return BoostGamma.tgamma(a, x);
103        }
104
105        /**
106         * Computes the upper incomplete gamma function \( \Gamma(a, x) \).
107         *
108         * @param a Argument.
109         * @param x Argument.
110         * @param epsilon Tolerance in series evaluation.
111         * @param maxIterations Maximum number of iterations in series evaluation.
112         * @return \( \Gamma(a, x) \).
113         * @throws ArithmeticException if the series evaluation fails to converge.
114         */
115        public static double value(double a,
116                                   double x,
117                                   double epsilon,
118                                   int maxIterations) {
119            return BoostGamma.tgamma(a, x, new Policy(epsilon, maxIterations));
120        }
121    }
122}