Boost ã§æ£è¦ä¹±æ°ã®çæ
ã·ãã¥ã¬ã¼ã·ã§ã³å®é¨ãè¡ã£ã¦ããã¨æ£è¦ä¹±æ°ãå¿
è¦ã«ãªããã¨ãããããã¾ãï¼æ£è¦ä¹±æ°ã¯ããªãåºæ¬çãªä¹±æ°ã§ãããããã¾ãã¾ãªã©ã¤ãã©ãªã«å®è£
ããã¦ããã®ã§ããï¼ç§ã¯ Boost ããã使ã£ã¦ããã®ã§ï¼æ£è¦ä¹±æ°ã§ã Boost ã使ç¨ãã¦çºçããã¦ãã¾ãï¼
ããã Boost ã®å®è£
ã¯æè»æ§ãæ±ãéãããã¾ã使ããããã失ã£ã¦ãã¾ã£ã¦ããããã«æãã¾ãï¼åã«æ£è¦ä¹±æ°ãçºçãããã人ã«ã¨ã£ã¦ã¯ï¼ï¼ã¨ããã®ãï¼Boost ã§æ£è¦ä¹±æ°ãçºçãããããã«ã¯ã¾ãä¸æ§åå¸ãçºçãããã¨ã³ã¸ã³ãé¸ã³ï¼ãããé©åã«ã³ã³ã¹ãã©ã¯ãããå¿
è¦ãããã¾ãï¼ã¨ã³ã¸ã³ã«ãã£ã¦ã¯ãã³ãã¬ã¼ãåãããã³ã³ã¹ãã©ã¯ã¿ããã¤ããï¼ã¨ã³ã¸ã³ãé©åã«åæåããããã«ã¯ã³ã³ã¹ãã©ã¯ã¿ã«æ¸¡ã種(seed)ã®åãæ£ç¢ºã«ä¸è´ãããå¿
è¦ãããã¾ãï¼ããããªããã°ãã³ãã¬ã¼ãåãããã³ã³ã¹ãã©ã¯ã¿ãå¼ã°ãã¦ãã¾ãã¾ãï¼ï¼ãã®å¾ normal_distribution 㨠variable_generator ãæ§ç¯ããã¨ããæé ãè¸ã¿ï¼ããããæ£è¦ä¹±æ°ãå¾ããã¨ãã§ããã®ã§ãï¼
ãã®ãããªéª¨ãæããä½æ¥ãï¼ç°¡åãªã©ããã¼ã¯ã©ã¹ãä½ãã°æ¥½ã«ãªãã¾ãï¼ä»¥ä¸ã«ãã®ã½ã¼ã¹ã³ã¼ãã示ãã¾ãï¼
gauss_rand.hpp
#ifndef GAUSS_RAND_HPP_20081010 #define GAUSS_RAND_HPP_20081010 #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif #include <boost/random.hpp> namespace math { template <class RealType = double, class Engine = boost::mt19937> class gauss_rand { private: template <class T> struct seed_traits { typedef typename T::result_type seed_type; }; template <class RT, int w, unsigned int p, unsigned int q> struct seed_traits<boost::random::lagged_fibonacci_01<RT, w, p, q> > { typedef boost::uint32_t seed_type; }; public: typedef boost::variate_generator<Engine, boost::normal_distribution<RealType> > generator_type; typedef typename generator_type::engine_value_type engine_value_type; typedef typename generator_type::engine_type engine_type; typedef typename generator_type::distribution_type distribution_type; typedef typename generator_type::result_type result_type; typedef typename seed_traits<Engine>::seed_type seed_type; explicit gauss_rand(seed_type seed, const result_type& mean = result_type(0), const result_type& sigma = result_type(1)) : generator_(Engine(seed), boost::normal_distribution<RealType>(mean, sigma)) {} void seed(seed_type value) { generator_.engine().seed(value); } result_type mean() const { return generator_.distribution().mean(); } result_type sigma() const { return generator_.distribution().sigma(); } result_type operator()() { return generator_(); } engine_value_type& engine() { return generator_.engine(); } const engine_value_type& engine() const { return generator_.engine(); } distribution_type& distribution() { return generator_.distribution(); } const distribution_type& distribution() const { return generator_.distribution(); } generator_type& generator() { return generator_; } const generator_type& generator() const { return generator_; } private: boost::variate_generator<Engine, boost::normal_distribution<RealType> > generator_; }; template <class RealType> class gauss_rand<RealType, boost::ecuyer1988> { public: typedef boost::variate_generator<boost::ecuyer1988, boost::normal_distribution<RealType> > generator_type; typedef typename generator_type::engine_value_type engine_value_type; typedef typename generator_type::engine_type engine_type; typedef typename generator_type::distribution_type distribution_type; typedef typename generator_type::result_type result_type; typedef boost::ecuyer1988::result_type seed_type; explicit gauss_rand(seed_type seed1, seed_type seed2, const result_type& mean = result_type(0), const result_type& sigma = result_type(1)) : generator_(boost::ecuyer1988(seed1, seed2), boost::normal_distribution<RealType>(mean, sigma)) {} void seed(seed_type value1, seed_type value2) { generator_.engine().seed(value1, value2); } result_type mean() const { return generator_.distribution().mean(); } result_type sigma() const { return generator_.distribution().sigma(); } result_type operator()() { return generator_(); } engine_value_type& engine() { return generator_.engine(); } const engine_value_type& engine() const { return generator_.engine(); } distribution_type& distribution() { return generator_.distribution(); } const distribution_type& distribution() const { return generator_.distribution(); } generator_type& generator() { return generator_; } const generator_type& generator() const { return generator_; } private: boost::variate_generator<boost::ecuyer1988, boost::normal_distribution<RealType> > generator_; }; } #endif
gauss_rand.hpp ã«æ£è¦ä¹±æ°ãè¨ç®ãããã¡ã³ã¯ã¿ gauss_rand ãå®è£
ãã¾ããï¼gauss_rand.hpp ã include ããã ã㧠gauss_rand ã使ç¨å¯è½ã«ãªãã¾ãï¼
gauss_rand ã®ç¬¬ä¸ãã³ãã¬ã¼ãå¼æ°ã« float ã double ã渡ããã¨ã«ããæ»ãå¤ã®åãï¼ç¬¬äºãã³ãã¬ã¼ãå¼æ°ã« minstd_rand ã mt19937 ã渡ããã¨ã«ããä¸æ§åå¸ã®ã¨ã³ã¸ã³ãæå®ãããã¨ãåºæ¥ã¾ãï¼Boost ã® normal_distribution ã§ã¯ããã§æå®ããä¸æ§åå¸ãç¨ãã¦ボックス=ミューラー法(Box-Muller transform)ã«ããæ£è¦ä¹±æ°ãè¨ç®ãããã¨ã«ãªãã¾ãï¼
以ä¸ã®ãã¹ãã³ã¼ã㧠gauss_rand ã®åä½ã確èªã§ãã¾ãï¼
test.cpp
#include "gauss_rand.hpp" #include <iostream> int main() { // æãåç´ãªä½¿ãæ¹ // 種=0x5eed, å¹³å=0, æ¨æºåå·®=10 ã®æ£è¦ä¹±æ° // ï¼æ»ãå¤ã¯ double, ä¸æ§ä¹±æ°ã¯ mt19937 ã使ããã¾ãï¼ { math::gauss_rand<> grand(0x5eed, 0, 10); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=5, æ¨æºåå·®=7 ã®æ£è¦ä¹±æ° // æ»ãå¤=float // ï¼ä¸æ§ä¹±æ°ã¯ mt19937 ã使ããã¾ãï¼ { math::gauss_rand<float> grand(0x5eed, 5, 7); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=10, æ¨æºåå·®=20 ã®æ£è¦ä¹±æ° // æ»ãå¤=double // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« ministd ãç¨ãã { math::gauss_rand<double, boost::minstd_rand> grand(0x5eed, 10, 20); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=1, æ¨æºåå·®=2 ã®æ£è¦ä¹±æ° // æ»ãå¤=long double // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« rand48 ãç¨ãã { math::gauss_rand<long double, boost::rand48> grand(0x5eed, 1, 2); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種1=0x5eed1, 種2=0x5eed2, å¹³å=11, æ¨æºåå·®=0 ã®æ£è¦ä¹±æ° // æ»ãå¤=double // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« ecuyer1988 ãç¨ãã { math::gauss_rand<double, boost::ecuyer1988> grand(0x5eed1, 0x5eed2, 11, 0); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=100, æ¨æºåå·®=5 ã®æ£è¦ä¹±æ° // æ»ãå¤=float // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« kreutzer1986 ãç¨ãã { math::gauss_rand<float, boost::kreutzer1986> grand(0x5eed, 100, 5); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=5, æ¨æºåå·®=100 ã®æ£è¦ä¹±æ° // æ»ãå¤=float // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« hellekalek1995 ãç¨ãã { math::gauss_rand<float, boost::hellekalek1995> grand(0x5eed, 5, 100); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=10, æ¨æºåå·®=12 ã®æ£è¦ä¹±æ° // æ»ãå¤=float // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« mt19937 ãç¨ãã { math::gauss_rand<float, boost::mt19937> grand(0x5eed, 10, 12); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } // 種=0x5eed, å¹³å=10, æ¨æºåå·®=5 ã®æ£è¦ä¹±æ° // æ»ãå¤=double // æ£è¦ä¹±æ°ã®çºçã¢ã«ã´ãªãºã ã§ç¨ããä¸æ§ä¹±æ°ã®çæã« lagged_fibonacci19937 ãç¨ãã { math::gauss_rand<double, boost::lagged_fibonacci19937> grand(0x5eed, 10, 5); for (int i = 0; i < 100; ++i) { std::cout << grand() << std::endl; } } return 0; }
ã§ã®ã³ã³ãã¤ã«ã確èªãã¦ãã¾ãï¼
å®è¡ãã¦ã¿ãã¨ï¼æ£è¦ä¹±æ°ãæ±ãããã¦ãããã¨ãåããã¾ãï¼
gauss_rand.hpp ã¯ããããダウンロードã§ãã¾ãï¼
次å㯠OpenCV ã®ç»ç´ ã¢ã¯ã»ã¹ã«ã¤ãã¦ç´¹ä»ãããã¨æãã¾ãï¼
ããã§ã¯ï¼