Sign in to follow this  

random value on Twister class

This topic is 2834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, i need help translating a class, i hope you guys dont mind i put the whole code in here. honestly speaking i dont understand what it did from top to bottom but i know the intention is to build a random value. the problem is i dont know if this random has some kind of constraint or its pure random. so im trying to build a ray tracing program. one of the purpose is to create a random value to create the ray, some kind of random sampling. if you follow this link: http://www.devmaste r.net/articles/ raytracing_ series/part5. php you'll find the explanation about the function used in one of the sniplet (the diffuse reflection subtopic). its the Twister.cpp file. all i need to know is if the value generated to some value or its pure random so i can replace it by c++ random function or there are some kind of constraints to the random value hope i did not ask too much :) many thanks in advance here is the code in the class

#include<math.h>
#include<stdlib.h>

#include"twister. h"

namespace Raytracer {

unsigned short mtRand_xsubi[ 3] = { 723, 32761, 44444 };

#define M 397
#define MATRIX_A 0x9908b0df
#define UPPER_MASK 0x80000000
#define LOWER_MASK 0x7fffffff

#define TEMPERING_MASK_ B 0x9d2c5680
#define TEMPERING_MASK_ C 0xefc60000
#define TEMPERING_SHIFT_ U(y)  (y >> 11)
#define TEMPERING_SHIFT_ S(y)  (y << 7)
#define TEMPERING_SHIFT_ T(y)  (y << 15)
#define TEMPERING_SHIFT_ L(y)  (y >> 18)

void Twister::Seed( unsigned long seed )
{
    mt[0]= seed & 0xffffffff;
    for ( mti = 1; mti < mtRand_N; mti++ ) mt[mti] = (69069 * mt[mti - 1]) & 0xffffffff;
    unsigned long s = 373737;
    for ( mti = 1; mti < mtRand_N; mti++ )
    {
		mt[mti] ^= s;
		s = s * 5531 + 81547;
		s ^= (s >> 9) ^ (s << 19);
    }
}

float Twister::Rand( )
{
    unsigned long y;
    static unsigned long mag01[2] = {0x0, MATRIX_A};
    if (mti >= mtRand_N) 
	{
        int kk;
        for (kk=0;kk<mtRand_N-M;kk+ +) 
		{
            y = (mt[kk]&UPPER_MASK)| (mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        for (;kk<mtRand_N-1;kk+ +) 
		{
            y = (mt[kk]&UPPER_MASK)| (mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+(M-mtRand_ N)] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        y = (mt[mtRand_N- 1]&UPPER_MASK)| (mt[0]&LOWER_MASK);
        mt[mtRand_N- 1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
        mti = 0;
    }
    y = mt[mti++];
    y ^= TEMPERING_SHIFT_ U(y);
    y ^= TEMPERING_SHIFT_ S(y) & TEMPERING_MASK_ B;
    y ^= TEMPERING_SHIFT_ T(y) & TEMPERING_MASK_ C;
    y ^= TEMPERING_SHIFT_ L(y);
    return ( (float)y * 2.3283064370807974e -10f );
}

unsigned long Twister::RandL( )
{
    unsigned long y;
    static unsigned long mag01[2] = { 0x0, MATRIX_A };
    if (mti >= mtRand_N) 
	{
        int kk;
        for (kk=0;kk<mtRand_N-M;kk+ +) 
		{
            y = (mt[kk]&UPPER_MASK)| (mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        for (;kk<mtRand_N-1;kk+ +) 
		{
            y = (mt[kk]&UPPER_MASK)| (mt[kk+1]&LOWER_MASK);
            mt[kk] = mt[kk+(M-mtRand_ N)] ^ (y >> 1) ^ mag01[y & 0x1];
        }
        y = (mt[mtRand_N- 1]&UPPER_MASK)| (mt[0]&LOWER_MASK);
        mt[mtRand_N- 1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
        mti = 0;
    }
    y = mt[mti++];
    y ^= TEMPERING_SHIFT_ U(y);
    y ^= TEMPERING_SHIFT_ S(y) & TEMPERING_MASK_ B;
    y ^= TEMPERING_SHIFT_ T(y) & TEMPERING_MASK_ C;
    y ^= TEMPERING_SHIFT_ L(y);
    return y;
}

}; // namespace Raytracer

Share this post


Link to post
Share on other sites
Yes, you can replace that Mersenne Twister random number generator with the basic C++ random number generator, but the Mersenne Twister generally offers better performance and better randomness, which is why it's used in that Devmaster tutorial in the first place.

If you were to rely on rand() to jitter samples in your raytracer (or to do anything else that requires a lot of random numbers), you'd eventually notice unnatural-looking patterns.

If the Mersenne Twister is working in your raytracer, you might as well keep using it, even if you don't understand its workings. If you could intuitively understand what it was doing, it wouldn't be much of a random number generator, would it?

Share this post


Link to post
Share on other sites

This topic is 2834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this