CVR-Lib last update 20 Sep 2009

cvrRandomDistribution.h

Go to the documentation of this file.
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 

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8