random_generator.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004                                                \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef __VCG_RandomGenerator
00025 #define __VCG_RandomGenerator
00026 
00027 #include <vcg/math/base.h>
00028 
00029 namespace vcg {
00030 namespace math {
00031 
00037 class RandomGenerator
00038 {
00039 
00040 // construction
00041 public:
00042 
00043     RandomGenerator(){}
00044 
00045     virtual ~RandomGenerator()
00046     {}
00047 
00048 // public methods
00049 public:
00050 
00052     virtual void initialize(unsigned int seed)=0;
00053 
00055     virtual unsigned int generate(unsigned int limit)=0;
00056 
00058     virtual double generate01()=0;
00059 
00061     virtual double generate01closed()=0;
00062 
00064     virtual double generate01open()=0;
00065     virtual double generateRange(double minV, double maxV) { return minV+(maxV-minV)*generate01(); }
00066 
00067 };
00068 
00072 template <class ScalarType, class GeneratorType>
00073 vcg::Point3<ScalarType> GenerateBarycentricUniform(GeneratorType &rnd)
00074 {
00075   vcg::Point3<ScalarType>  interp;
00076     interp[1] = rnd.generate01();
00077     interp[2] = rnd.generate01();
00078     if(interp[1] + interp[2] > 1.0)
00079     {
00080         interp[1] = 1.0 - interp[1];
00081         interp[2] = 1.0 - interp[2];
00082         }
00083 
00084     assert(interp[1] + interp[2] <= 1.0);
00085     interp[0]=1.0-(interp[1] + interp[2]);
00086     return interp;
00087 }
00088 
00090 template <class ScalarType, class GeneratorType>
00091 vcg::Point3<ScalarType> GeneratePointInBox3Uniform(GeneratorType &rnd, const Box3<ScalarType> &bb)
00092 {
00093   return Point3<ScalarType>(
00094       (ScalarType) rnd.generateRange(double(bb.min[0]),double(bb.max[0])),
00095       (ScalarType) rnd.generateRange(double(bb.min[1]),double(bb.max[1])),
00096       (ScalarType) rnd.generateRange(double(bb.min[2]),double(bb.max[2]))
00097       );
00098 }
00099 
00111 template <class ScalarType, class GeneratorType>
00112 vcg::Point3<ScalarType> GeneratePointOnUnitSphereUniform(GeneratorType &rnd)
00113 {
00114   vcg::Point3<ScalarType> p;
00115   double x,y,s;
00116   do
00117   {
00118     x = 2.0*rnd.generate01()-1.0;
00119     y = 2.0*rnd.generate01()-1.0;
00120     s = x*x+y*y;
00121   } while (s>1);
00122   p[0]= ScalarType(2 * x * sqrt(1-s));
00123   p[1]= ScalarType(2 * y * sqrt(1-s));
00124   p[2]= ScalarType(1-2*s);
00125   return p;
00126 }
00127 
00129 template <class ScalarType, class GeneratorType>
00130 vcg::Point3<ScalarType> GeneratePointInUnitBallUniform(GeneratorType &rnd)
00131 {
00132   vcg::Point3<ScalarType> p;
00133   while(1)
00134   {
00135     p.Import(Point3d(0.5-rnd.generate01(),0.5-rnd.generate01(),0.5-rnd.generate01()));
00136     if(SquaredNorm(p)<=0.25){
00137       p*=2;
00138       return p;
00139     }
00140   }
00141 }
00142 
00143 
00156 class SubtractiveRingRNG : public RandomGenerator
00157 {
00158 
00159 // private data member
00160 private:
00161 
00162     // Subtractive Ring RNG status variables
00163     unsigned int _M_table[55];
00164     size_t _M_index1;
00165     size_t _M_index2;
00166 
00167 // construction
00168 public:
00169 
00170     // ctor
00171     SubtractiveRingRNG(int default_seed=161803398u)
00172     {
00173         initialize(default_seed);
00174     }
00175 
00176     virtual ~SubtractiveRingRNG()
00177     {}
00178 
00179 // public methods
00180 public:
00181 
00183     void initialize(unsigned int seed)
00184     {
00185         unsigned int __k = 1;
00186         _M_table[54] = seed;
00187         size_t __i;
00188         for (__i = 0; __i < 54; __i++)
00189         {
00190             size_t __ii = (21 * (__i + 1) % 55) - 1;
00191             _M_table[__ii] = __k;
00192             __k = seed - __k;
00193             seed = _M_table[__ii];
00194         }
00195         for (int __loop = 0; __loop < 4; __loop++)
00196         {
00197             for (__i = 0; __i < 55; __i++)
00198                 _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];
00199         }
00200         _M_index1 = 0;
00201         _M_index2 = 31;
00202     }
00203 
00205     unsigned int generate(unsigned int limit= 0xffffffffu)
00206     {
00207         _M_index1 = (_M_index1 + 1) % 55;
00208         _M_index2 = (_M_index2 + 1) % 55;
00209         _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];
00210         return _M_table[_M_index1] % limit;
00211     }
00212 
00214     double generate01()
00215     {
00216         const unsigned int lmt = 0xffffffffu;
00217         unsigned int number = generate(lmt);
00218         return static_cast<double>(number) / static_cast<double>(lmt);
00219     }
00220 
00222     double generate01closed()
00223     {
00224         const unsigned int lmt = 0xffffffffu;
00225         unsigned int number = generate(lmt);
00226         return static_cast<double>(number) / static_cast<double>(0xfffffffEu);
00227     }
00228 
00230     double generate01open()
00231     {
00232         const unsigned int lmt = 0xffffffffu;
00233         unsigned int number = generate(lmt);
00234         return (static_cast<double>(number) + 0.5) * (1.0/static_cast<double>(lmt));
00235     }
00236 
00237 };
00238 
00250 class MarsenneTwisterRNG : public RandomGenerator
00251 {
00252 
00253 // definitions
00254 private:
00255 
00256     static const int N = 624;
00257     static const int M = 397;
00258     static const unsigned int MATRIX_A = 0x9908b0dfu;   // constant vector a
00259     static const unsigned int UPPER_MASK = 0x80000000u; // most significant w-r bits
00260     static const unsigned int LOWER_MASK = 0x7fffffffu; // least significant r bits
00261 
00262 // private data member
00263 private:
00264 
00265     // Improved Marsenne-Twister RNG status variables
00266     unsigned int mt[N]; // the array for the state vector
00267     int mti;
00268 
00269 // construction
00270 public:
00271 
00272     // ctor
00273     MarsenneTwisterRNG()
00274     {
00275         initialize(5489u);
00276     }
00277 
00278     MarsenneTwisterRNG(unsigned int seed)
00279     {
00280         initialize(seed);
00281     }
00282 
00283     virtual ~MarsenneTwisterRNG()
00284     {}
00285 
00286 
00287 // public methods
00288 public:
00289 
00291     void initialize(unsigned int seed)
00292     {
00293         mt[0]= seed & 0xffffffffu;
00294         for (mti=1; mti<N; mti++)
00295         {
00296             mt[mti] = (1812433253u * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00297             /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00298             /* In the previous versions, MSBs of the seed affect   */
00299             /* only MSBs of the array mt[].                        */
00300             /* 2002/01/09 modified by Makoto Matsumoto             */
00301             mt[mti] &= 0xffffffffu;
00302             /* for >32 bit machines */
00303         }
00304     }
00305 
00312     void initializeByArray(unsigned int init_key[], int key_length)
00313     {
00314         int i, j, k;
00315         initialize(19650218u);
00316         i=1; j=0;
00317         k = (N>key_length ? N : key_length);
00318         for (; k; k--)
00319         {
00320             mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525u)) + init_key[j] + j; /* non linear */
00321             mt[i] &= 0xffffffffu; /* for WORDSIZE > 32 machines */
00322             i++; j++;
00323 
00324             if (i>=N)
00325             {
00326                 mt[0] = mt[N-1];
00327                 i=1;
00328             }
00329 
00330             if (j>=key_length) j=0;
00331         }
00332 
00333         for (k=N-1; k; k--)
00334         {
00335             mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941u)) - i; /* non linear */
00336             mt[i] &= 0xffffffffu; /* for WORDSIZE > 32 machines */
00337             i++;
00338             if (i>=N)
00339             {
00340                 mt[0] = mt[N-1];
00341                 i=1;
00342             }
00343         }
00344 
00345         mt[0] = 0x80000000u; /* MSB is 1; assuring non-zero initial array */
00346     }
00347 
00348     unsigned int generate(unsigned int limit)
00349     {
00350       return generate()%limit;
00351     }
00352 
00358     unsigned int generate()
00359     {
00360         unsigned int y;
00361         static unsigned int mag01[2]={0x0u, MATRIX_A};
00362         /* mag01[x] = x * MATRIX_A  for x=0,1 */
00363 
00364         if (mti >= N) // generate N words at one time
00365         {
00366             int kk;
00367 
00368             for (kk=0;kk<N-M;kk++)
00369             {
00370                 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00371                 mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1u];
00372             }
00373 
00374             for (;kk<N-1;kk++)
00375             {
00376                 y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00377                 mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1u];
00378             }
00379 
00380             y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00381             mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1u];
00382 
00383             mti = 0;
00384         }
00385 
00386         y = mt[mti++];
00387 
00388         /* Tempering */
00389         y ^= (y >> 11);
00390         y ^= (y << 7) & 0x9d2c5680u;
00391         y ^= (y << 15) & 0xefc60000u;
00392         y ^= (y >> 18);
00393 
00394         return y;
00395     }
00396 
00398     double generate01closed()
00399     {
00400         return generate()*(1.0/4294967295.0);
00401     }
00402 
00404     double generate01()
00405     {
00406         return generate()*(1.0/4294967296.0);
00407     }
00408 
00410     double generate01open()
00411     {
00412         return (((double)generate()) + 0.5)*(1.0/4294967296.0);
00413     }
00414 
00416     template <class PointType>
00417     void generateBarycentric(PointType &p){
00418         p[1] = this->generate01();
00419         p[2] = this->generate01();
00420 
00421         if(p[1] + p[2] > 1.0){
00422             p[1] = 1.0 - p[1];
00423             p[2] = 1.0 - p[2];
00424         }
00425         p[0]=1.0-(p[1] + p[2]);
00426     }
00427 }; // end class MarsenneTwisterRNG
00428 
00429 /* Returns a value with normal distribution with mean m, standard deviation s
00430  *
00431  * It implements the Polar form of the Box-Muller Transformation
00432  * A transformation which transforms from a two-dimensional continuous uniform distribution
00433  * to a two-dimensional bivariate normal distribution
00434  * with mean m, standard deviation s
00435  */
00436 inline double box_muller(RandomGenerator &generator, double m, double s) /* normal random variate generator */
00437 { /* */
00438   double x1, x2, w, y1;
00439   static double y2;
00440   static int use_last = 0;
00441   static RandomGenerator *last_generator = 0;
00442   if(last_generator != &generator)
00443     use_last = 0;
00444   last_generator = &generator;
00445   if (use_last){ /* use value from previous call */
00446     y1 = y2;
00447     use_last = 0;
00448   } else {
00449     do {
00450       x1 = 2.0 * generator.generate01closed() - 1.0;
00451       x2 = 2.0 * generator.generate01closed() - 1.0;
00452       w = x1 * x1 + x2 * x2;
00453     } while ( w >= 1.0 );
00454     w = sqrt( (-2.0 * log( w ) ) / w );
00455     y1 = x1 * w;
00456     y2 = x2 * w;
00457    use_last = 1;
00458   }
00459   return( m + y1 * s );
00460 }
00461 } // end namespace math
00462 } // end namespace vcg
00463 
00464 
00465 
00466 /*
00467    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
00468    All rights reserved.
00469 
00470    Redistribution and use in source and binary forms, with or without
00471    modification, are permitted provided that the following conditions
00472    are met:
00473 
00474      1. Redistributions of source code must retain the above copyright
00475         notice, this list of conditions and the following disclaimer.
00476 
00477      2. Redistributions in binary form must reproduce the above copyright
00478         notice, this list of conditions and the following disclaimer in the
00479         documentation and/or other materials provided with the distribution.
00480 
00481      3. The names of its contributors may not be used to endorse or promote
00482         products derived from this software without specific prior written
00483         permission.
00484 
00485    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00486    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00487    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00488    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00489    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00490    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00491    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00492    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00493    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00494    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00495    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00496 */
00497 
00498 
00499 #endif /* __VCG_RandomGenerator */


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:34:52