⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ibeta_data.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
字号:
//  (C) Copyright John Maddock 2006.//  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)#include <boost/math/bindings/rr.hpp>#include <boost/test/included/test_exec_monitor.hpp>#include <boost/math/special_functions/gamma.hpp>#include <boost/math/special_functions/beta.hpp>#include <boost/math/constants/constants.hpp>#include <boost/math/tools/test.hpp>#include <boost/lexical_cast.hpp>#include <fstream>#include <map>#include <boost/math/tools/test_data.hpp>// speed up beta function computation with a 90-decimal digit approximation:#include "ntl_rr_lanczos.hpp" using namespace boost::math::tools;using namespace boost::math;using namespace std;template <class T>struct ibeta_fraction1_t{   typedef std::pair<T, T> result_type;   ibeta_fraction1_t(T a_, T b_, T x_) : a(a_), b(b_), x(x_), k(1) {}   result_type operator()()   {      T aN;      if(k & 1)      {         int m = (k - 1) / 2;         aN = -(a + m) * (a + b + m) * x;         aN /= a + 2*m;         aN /= a + 2*m + 1;      }      else      {         int m = k / 2;         aN = m * (b - m) *x;         aN /= a + 2*m - 1;         aN /= a + 2*m;      }      ++k;      return std::make_pair(aN, T(1));   }private:   T a, b, x;   int k;};//// This function caches previous calls to beta// just so we can speed things up a bit://template <class T>T get_beta(T a, T b){   static std::map<std::pair<T, T>, T> m;   if(a < b)      std::swap(a, b);   std::pair<T, T> p(a, b);   std::map<std::pair<T, T>, T>::const_iterator i = m.find(p);   if(i != m.end())      return i->second;   T r = beta(a, b);   p.first = a;   p.second = b;   m[p] = r;   return r;}//// compute the continued fraction://template <class T>T get_ibeta_fraction1(T a, T b, T x){   ibeta_fraction1_t<T> f(a, b, x);   T fract = boost::math::tools::continued_fraction_a(f, boost::math::policies::digits<T, boost::math::policies::policy<> >());   T denom = (a * (fract + 1));   T num = pow(x, a) * pow(1 - x, b);   if(num == 0)      return 0;   else if(denom == 0)      return -1;   return num / denom;}//// calculate the incomplete beta from the fraction://template <class T>std::pair<T,T> ibeta_fraction1(T a, T b, T x){   T bet = get_beta(a, b);   if(x > ((a+1)/(a+b+2)))   {      T fract = get_ibeta_fraction1(b, a, 1-x);      if(fract/bet > 0.75)      {         fract = get_ibeta_fraction1(a, b, x);         return std::make_pair(fract, bet - fract);      }      return std::make_pair(bet - fract, fract);   }   T fract = get_ibeta_fraction1(a, b, x);   if(fract/bet > 0.75)   {      fract = get_ibeta_fraction1(b, a, 1-x);      return std::make_pair(bet - fract, fract);   }   return std::make_pair(fract, bet - fract);}//// calculate the regularised incomplete beta from the fraction://template <class T>std::pair<T,T> ibeta_fraction1_regular(T a, T b, T x){   T bet = get_beta(a, b);   if(x > ((a+1)/(a+b+2)))   {      T fract = get_ibeta_fraction1(b, a, 1-x);      if(fract == 0)         bet = 1;  // normalise so we don't get 0/0      else if(bet == 0)         return std::make_pair(T(-1), T(-1)); // Yikes!!      if(fract / bet > 0.75)      {         fract = get_ibeta_fraction1(a, b, x);         return std::make_pair(fract / bet, 1 - (fract / bet));      }      return std::make_pair(1 - (fract / bet), fract / bet);   }   T fract = get_ibeta_fraction1(a, b, x);   if(fract / bet > 0.75)   {      fract = get_ibeta_fraction1(b, a, 1-x);      return std::make_pair(1 - (fract / bet), fract / bet);   }   return std::make_pair(fract / bet, 1 - (fract / bet));}//// we absolutely must trunctate the input values to float// precision: we have to be certain that the input values// can be represented exactly in whatever width floating// point type we are testing, otherwise the output will // necessarily be off.//float external_f;float force_truncate(const float* f){   external_f = *f;   return external_f;}float truncate_to_float(boost::math::ntl::RR r){   float f = boost::math::tools::real_cast<float>(r);   return force_truncate(&f);}std::tr1::mt19937 rnd;std::tr1::uniform_real<float> ur_a(1.0F, 5.0F);std::tr1::variate_generator<std::tr1::mt19937, std::tr1::uniform_real<float> > gen(rnd, ur_a);std::tr1::uniform_real<float> ur_a2(0.0F, 100.0F);std::tr1::variate_generator<std::tr1::mt19937, std::tr1::uniform_real<float> > gen2(rnd, ur_a2);struct beta_data_generator{   std::tr1::tuple<boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR> operator()(boost::math::ntl::RR ap, boost::math::ntl::RR bp, boost::math::ntl::RR x_)   {      float a = truncate_to_float(real_cast<float>(gen() * pow(boost::math::ntl::RR(10), ap)));            float b = truncate_to_float(real_cast<float>(gen() * pow(boost::math::ntl::RR(10), bp)));       float x = truncate_to_float(real_cast<float>(x_));      std::cout << a << " " << b << " " << x << std::endl;      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_full = ibeta_fraction1(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_reg = ibeta_fraction1_regular(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      return std::tr1::make_tuple(a, b, x, ib_full.first, ib_full.second, ib_reg.first, ib_reg.second);   }};// medium sized values:struct beta_data_generator_medium{   std::tr1::tuple<boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR> operator()(boost::math::ntl::RR x_)   {      boost::math::ntl::RR a = gen2();            boost::math::ntl::RR b = gen2();       boost::math::ntl::RR x = x_;      a = ConvPrec(a.value(), 22);      b = ConvPrec(b.value(), 22);      x = ConvPrec(x.value(), 22);      std::cout << a << " " << b << " " << x << std::endl;      //boost::math::ntl::RR exp_beta = boost::math::beta(a, b, x);      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_full = ibeta_fraction1(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      /*exp_beta = boost::math::tools::relative_error(ib_full.first, exp_beta);      if(exp_beta > 1e-40)      {         std::cout << exp_beta << std::endl;      }*/      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_reg = ibeta_fraction1_regular(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      return std::tr1::make_tuple(a, b, x, ib_full.first, ib_full.second, ib_reg.first, ib_reg.second);   }};struct beta_data_generator_small{   std::tr1::tuple<boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR> operator()(boost::math::ntl::RR x_)   {      float a = truncate_to_float(gen2()/10);            float b = truncate_to_float(gen2()/10);       float x = truncate_to_float(real_cast<float>(x_));      std::cout << a << " " << b << " " << x << std::endl;      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_full = ibeta_fraction1(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_reg = ibeta_fraction1_regular(boost::math::ntl::RR(a), boost::math::ntl::RR(b), boost::math::ntl::RR(x));      return std::tr1::make_tuple(a, b, x, ib_full.first, ib_full.second, ib_reg.first, ib_reg.second);   }};struct beta_data_generator_int{   std::tr1::tuple<boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR, boost::math::ntl::RR> operator()(boost::math::ntl::RR a, boost::math::ntl::RR b, boost::math::ntl::RR x_)   {      float x = truncate_to_float(real_cast<float>(x_));      std::cout << a << " " << b << " " << x << std::endl;      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_full = ibeta_fraction1(a, b, boost::math::ntl::RR(x));      std::pair<boost::math::ntl::RR, boost::math::ntl::RR> ib_reg = ibeta_fraction1_regular(a, b, boost::math::ntl::RR(x));      return std::tr1::make_tuple(a, b, x, ib_full.first, ib_full.second, ib_reg.first, ib_reg.second);   }};int test_main(int, char* []){   boost::math::ntl::RR::SetPrecision(1000);   boost::math::ntl::RR::SetOutputPrecision(40);   parameter_info<boost::math::ntl::RR> arg1, arg2, arg3, arg4, arg5;   test_data<boost::math::ntl::RR> data;   std::cout << "Welcome.\n"      "This program will generate spot tests for the incomplete beta functions:\n"      "  beta(a, b, x) and ibeta(a, b, x)\n\n"      "This is not an interactive program be prepared for a long wait!!!\n\n";   arg1 = make_periodic_param(boost::math::ntl::RR(-5), boost::math::ntl::RR(6), 11);   arg2 = make_periodic_param(boost::math::ntl::RR(-5), boost::math::ntl::RR(6), 11);   arg3 = make_random_param(boost::math::ntl::RR(0.0001), boost::math::ntl::RR(1), 10);   arg4 = make_random_param(boost::math::ntl::RR(0.0001), boost::math::ntl::RR(1), 100 /*500*/);   arg5 = make_periodic_param(boost::math::ntl::RR(1), boost::math::ntl::RR(41), 10);   arg1.type |= dummy_param;   arg2.type |= dummy_param;   arg3.type |= dummy_param;   arg4.type |= dummy_param;   arg5.type |= dummy_param;   // comment out all but one of the following when running   // or this program will take forever to complete!   //data.insert(beta_data_generator(), arg1, arg2, arg3);   //data.insert(beta_data_generator_medium(), arg4);   //data.insert(beta_data_generator_small(), arg4);   data.insert(beta_data_generator_int(), arg5, arg5, arg3);   test_data<boost::math::ntl::RR>::const_iterator i, j;   i = data.begin();   j = data.end();   while(i != j)   {      boost::math::ntl::RR v1 = beta((*i)[0], (*i)[1], (*i)[2]);      boost::math::ntl::RR v2 = relative_error(v1, (*i)[3]);      std::string s = boost::lexical_cast<std::string>((*i)[3]);      boost::math::ntl::RR v3 = boost::lexical_cast<boost::math::ntl::RR>(s);      boost::math::ntl::RR v4 = relative_error(v3, (*i)[3]);      if(v2 > 1e-40)      {         std::cout << v2 << std::endl;      }      if(v4 > 1e-60)      {         std::cout << v4 << std::endl;      }      ++ i;   }   std::cout << "Enter name of test data file [default=ibeta_data.ipp]";   std::string line;   std::getline(std::cin, line);   boost::algorithm::trim(line);   if(line == "")      line = "ibeta_data.ipp";   std::ofstream ofs(line.c_str());   write_code(ofs, data, "ibeta_data");      return 0;}

⌨️ 快捷键说明

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