math.randomseed how does it work?

I’ve seen theexample tutorial for using it with touchid but have not been able to figure out how to usebit outside of that exmple.

For instance if you were to use:

function draw()

math.randomseed(3)

print(math.random(1, 70))

end

the output would only be a series of 1’s. What is random about that? And how do you get it to take the randomseed into account?

Hi @pioyugb, that only happens because math.randomseed() allows you to force what numbers the math.random generates, try removing the math.randomseed(), run your code, then run it again, and see if the numbers differ, then try put math.randomseed() in your setup function.

XKCD cartoon on random numbers

@pioyugb that is because of how the pseudo(!) random generator in the underlying C lib works. The laymans version is, it takes some number which it calls the seed, applies a series of mathematical operations on it, and returns the result. Also, the return value becomes the new seed. With math.randomseed() you explicitely set the seed. This means, that in your example, the seed is always the same (3), this the result of the following mathematical operations will also always be the same, just like a*2 is always 6 if a is always 3. Try using math.randomseed() once in your setup() function, and in your draw() function just call math.random(), you will see, the results are much more… random :wink:

@Simeon

Is there a problem with the random functions. Run the following program and keep hitting the replay button. The seed changes, but the first number of the sequence is always 1 while the following 19 numbers vary. If you flip ( comment out the other) of the print(math.random() ) statements, you’ll see that the first number is always less than .001 . Also, if you change the line math.random(1,100) to 1,200 and keep replaying the program, when you hit a seed of 160 ( it might take awhile ), you’ll keep getting a seed of 160.


function setup()
    x=math.random(1,100)
    print("seed ",x)
    math.randomseed(x)
    for z= 1,20 do
        --print(math.random())
        print(math.random(1,1000))
    end
end

function draw()
end

that is certainly weird, but probably not a codea problem, as lua uses the rng of the system’s C library. I have made some tests, lua on Mac OS X shows the same problem, lua on linux does not.

I was thinking about replacing the Lua math.random() with a more modern algorithm, like Mersenne Twister. I’m not sure if this is a good idea, though. @gunnar_z, what do you think?

normally I’m all about “if it is there, don’t reimplement” - unless necessary. But this is really weird and limits the usefulness of the generator. This practically calls for a reimplementation - or for a wrapper that dumps the first value returned. I have no idea what algorithm Apples C lib uses, glibc uses a quite simple one. The Mersenne Twister has very nice properties, especially the ridiculously long period and also the desirable one that you can seed it and thus generate a deterministic sequence of “random” values, so it sure is a good choice. However, I would replace the low level rng, i.e. rand() and srand(), and have the math_random() and math_randomseed() functions call the new versions of those functions. This way you can easily switch back if you so desire.

I was quite surprised to read this so I just tried it on lua on my Mac and can confirm, except that I did occasionally get a first value of 2. It also “converged” on 160 as described.

Now, if I put it in a script and run it that way then I have to keep calling lua random.lua and it gives me the same seed every time: 1. However, if I use texlua then I get a different seed each time. Unfortunately, texlua doesn’t seem able to be run in interactive mode.

Anyway, seems as though texlua uses a different method for its random numbers.

@gunnar_z good points, I’ll look into doing this the way you describe.

Though we have to preserve old rand() and srand() behaviour for sfxr — otherwise people’s sound effects will change for particular random seeds.

@simeon just a thought, you could implement the new functions API compitible with the old ones, but with different names. Then you could #define rand my_rand and so on at the end of luaconf.h, this way your functions would only be used by lua, and you would not need to modify the source, and other parts of codea, that might rely on some behaviour of the orig rng are not influenced by this.