non_central_t.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,068 行 · 第 1/3 页

HPP
1,068
字号
               ++count;               if(count > max_iter)               {                  return policies::raise_evaluation_error(                     "pdf(non_central_t_distribution<%1%>, %1%)",                      "Series did not converge, closest value was %1%", sum, pol);               }            }            for(int i = k + 1; ; ++i)            {               poisf *= d2 / (i + 0.5f);               xtermf *= (x * (n / 2 + i)) / (i);               T term = poisf * xtermf;               sum += term;               if((fabs(term/sum) < errtol) || (term == 0))                  break;               ++count;               if(count > max_iter)               {                  return policies::raise_evaluation_error(                     "pdf(non_central_t_distribution<%1%>, %1%)",                      "Series did not converge, closest value was %1%", sum, pol);               }            }            return sum;         }         template <class T, class Policy>         T non_central_t_pdf(T n, T delta, T t, const Policy& pol)         {            BOOST_MATH_STD_USING            //            // For t < 0 we have to use the reflection formula:            //            if(t < 0)            {               t = -t;               delta = -delta;            }            if(t == 0)            {               //               // Handle this as a special case, using the formula               // from Weisstein, Eric W.                // "Noncentral Student's t-Distribution."                // From MathWorld--A Wolfram Web Resource.                // http://mathworld.wolfram.com/NoncentralStudentst-Distribution.html                //                // The formula is simplified thanks to the relation               // 1F1(a,b,0) = 1.               //               return tgamma_delta_ratio(n / 2 + 0.5f, T(0.5f))                  * sqrt(n / constants::pi<T>())                   * exp(-delta * delta / 2) / 2;            }            //            // x and y are the corresponding random            // variables for the noncentral beta distribution,            // with y = 1 - x:            //            T x = t * t / (n + t * t);            T y = n / (n + t * t);            T a = 0.5f;            T b = n / 2;            T d2 = delta * delta;            //            // Calculate pdf:            //            T dt = n * t / (n * n + 2 * n * t * t + t * t * t * t);            T result = non_central_beta_pdf(a, b, d2, x, y, pol);            T tol = tools::epsilon<T>() * result * 500;            result = non_central_t2_pdf(n, delta, x, y, pol, result);            if(result <= tol)               result = 0;            result *= dt;            return result;         }         template <class T, class Policy>         T mean(T v, T delta, const Policy& pol)         {            BOOST_MATH_STD_USING            return delta * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, T(0.5f), pol);         }         template <class T, class Policy>         T variance(T v, T delta, const Policy& pol)         {            T result = ((delta * delta + 1) * v) / (v - 2);            T m = mean(v, delta, pol);            result -= m * m;            return result;         }         template <class T, class Policy>         T skewness(T v, T delta, const Policy& pol)         {            BOOST_MATH_STD_USING            T mean = boost::math::detail::mean(v, delta, pol);            T l2 = delta * delta;            T var = ((l2 + 1) * v) / (v - 2) - mean * mean;            T result = -2 * var;            result += v * (l2 + 2 * v - 3) / ((v - 3) * (v - 2));            result *= mean;            result /= pow(var, T(1.5f));            return result;         }         template <class T, class Policy>         T kurtosis_excess(T v, T delta, const Policy& pol)         {            BOOST_MATH_STD_USING            T mean = boost::math::detail::mean(v, delta, pol);            T l2 = delta * delta;            T var = ((l2 + 1) * v) / (v - 2) - mean * mean;            T result = -3 * var;            result += v * (l2 * (v + 1) + 3 * (3 * v - 5)) / ((v - 3) * (v - 2));            result *= -mean * mean;            result += v * v * (l2 * l2 + 6 * l2 + 3) / ((v - 4) * (v - 2));            result /= var * var;            return result;         }#if 0         //          // This code is disabled, since there can be multiple answers to the         // question, and it's not clear how to find the "right" one.         //         template <class RealType, class Policy>         struct t_degrees_of_freedom_finder         {            t_degrees_of_freedom_finder(               RealType delta_, RealType x_, RealType p_, bool c)               : delta(delta_), x(x_), p(p_), comp(c) {}            RealType operator()(const RealType& v)            {               non_central_t_distribution<RealType, Policy> d(v, delta);               return comp ?                  p - cdf(complement(d, x))                  : cdf(d, x) - p;            }         private:            RealType delta;            RealType x;            RealType p;            bool comp;         };         template <class RealType, class Policy>         inline RealType find_t_degrees_of_freedom(            RealType delta, RealType x, RealType p, RealType q, const Policy& pol)         {            const char* function = "non_central_t<%1%>::find_degrees_of_freedom";            if((p == 0) || (q == 0))            {               //               // Can't a thing if one of p and q is zero:               //               return policies::raise_evaluation_error<RealType>(function,                   "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%",                   RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());            }            t_degrees_of_freedom_finder<RealType, Policy> f(delta, x, p < q ? p : q, p < q ? false : true);            tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());            boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();            //            // Pick an initial guess:            //            RealType guess = 200;            std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(               f, guess, RealType(2), false, tol, max_iter, pol);            RealType result = ir.first + (ir.second - ir.first) / 2;            if(max_iter >= policies::get_max_root_iterations<Policy>())            {               policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"                  " or there is no answer to problem.  Current best guess is %1%", result, Policy());            }            return result;         }         template <class RealType, class Policy>         struct t_non_centrality_finder         {            t_non_centrality_finder(               RealType v_, RealType x_, RealType p_, bool c)               : v(v_), x(x_), p(p_), comp(c) {}            RealType operator()(const RealType& delta)            {               non_central_t_distribution<RealType, Policy> d(v, delta);               return comp ?                  p - cdf(complement(d, x))                  : cdf(d, x) - p;            }         private:            RealType v;            RealType x;            RealType p;            bool comp;         };         template <class RealType, class Policy>         inline RealType find_t_non_centrality(            RealType v, RealType x, RealType p, RealType q, const Policy& pol)         {            const char* function = "non_central_t<%1%>::find_t_non_centrality";            if((p == 0) || (q == 0))            {               //               // Can't do a thing if one of p and q is zero:               //               return policies::raise_evaluation_error<RealType>(function,                   "Can't find non centrality parameter when the probability is 0 or 1, only possible answer is %1%",                   RealType(std::numeric_limits<RealType>::quiet_NaN()), Policy());            }            t_non_centrality_finder<RealType, Policy> f(v, x, p < q ? p : q, p < q ? false : true);            tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());            boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();            //            // Pick an initial guess that we know is the right side of            // zero:            //            RealType guess;            if(f(0) < 0)               guess = 1;            else               guess = -1;            std::pair<RealType, RealType> ir = tools::bracket_and_solve_root(               f, guess, RealType(2), false, tol, max_iter, pol);            RealType result = ir.first + (ir.second - ir.first) / 2;            if(max_iter >= policies::get_max_root_iterations<Policy>())            {               policies::raise_evaluation_error<RealType>(function, "Unable to locate solution in a reasonable time:"                  " or there is no answer to problem.  Current best guess is %1%", result, Policy());            }            return result;         }#endif      } // namespace detail      template <class RealType = double, class Policy = policies::policy<> >      class non_central_t_distribution      {      public:         typedef RealType value_type;         typedef Policy policy_type;         non_central_t_distribution(RealType v_, RealType lambda) : v(v_), ncp(lambda)         {             const char* function = "boost::math::non_central_t_distribution<%1%>::non_central_t_distribution(%1%,%1%)";            RealType r;            detail::check_df(               function,               v, &r, Policy());            detail::check_finite(               function,               lambda,               &r,               Policy());         } // non_central_t_distribution constructor.         RealType degrees_of_freedom() const         { // Private data getter function.            return v;         }         RealType non_centrality() const         { // Private data getter function.            return ncp;         }#if 0         //          // This code is disabled, since there can be multiple answers to the         // question, and it's not clear how to find the "right" one.         //         static RealType find_degrees_of_freedom(RealType delta, RealType x, RealType p)         {            const char* function = "non_central_t<%1%>::find_degrees_of_freedom";            typedef typename policies::evaluation<RealType, Policy>::type value_type;            typedef typename policies::normalise<               Policy,                policies::promote_float<false>,                policies::promote_double<false>,                policies::discrete_quantile<>,               policies::assert_undefined<> >::type forwarding_policy;            value_type result = detail::find_t_degrees_of_freedom(               static_cast<value_type>(delta),                static_cast<value_type>(x),                static_cast<value_type>(p),                static_cast<value_type>(1-p),                forwarding_policy());            return policies::checked_narrowing_cast<RealType, forwarding_policy>(               result,                function);         }         template <class A, class B, class C>         static RealType find_degrees_of_freedom(const complemented3_type<A,B,C>& c)         {            const char* function = "non_central_t<%1%>::find_degrees_of_freedom";            typedef typename policies::evaluation<RealType, Policy>::type value_type;            typedef typename policies::normalise<               Policy,                policies::promote_float<false>,                policies::promote_double<false>,                policies::discrete_quantile<>,               policies::assert_undefined<> >::type forwarding_policy;            value_type result = detail::find_t_degrees_of_freedom(               static_cast<value_type>(c.dist),                static_cast<value_type>(c.param1),                static_cast<value_type>(1-c.param2),                static_cast<value_type>(c.param2),                forwarding_policy());            return policies::checked_narrowing_cast<RealType, forwarding_policy>(               result,                function);         }         static RealType find_non_centrality(RealType v, RealType x, RealType p)         {            const char* function = "non_central_t<%1%>::find_t_non_centrality";            typedef typename policies::evaluation<RealType, Policy>::type value_type;            typedef typename policies::normalise<               Policy,                policies::promote_float<false>,                policies::promote_double<false>,                policies::discrete_quantile<>,               policies::assert_undefined<> >::type forwarding_policy;            value_type result = detail::find_t_non_centrality(               static_cast<value_type>(v),                static_cast<value_type>(x),                static_cast<value_type>(p),                static_cast<value_type>(1-p),                forwarding_policy());            return policies::checked_narrowing_cast<RealType, forwarding_policy>(               result,                function);         }         template <class A, class B, class C>         static RealType find_non_centrality(const complemented3_type<A,B,C>& c)         {            const char* function = "non_central_t<%1%>::find_t_non_centrality";            typedef typename policies::evaluation<RealType, Policy>::type value_type;            typedef typename policies::normalise<               Policy,                policies::promote_float<false>,                policies::promote_double<false>,                policies::discrete_quantile<>,               policies::assert_undefined<> >::type forwarding_policy;            value_type result = detail::find_t_non_centrality(               static_cast<value_type>(c.dist),                static_cast<value_type>(c.param1),                static_cast<value_type>(1-c.param2),                static_cast<value_type>(c.param2),                forwarding_policy());            return policies::checked_narrowing_cast<RealType, forwarding_policy>(               result,                function);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?