generic_mode.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 150 行
HPP
150 行
// Copyright John Maddock 2008.// Use, modification and distribution are subject to the// Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt// or copy at http://www.boost.org/LICENSE_1_0.txt)#ifndef BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP#include <boost/math/tools/minima.hpp> // function minimization for mode#include <boost/math/policies/error_handling.hpp>#include <boost/math/distributions/fwd.hpp>namespace boost{ namespace math{ namespace detail{template <class Dist>struct pdf_minimizer{ pdf_minimizer(const Dist& d) : dist(d) {} typename Dist::value_type operator()(const typename Dist::value_type& x) { return -pdf(dist, x); }private: Dist dist;};template <class Dist>typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0){ BOOST_MATH_STD_USING typedef typename Dist::value_type value_type; typedef typename Dist::policy_type policy_type; // // Need to begin by bracketing the maxima of the PDF: // value_type maxval; value_type upper_bound = guess; value_type lower_bound; value_type v = pdf(dist, guess); if(v == 0) { // // Oops we don't know how to handle this, or even in which // direction we should move in, treat as an evaluation error: // policies::raise_evaluation_error( function, "Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type()); } do { maxval = v; if(step != 0) upper_bound += step; else upper_bound *= 2; v = pdf(dist, upper_bound); }while(maxval < v); lower_bound = upper_bound; do { maxval = v; if(step != 0) lower_bound -= step; else lower_bound /= 2; v = pdf(dist, lower_bound); }while(maxval < v); boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>(); value_type result = tools::brent_find_minima( pdf_minimizer<Dist>(dist), lower_bound, upper_bound, policies::digits<value_type, policy_type>(), max_iter).first; if(max_iter >= policies::get_max_root_iterations<policy_type>()) { return policies::raise_evaluation_error<value_type>( function, "Unable to locate solution in a reasonable time:" " either there is no answer to the mode of the distribution" " or the answer is infinite. Current best guess is %1%", result, policy_type()); } return result;}//// As above,but confined to the interval [0,1]://template <class Dist>typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function){ BOOST_MATH_STD_USING typedef typename Dist::value_type value_type; typedef typename Dist::policy_type policy_type; // // Need to begin by bracketing the maxima of the PDF: // value_type maxval; value_type upper_bound = guess; value_type lower_bound; value_type v = pdf(dist, guess); do { maxval = v; upper_bound = 1 - (1 - upper_bound) / 2; if(upper_bound == 1) return 1; v = pdf(dist, upper_bound); }while(maxval < v); lower_bound = upper_bound; do { maxval = v; lower_bound /= 2; if(lower_bound < tools::min_value<value_type>()) return 0; v = pdf(dist, lower_bound); }while(maxval < v); boost::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>(); value_type result = tools::brent_find_minima( pdf_minimizer<Dist>(dist), lower_bound, upper_bound, policies::digits<value_type, policy_type>(), max_iter).first; if(max_iter >= policies::get_max_root_iterations<policy_type>()) { return policies::raise_evaluation_error<value_type>( function, "Unable to locate solution in a reasonable time:" " either there is no answer to the mode of the distribution" " or the answer is infinite. Current best guess is %1%", result, policy_type()); } return result;}}}} // namespaces#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?