2007-02-08 23:09:05 +01:00
/*
* Mersenne Twister Random Algorithm
* Copyright ( c ) 2006 Ryan Martell .
* Based on A C - program for MT19937 , with initialization improved 2002 / 1 / 26. Coded by
* Takuji Nishimura and Makoto Matsumoto .
*
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* FFmpeg is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2007-10-17 11:37:46 +02:00
# ifndef FFMPEG_RANDOM_H
# define FFMPEG_RANDOM_H
2007-02-08 23:09:05 +01:00
# define AV_RANDOM_N 624
typedef struct {
unsigned int mt [ AV_RANDOM_N ] ; ///< the array for the state vector
2008-08-04 23:54:50 +02:00
int index ; ///< Current untempered value we use as the base.
2007-02-08 23:09:05 +01:00
} AVRandomState ;
2008-08-04 23:54:50 +02:00
void av_init_random ( unsigned int seed , AVRandomState * state ) ; ///< To be inlined, the struct must be visible. So it does not make sense to try and keep it opaque with malloc/free-like calls.
void av_random_generate_untempered_numbers ( AVRandomState * state ) ; ///< Regenerate the untempered numbers (must be done every 624 iterations, or it will loop).
2007-02-08 23:09:05 +01:00
2008-07-28 17:44:00 +02:00
/**
2008-08-04 23:54:50 +02:00
* Generates a random number from the interval [ 0 , 0xffffffff ] .
2008-07-28 17:44:00 +02:00
*
2008-08-04 23:54:50 +02:00
* Please do NOT use the Mersenne Twister , it is slow . Use the random generator
2008-07-28 17:44:00 +02:00
* from lfg . c / h or a simple LCG like state = state * 1664525 + 1013904223.
* If you still choose to use MT , expect that you will have to provide
* some evidence that it makes a difference for the case where you use it .
*/
2007-02-08 23:09:05 +01:00
static inline unsigned int av_random ( AVRandomState * state )
{
unsigned int y ;
2008-08-04 23:54:50 +02:00
// Regenerate the untempered numbers if we should...
2007-02-08 23:09:05 +01:00
if ( state - > index > = AV_RANDOM_N )
av_random_generate_untempered_numbers ( state ) ;
2008-08-04 23:54:50 +02:00
// Grab one...
2007-02-08 23:09:05 +01:00
y = state - > mt [ state - > index + + ] ;
2008-08-04 23:54:50 +02:00
/* Now temper (Mersenne Twister coefficients). The coefficients for MT19937 are.. */
2007-02-08 23:09:05 +01:00
y ^ = ( y > > 11 ) ;
y ^ = ( y < < 7 ) & 0x9d2c5680 ;
y ^ = ( y < < 15 ) & 0xefc60000 ;
y ^ = ( y > > 18 ) ;
return y ;
}
2008-08-04 23:54:50 +02:00
/** Return random in range [0-1] as double. */
2007-02-08 23:09:05 +01:00
static inline double av_random_real1 ( AVRandomState * state )
{
/* divided by 2^32-1 */
return av_random ( state ) * ( 1.0 / 4294967296.0 ) ;
}
2007-10-17 11:37:46 +02:00
# endif /* FFMPEG_RANDOM_H */