last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 2007 00003 * Pablo Alvarado 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 /** 00042 * \file cvrRandomDistribution.h 00043 * Contains the class cvr::randomDistribution, which is the parent 00044 * class of all random distributions in the library. 00045 * 00046 * \author Pablo Alvarado 00047 * \date 21.09.2007 00048 * 00049 * revisions ..: $Id: cvrRandomDistribution.h,v 1.3 2007/10/22 00:46:23 alvarado Exp $ 00050 */ 00051 00052 #ifndef _CVR_RANDOM_DISTRIBUTION_H_ 00053 #define _CVR_RANDOM_DISTRIBUTION_H_ 00054 00055 #include "cvrFunctor.h" 00056 #include <cstdio> 00057 00058 namespace cvr { 00059 00060 /** 00061 * Class randomDistribution 00062 * 00063 * The class cvr::randomDistribution is the parent class of all random number 00064 * generators in the CVR-Lib . 00065 * 00066 * The concept followed in this library is complementary to the standard 00067 * concept found in the STL <random> classes, which are employed within the 00068 * classes of the present hierarchy. Since the std::tr1 classes are not 00069 * implemented by all STL implementations, the CVR-Lib provides the required 00070 * partial implementations for internal use only. 00071 * 00072 * Note that the standard random number generators and distributions are 00073 * highly template based, what makes them very efficient for execution time, 00074 * but relatively hard to be dinamically configured. The present hierarchy 00075 * is not intended as replacement of the standard concepts. It simply is a 00076 * wrapper concept that allows the number generators to be configured 00077 * dinamically, through the accustomed parameter objects, at the cost of 00078 * reduced speed. In case you need the ultimative speed, then use the 00079 * standard concept instead, or the original Boost Random Number Library 00080 * (http://www.boost.org/libs/random/index.html), on which the standard 00081 * relies. If you need runtime configuration capabilities, then the CVR-Lib 00082 * concept is for you. 00083 * 00084 * For image applications 32 bit precision is still sufficient. Hence, that 00085 * is the precision you will get by the number generation of these 00086 * distributions. This means that internally, the uniformly distributed 00087 * number generator will produce numbers of type cvr::uint32. 00088 * 00089 * @see randomDistribution::parameters. 00090 * 00091 * @ingroup gRandom 00092 */ 00093 class randomDistribution : public functor { 00094 public: 00095 /** 00096 * Enumerator with the possible underlying uniformly distributed number 00097 * generators. 00098 */ 00099 enum eNumberGenerator { 00100 SystemWide, /**< The system-wide random generator makes use of the old 00101 * C-style rand() function, which is shared among all 00102 * instances of classes derived from randomDistribution. 00103 */ 00104 Stochastic, /**< The stochastic method makes use of the device random 00105 * generator, which is usually in "/dev/urandom". It is a 00106 * non-deterministic random number generator, usually 00107 * implemented in the operating system, using highly 00108 * entropic processes. 00109 * Since it uses file I/O it is realtively slow. 00110 */ 00111 MinStd, /**< Linear congruential generator which uses \f$x_{n+1} = ( 00112 * a x_{n} ) \mod m \f$ con \f$ a=16807 \f$ y \f$ m = 00113 * 2147483647 \f$. Therefore, the generated numbers are 00114 * unsigned of 31 bit precision, and since \a m and \a c 00115 * are relative primes, the repetition period equals \a m. 00116 */ 00117 00118 MinStd0, /**< Linear congruential generator which uses \f$x_{n+1} = ( 00119 * a x_{n} ) \mod m \f$ con \f$ a=48271 \f$ y \f$ m = 00120 * 2147483647 \f$. Therefore, the generated numbers are 00121 * unsigned of 31 bit precision, and since \a m and \a c 00122 * are relative primes, the repetition period equals \a m. 00123 */ 00124 MT /**< Mersenne Twister random number generator. The code for 00125 * this generator is based on 00126 * M. Matsumoto and T. Nishimura, "Mersenne Twister: 00127 * A 623-Dimensionally Equidistributed Uniform 00128 * Pseudo-Random Number Generator", ACM Transactions on 00129 * Modeling and Computer Simulation, Vol. 8, No. 1, 00130 * January 1998, pp 3-30. 00131 * 00132 * Check also the page 00133 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 00134 */ 00135 }; 00136 00137 /** 00138 * The parameters for the class randomDistribution 00139 */ 00140 class parameters : public functor::parameters { 00141 public: 00142 /** 00143 * Default constructor 00144 */ 00145 parameters(); 00146 00147 /** 00148 * Copy constructor 00149 * @param other the parameters object to be copied 00150 */ 00151 parameters(const parameters& other); 00152 00153 /** 00154 * Destructor 00155 */ 00156 ~parameters(); 00157 00158 /** 00159 * Copy the contents of a parameters object 00160 * @param other the parameters object to be copied 00161 * @return a reference to this parameters object 00162 */ 00163 parameters& copy(const parameters& other); 00164 00165 /** 00166 * Copy the contents of a parameters object 00167 * @param other the parameters object to be copied 00168 * @return a reference to this parameters object 00169 */ 00170 parameters& operator=(const parameters& other); 00171 00172 /** 00173 * Returns the complete name of the parameters class. 00174 */ 00175 virtual const std::string& name() const; 00176 00177 /** 00178 * Returns a pointer to a clone of the parameters. 00179 */ 00180 virtual parameters* clone() const; 00181 00182 /** 00183 * Returns a pointer to a new instance of the parameters. 00184 */ 00185 virtual parameters* newInstance() const; 00186 00187 /** 00188 * Write the parameters in the given ioHandler 00189 * @param handler the ioHandler to be used 00190 * @param complete if true (the default) the enclosing begin/end will 00191 * be also written, otherwise only the data block will be written. 00192 * @return true if write was successful 00193 */ 00194 virtual bool write(ioHandler& handler,const bool complete=true) const; 00195 00196 /** 00197 * Read the parameters from the given ioHandler 00198 * @param handler the ioHandler to be used 00199 * @param complete if true (the default) the enclosing begin/end will 00200 * be also written, otherwise only the data block will be written. 00201 * @return true if write was successful 00202 */ 00203 virtual bool read(ioHandler& handler,const bool complete=true); 00204 00205 // ------------------------------------------------ 00206 // the parameters 00207 // ------------------------------------------------ 00208 00209 /** 00210 * Type of number generator to be used. 00211 * 00212 * Default value: MT 00213 */ 00214 eNumberGenerator generator; 00215 00216 /** 00217 * Seed for the number generator. 00218 * 00219 * The seed is not allowed to be 0. In that case, no seed setting 00220 * will be done. 00221 * 00222 * Default value: 15485863 (the 1 millionth prime number) 00223 */ 00224 uint32 seed; 00225 00226 /** 00227 * Name of the device for the stochastic number generator. 00228 * 00229 * This is used only if generator=Stochastic. In case the 00230 * given device does not exist, setting the parameters will fail, and 00231 * the corresponding status string will be set accordingly. 00232 * 00233 * Default value: "/dev/urandom" 00234 */ 00235 std::string device; 00236 00237 }; 00238 00239 /** 00240 * Default constructor 00241 */ 00242 randomDistribution(); 00243 00244 /** 00245 * Construct a functor using the given parameters 00246 */ 00247 randomDistribution(const parameters& par); 00248 00249 /** 00250 * Copy constructor 00251 * @param other the object to be copied 00252 */ 00253 randomDistribution(const randomDistribution& other); 00254 00255 /** 00256 * Destructor 00257 */ 00258 virtual ~randomDistribution(); 00259 00260 /** 00261 * Copy data of "other" functor. 00262 * @param other the functor to be copied 00263 * @return a reference to this functor object 00264 */ 00265 randomDistribution& copy(const randomDistribution& other); 00266 00267 /** 00268 * Alias for copy member 00269 * @param other the functor to be copied 00270 * @return a reference to this functor object 00271 */ 00272 randomDistribution& operator=(const randomDistribution& other); 00273 00274 /** 00275 * Returns the complete name of the functor class 00276 */ 00277 virtual const std::string& name() const; 00278 00279 /** 00280 * Returns a pointer to a clone of this functor. 00281 */ 00282 virtual randomDistribution* clone() const; 00283 00284 /** 00285 * Returns a pointer to a new instance of this functor. 00286 */ 00287 virtual randomDistribution* newInstance() const; 00288 00289 /** 00290 * Returns used parameters 00291 */ 00292 const parameters& getParameters() const; 00293 00294 /** 00295 * Update the parameters 00296 */ 00297 bool updateParameters(); 00298 00299 /** 00300 * Shortcut for changing the seed of the number generator 00301 * 00302 * @param newSeed new seed for the number generator. 00303 */ 00304 void setSeed(const uint32 newSeed); 00305 00306 /** 00307 * Write the parameters in the given ioHandler 00308 * @param handler the ioHandler to be used 00309 * @param complete if true (the default) the enclosing begin/end will 00310 * be also written, otherwise only the data block will be written. 00311 * @return true if write was successful 00312 */ 00313 virtual bool write(ioHandler& handler,const bool complete=true) const; 00314 00315 /** 00316 * Read the parameters from the given ioHandler 00317 * @param handler the ioHandler to be used 00318 * @param complete if true (the default) the enclosing begin/end will 00319 * be also written, otherwise only the data block will be written. 00320 * @return true if write was successful 00321 */ 00322 virtual bool read(ioHandler& handler,const bool complete=true); 00323 00324 protected: 00325 00326 /** 00327 * Returns read-writable reference to the internal parameters 00328 */ 00329 parameters& getRWParameters(); 00330 00331 00332 /** 00333 * Pure virtual nested class base of all random number generators. 00334 * 00335 * It does not need copy constructors, since the updateParameters of each 00336 * new functor will create a new instance of the correct rndBase class. 00337 */ 00338 class rndBase { 00339 public: 00340 /** 00341 * Destructor 00342 */ 00343 virtual ~rndBase(); 00344 00345 /** 00346 * Get a single number 00347 */ 00348 virtual uint32 draw() = 0; 00349 00350 /** 00351 * Set the seed for the generator 00352 */ 00353 virtual void setSeed(const uint32 seed) = 0; 00354 00355 /** 00356 * Return the maximal obtainable number (inclusive) 00357 */ 00358 virtual uint32 max() const = 0; 00359 00360 /** 00361 * Write the parameters in the given ioHandler 00362 * @param handler the ioHandler to be used 00363 * @param complete if true (the default) the enclosing begin/end will 00364 * be also written, otherwise only the data block will be written. 00365 * @return true if write was successful 00366 */ 00367 virtual bool write(ioHandler& handler,const bool complete=true) const=0; 00368 00369 /** 00370 * Read the parameters from the given ioHandler 00371 * @param handler the ioHandler to be used 00372 * @param complete if true (the default) the enclosing begin/end will 00373 * be also written, otherwise only the data block will be written. 00374 * @return true if write was successful 00375 */ 00376 virtual bool read(ioHandler& handler,const bool complete=true)=0; 00377 }; 00378 00379 /** 00380 * Wrapper for the <cstdlib> rand() function. Note that this class will 00381 * interfere with other instances when the seed is set. 00382 */ 00383 class rndSystem : public rndBase { 00384 public: 00385 /** 00386 * Constructor 00387 */ 00388 rndSystem(); 00389 00390 /** 00391 * Destructor 00392 */ 00393 virtual ~rndSystem(); 00394 00395 /** 00396 * Get a single number 00397 */ 00398 virtual uint32 draw(); 00399 00400 /** 00401 * Set the seed for the generator 00402 */ 00403 virtual void setSeed(const uint32 seed); 00404 00405 /** 00406 * Return the maximal obtainable number (inclusive) 00407 */ 00408 uint32 max() const; 00409 00410 /** 00411 * Write the parameters in the given ioHandler 00412 * @param handler the ioHandler to be used 00413 * @param complete if true (the default) the enclosing begin/end will 00414 * be also written, otherwise only the data block will be written. 00415 * @return true if write was successful 00416 */ 00417 virtual bool write(ioHandler& handler,const bool complete=true) const; 00418 00419 /** 00420 * Read the parameters from the given ioHandler 00421 * @param handler the ioHandler to be used 00422 * @param complete if true (the default) the enclosing begin/end will 00423 * be also written, otherwise only the data block will be written. 00424 * @return true if write was successful 00425 */ 00426 virtual bool read(ioHandler& handler,const bool complete=true); 00427 }; 00428 00429 /** 00430 * Wrapper for <random> std::tr1::random_device, which is a hardware based 00431 * true, unpredictable, random number generator. 00432 */ 00433 class rndStochastic : public rndBase { 00434 public: 00435 /** 00436 * Constructor 00437 */ 00438 rndStochastic(); 00439 00440 /** 00441 * Destructor 00442 */ 00443 virtual ~rndStochastic(); 00444 00445 /** 00446 * Get a single number 00447 */ 00448 virtual uint32 draw(); 00449 00450 /** 00451 * Set the seed for the generator 00452 */ 00453 virtual void setSeed(const uint32 seed); 00454 00455 /** 00456 * Return the maximal obtainable number (inclusive) 00457 */ 00458 uint32 max() const; 00459 00460 /** 00461 * Set the file device to be used 00462 */ 00463 bool setDevice(const std::string& device); 00464 00465 /** 00466 * Write the parameters in the given ioHandler 00467 * @param handler the ioHandler to be used 00468 * @param complete if true (the default) the enclosing begin/end will 00469 * be also written, otherwise only the data block will be written. 00470 * @return true if write was successful 00471 */ 00472 virtual bool write(ioHandler& handler,const bool complete=true) const; 00473 00474 /** 00475 * Read the parameters from the given ioHandler 00476 * @param handler the ioHandler to be used 00477 * @param complete if true (the default) the enclosing begin/end will 00478 * be also written, otherwise only the data block will be written. 00479 * @return true if write was successful 00480 */ 00481 virtual bool read(ioHandler& handler,const bool complete=true); 00482 00483 protected: 00484 /** 00485 * File handler to the device used to generate random numbers 00486 */ 00487 FILE* handler_; 00488 }; 00489 00490 /** 00491 * Linear Congruency Random Number Generator 00492 */ 00493 class rndMinStd : public rndBase { 00494 public: 00495 /** 00496 * Constructor 00497 */ 00498 rndMinStd(); 00499 00500 /** 00501 * Destructor 00502 */ 00503 virtual ~rndMinStd(); 00504 00505 /** 00506 * Get a single number 00507 */ 00508 virtual uint32 draw(); 00509 00510 /** 00511 * Set the seed for the generator 00512 */ 00513 virtual void setSeed(const uint32 seed); 00514 00515 /** 00516 * Return the maximal obtainable number (inclusive) 00517 */ 00518 uint32 max() const; 00519 00520 /** 00521 * Write the parameters in the given ioHandler 00522 * @param handler the ioHandler to be used 00523 * @param complete if true (the default) the enclosing begin/end will 00524 * be also written, otherwise only the data block will be written. 00525 * @return true if write was successful 00526 */ 00527 virtual bool write(ioHandler& handler,const bool complete=true) const; 00528 00529 /** 00530 * Read the parameters from the given ioHandler 00531 * @param handler the ioHandler to be used 00532 * @param complete if true (the default) the enclosing begin/end will 00533 * be also written, otherwise only the data block will be written. 00534 * @return true if write was successful 00535 */ 00536 virtual bool read(ioHandler& handler,const bool complete=true); 00537 00538 protected: 00539 /** 00540 * Current state 00541 */ 00542 uint32 state_; 00543 00544 /** 00545 * Constant a 00546 */ 00547 static const uint32 a_ = 16807; 00548 00549 /** 00550 * Constant m 00551 */ 00552 static const uint32 m_ = 2147483647; 00553 00554 }; 00555 00556 /** 00557 * Linear Congruency Random Number Generator 00558 */ 00559 class rndMinStd0 : public rndBase { 00560 public: 00561 /** 00562 * Constructor 00563 */ 00564 rndMinStd0(); 00565 00566 /** 00567 * Destructor 00568 */ 00569 virtual ~rndMinStd0(); 00570 00571 /** 00572 * Get a single number 00573 */ 00574 virtual uint32 draw(); 00575 00576 /** 00577 * Set the seed for the generator 00578 */ 00579 virtual void setSeed(const uint32 seed); 00580 00581 /** 00582 * Return the maximal obtainable number (inclusive) 00583 */ 00584 uint32 max() const; 00585 00586 /** 00587 * Write the parameters in the given ioHandler 00588 * @param handler the ioHandler to be used 00589 * @param complete if true (the default) the enclosing begin/end will 00590 * be also written, otherwise only the data block will be written. 00591 * @return true if write was successful 00592 */ 00593 virtual bool write(ioHandler& handler,const bool complete=true) const; 00594 00595 /** 00596 * Read the parameters from the given ioHandler 00597 * @param handler the ioHandler to be used 00598 * @param complete if true (the default) the enclosing begin/end will 00599 * be also written, otherwise only the data block will be written. 00600 * @return true if write was successful 00601 */ 00602 virtual bool read(ioHandler& handler,const bool complete=true); 00603 00604 protected: 00605 /** 00606 * Current state 00607 */ 00608 uint32 state_; 00609 00610 /** 00611 * Constant a 00612 */ 00613 static const uint32 a_ = 48271; 00614 00615 /** 00616 * Constant m 00617 */ 00618 static const uint32 m_ = 2147483647; 00619 }; 00620 00621 /** 00622 * Mersenne Twister Random Number Generator. 00623 * 00624 * Reference: 00625 * M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally 00626 * Equidistributed Uniform Pseudo-Random Number Generator", 00627 * ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, 00628 * January 1998, pp 3-30. 00629 */ 00630 class rndMersenneTwister : public rndBase { 00631 public: 00632 /** 00633 * Constructor 00634 */ 00635 rndMersenneTwister(); 00636 00637 /** 00638 * Destructor 00639 */ 00640 virtual ~rndMersenneTwister(); 00641 00642 /** 00643 * Get a single number 00644 */ 00645 virtual uint32 draw(); 00646 00647 /** 00648 * Set the seed for the generator 00649 */ 00650 virtual void setSeed(const uint32 seed); 00651 00652 /** 00653 * Return the maximal obtainable number (inclusive) 00654 */ 00655 uint32 max() const; 00656 00657 /** 00658 * Write the parameters in the given ioHandler 00659 * @param handler the ioHandler to be used 00660 * @param complete if true (the default) the enclosing begin/end will 00661 * be also written, otherwise only the data block will be written. 00662 * @return true if write was successful 00663 */ 00664 virtual bool write(ioHandler& handler,const bool complete=true) const; 00665 00666 /** 00667 * Read the parameters from the given ioHandler 00668 * @param handler the ioHandler to be used 00669 * @param complete if true (the default) the enclosing begin/end will 00670 * be also written, otherwise only the data block will be written. 00671 * @return true if write was successful 00672 */ 00673 virtual bool read(ioHandler& handler,const bool complete=true); 00674 00675 private: 00676 00677 // Internal private constants 00678 static const int stateSize_ = 624; // __n 00679 static const int shiftSize_ = 397; // __m 00680 static const int maskBits_ = 31; // __r 00681 static const uint32 a_ = uint32(0x9908b0dfu); 00682 static const int u_ = 11; 00683 static const int s_ = 7; 00684 static const uint32 b_ = uint32(0x9d2c5680u); 00685 static const int t_ = 15; 00686 static const uint32 c_ = uint32(0xefc60000u); 00687 static const int l_ = 18; 00688 00689 /** 00690 * State of the random generator 00691 */ 00692 uint32 x_[stateSize_]; 00693 00694 /** 00695 * Pointer within state x_. 00696 */ 00697 int p_; 00698 }; 00699 00700 /** 00701 * Pointer to the random number generator for float. 00702 */ 00703 rndBase* generator_; 00704 00705 /** 00706 * Maximum number obtainable in the generator 00707 */ 00708 uint32 max_; 00709 00710 }; 00711 00712 /** 00713 * Read the resize mode 00714 * 00715 * @ingroup gStorable 00716 */ 00717 bool read(ioHandler& handler,randomDistribution::eNumberGenerator& data); 00718 00719 /** 00720 * Write the resize mode 00721 * 00722 * @ingroup gStorable 00723 */ 00724 bool write(ioHandler& handler, 00725 const randomDistribution::eNumberGenerator& data); 00726 00727 } 00728 00729 #endif 00730