random.c
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 Copyright (C) 2013 Andrea Vedaldi.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00070 #include "random.h"
00071 
00072 /*
00073 A C-program for MT19937, with initialization improved 2002/1/26.
00074 Coded by Takuji Nishimura and Makoto Matsumoto.
00075 
00076 Before using, initialize the state by using init_genrand(seed)
00077 or init_by_array(init_key, keySize).
00078 
00079 Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
00080 All rights reserved.
00081 
00082 Redistribution and use in source and binary forms, with or without
00083 modification, are permitted provided that the following conditions
00084 are met:
00085 
00086 1. Redistributions of source code must retain the above copyright
00087 notice, this list of conditions and the following disclaimer.
00088 
00089 2. Redistributions in binary form must reproduce the above copyright
00090 notice, this list of conditions and the following disclaimer in the
00091 documentation and/or other materials provided with the distribution.
00092 
00093 3. The names of its contributors may not be used to endorse or promote
00094 products derived from this software without specific prior written
00095 permission.
00096 
00097 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00098 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00099 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00100 A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00101 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00102 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00103 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00104 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00105 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00106 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00107 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00108 
00109 
00110 Any feedback is very welcome.
00111 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
00112 email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
00113 */
00114 
00115 #include <stdio.h>
00116 #include <string.h>
00117 
00118 /* Period parameters */
00119 #define N 624
00120 #define M 397
00121 #define MATRIX_A VL_UINT32_C(0x9908b0df)   /* constant vector a */
00122 #define UPPER_MASK VL_UINT32_C(0x80000000) /* most asignificant w-r bits */
00123 #define LOWER_MASK VL_UINT32_C(0x7fffffff) /* least significant r bits */
00124 
00125 /* initializes mt[N] with a seed */
00126 
00131 void
00132 vl_rand_init (VlRand * self)
00133 {
00134   memset (self->mt, 0, sizeof(self->mt[0]) * N) ;
00135   self->mti = N + 1 ;
00136 }
00137 
00143 void
00144 vl_rand_seed (VlRand * self, vl_uint32 s)
00145 {
00146 #define mti self->mti
00147 #define mt self->mt
00148   mt[0]= s & VL_UINT32_C(0xffffffff);
00149   for (mti=1; mti<N; mti++) {
00150     mt[mti] =
00151       (VL_UINT32_C(1812433253) * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
00152     /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
00153     /* In the previous versions, MSBs of the seed affect   */
00154     /* only MSBs of the array mt[].                        */
00155     /* 2002/01/09 modified by Makoto Matsumoto             */
00156     mt[mti] &= VL_UINT32_C(0xffffffff);
00157     /* for >32 bit machines */
00158   }
00159 #undef mti
00160 #undef mt
00161 }
00162 
00169 void
00170 vl_rand_seed_by_array (VlRand * self, vl_uint32 const key [], vl_size keySize)
00171 {
00172 #define mti self->mti
00173 #define mt self->mt
00174   int i, j, k;
00175   vl_rand_seed (self, VL_UINT32_C(19650218));
00176   i=1; j=0;
00177   k = (N > keySize ? N : (int)keySize);
00178   for (; k; k--) {
00179     mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * VL_UINT32_C(1664525)))
00180       + key[j] + j; /* non linear */
00181     mt[i] &= VL_UINT32_C(0xffffffff); /* for WORDSIZE > 32 machines */
00182     i++; j++;
00183     if (i>=N) { mt[0] = mt[N-1]; i=1; }
00184     if (j>=(signed)keySize) j=0;
00185   }
00186   for (k=N-1; k; k--) {
00187     mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * VL_UINT32_C(1566083941)))
00188       - i; /* non linear */
00189     mt[i] &= VL_UINT32_C(0xffffffff) ; /* for WORDSIZE > 32 machines */
00190     i++;
00191     if (i>=N) { mt[0] = mt[N-1]; i=1; }
00192   }
00193 
00194   mt[0] = VL_UINT32_C(0x80000000); /* MSB is 1; assuring non-zero initial array */
00195 #undef mti
00196 #undef mt
00197 }
00198 
00207 void
00208 vl_rand_permute_indexes (VlRand *self, vl_index *array, vl_size size)
00209 {
00210   vl_index i, j, tmp;
00211   for (i = size - 1 ; i > 0; i--) {
00212     /* Pick a random index j in the range 0, i + 1 and swap it with i */
00213     j = (vl_int) vl_rand_uindex (self, i + 1) ;
00214     tmp = array[i] ; array[i] = array[j] ; array[j] = tmp ;
00215   }
00216 }
00217 
00218 
00224 vl_uint32
00225 vl_rand_uint32 (VlRand * self)
00226 {
00227   vl_uint32 y;
00228   static vl_uint32 mag01[2]={VL_UINT32_C(0x0), MATRIX_A};
00229   /* mag01[x] = x * MATRIX_A  for x=0,1 */
00230 
00231 #define mti self->mti
00232 #define mt self->mt
00233 
00234   if (mti >= N) { /* generate N words at one time */
00235     int kk;
00236 
00237     if (mti == N+1)   /* if init_genrand() has not been called, */
00238       vl_rand_seed (self, VL_UINT32_C(5489)); /* a default initial seed is used */
00239 
00240     for (kk=0;kk<N-M;kk++) {
00241       y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00242       mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & VL_UINT32_C(0x1)];
00243     }
00244     for (;kk<N-1;kk++) {
00245       y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
00246       mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & VL_UINT32_C(0x1)];
00247     }
00248     y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
00249     mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & VL_UINT32_C(0x1)];
00250 
00251     mti = 0;
00252   }
00253 
00254   y = mt[mti++];
00255 
00256   /* Tempering */
00257   y ^= (y >> 11);
00258   y ^= (y << 7) & VL_UINT32_C(0x9d2c5680);
00259   y ^= (y << 15) & VL_UINT32_C(0xefc60000);
00260   y ^= (y >> 18);
00261 
00262   return (vl_uint32)y;
00263 
00264 #undef mti
00265 #undef mt
00266 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51