What's wrong with that is, it produces the screenshot above. It doesn't look random at all. With a bit of tweaking, I can actually get the tile selections to go in straight rows, as if it was a mere modulo thing instead of pseudorandom.
If it's supposed to give me NANs, why do I get numbers like 131072, 16777216, and 134217728 passing through my modulo operation?
Quick Lua math question
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Quick Lua math question
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Re: Quick Lua math question
Here's the problem with your math.random code: you're reseeding math.random every time.
On some platforms (including, apparently, yours), the first random result after seeding Lua's RNG is not very random at all. It generally remains constant across similar seeds, and can foul up an otherwise fairly random distribution if you reseed a lot.
You have two options, then:
1) seed the RNG once, and just call math.random each time, which will give you the standard rand() distribution
2) do what you're doing with the multiple reseeds, but call math.random an extra time before getting the value and applying it - that'll discard the junk number and give you a more random result.
I guess the third option is write your own generator, but that seems like a lot of unnecessary work.
On some platforms (including, apparently, yours), the first random result after seeding Lua's RNG is not very random at all. It generally remains constant across similar seeds, and can foul up an otherwise fairly random distribution if you reseed a lot.
You have two options, then:
1) seed the RNG once, and just call math.random each time, which will give you the standard rand() distribution
2) do what you're doing with the multiple reseeds, but call math.random an extra time before getting the value and applying it - that'll discard the junk number and give you a more random result.
I guess the third option is write your own generator, but that seems like a lot of unnecessary work.
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Quick Lua math question
I already tried your method 2, anjo. That picture was taken with two pre-math.random calls before choosing the tiles. I was rather surprised by the result. So I'm stuck with method 3.
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Quick Lua math question
The main problem is that you seed every time. Of course the results don't look very random then.
At the beginning of your code, call math.randomseed(os.time()). When you need a random number, call math.random(min, max)
At the beginning of your code, call math.randomseed(os.time()). When you need a random number, call math.random(min, max)
Help us help you: attach a .love.
Re: Quick Lua math question
I was actually referring not to your implementation, but this:Taehl wrote:What's wrong with that is, it produces the screenshot above.
Code: Select all
function math.drand(seed, min, max)
math.randomseed(seed)
math.random(min, max)
end
The seed could be something like y * with + x.Taehl wrote:it requires that I can make a deterministic chain of pseudorandom numbers for any given coordinate.
Your implementation with math.sinh is not well suited for pseudo random numbers. Look at this plot of sinh(x):Taehl wrote:If it's supposed to give me NANs, why do I get numbers like 131072, 16777216, and 134217728 passing through my modulo operation?
You can see that the values of sinh(x) get really big really fast. It's already about 10000 for x = 10 and you are using numbers up to 999. Wolframalpha says this number is bigger 10^433 (a 1 with 433 zeros!)
Lua uses doubles as number type (at least on a PC/Mac). But a double cannot handle numbers that big. In fact, the bigger the number gets, some strange things happen. Adding a small number to a big number does not change the value; the small number gets "eaten". Some big (as well as some really small) numbers cannot be represented properly.
A combination of these and other effects could lead to your result.
If you absolutely do not want to use math.random() in combination with math.randomseed() to get predictable numbers, you could use the Middle-square method. The quality (= time to get to the same number with which you started is small) of this method is worse than what math.random() uses, but as you reseed for every cell anyway, it should not be a problem (it will be slower than the provided random though).
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Quick Lua math question
That's no good - a given coordinate must always return the same list of pseudorandom numbers. If I put os.time in the mix, the list will always be different.Robin wrote:The main problem is that you seed every time. Of course the results don't look very random then.
At the beginning of your code, call math.randomseed(os.time()). When you need a random number, call math.random(min, max)
I know, but that's exactly the method I was using when I made that screenshot.vrld wrote:I was actually referring not to your implementation, but this:Taehl wrote:What's wrong with that is, it produces the screenshot above.It meets your requirement:Code: Select all
function math.drand(seed, min, max) math.randomseed(seed) math.random(min, max) end
The seed could be something like y * with + x.Taehl wrote:it requires that I can make a deterministic chain of pseudorandom numbers for any given coordinate.
Aah, neat. That makes sense. The sinh thing doesn't hold any significance, I was just trying out random math calls until I found one that looked like it produced some wild numbers. I could use anything, really.vrld wrote:Your implementation with math.sinh is not well suited for pseudo random numbers. Look at this plot of sinh(x):Taehl wrote:If it's supposed to give me NANs, why do I get numbers like 131072, 16777216, and 134217728 passing through my modulo operation?
You can see that the values of sinh(x) get really big really fast. It's already about 10000 for x = 10 and you are using numbers up to 999. Wolframalpha says this number is bigger 10^433 (a 1 with 433 zeros!)
Lua uses doubles as number type (at least on a PC/Mac). But a double cannot handle numbers that big. In fact, the bigger the number gets, some strange things happen. Adding a small number to a big number does not change the value; the small number gets "eaten". Some big (as well as some really small) numbers cannot be represented properly.
A combination of these and other effects could lead to your result.
Not bad, that's pretty neat. Is there any way to implement that that doesn't require making it a string, messing with it, and making it a number again (i.e., is slow)?vrld wrote:If you absolutely do not want to use math.random() in combination with math.randomseed() to get predictable numbers, you could use the Middle-square method. The quality (= time to get to the same number with which you started is small) of this method is worse than what math.random() uses, but as you reseed for every cell anyway, it should not be a problem (it will be slower than the provided random though).
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
- Robin
- The Omniscient
- Posts: 6506
- Joined: Fri Feb 20, 2009 4:29 pm
- Location: The Netherlands
- Contact:
Re: Quick Lua math question
Ah, I didn't know. (Why do you want to do that, may I ask?)Taehl wrote:That's no good - a given coordinate must always return the same list of pseudorandom numbers. If I put os.time in the mix, the list will always be different.Robin wrote:The main problem is that you seed every time. Of course the results don't look very random then.
At the beginning of your code, call math.randomseed(os.time()). When you need a random number, call math.random(min, max)
And have you tried seeding by doing: math.randomseed(X_OF_TILE * 493 + Y_OF_TILE * 29302)? I just made up the two constant numbers. They might need to be primes, but I'm not sure. They are probably preferably large and very different from each other. I don't know if it'll work.
Help us help you: attach a .love.
Re: Quick Lua math question
What do you use to calculate the seed for a given tile? Maybe the error is in there.Taehl wrote:I know, but that's exactly the method I was using when I made that screenshot.
There is one that does not require messing with it, once it is a string:Taehl wrote:Is there any way to implement that that doesn't require making it a string, messing with it, and making it a number again (i.e., is slow)?
Code: Select all
local seed = 58008
function msrand(digits)
local r = seed * seed
local pad = math.floor( (#tostring(r) - digits) / 2 )
if pad > 0 then
r = math.floor(r / math.pow(10, pad)) % math.pow(10, pad)
end
if r == 0 or r == 1 then
seed = 5138008
else
seed = r
end
return r
end
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Quick Lua math question
mm... what about setting the seed to a fixed value then?Taehl wrote:That's no good - a given coordinate must always return the same list of pseudorandom numbers. If I put os.time in the mix, the list will always be different.Robin wrote:The main problem is that you seed every time. Of course the results don't look very random then.
At the beginning of your code, call math.randomseed(os.time()). When you need a random number, call math.random(min, max)
Code: Select all
-- at the beginning of your code
math.randomseed(314159265)
When I write def I mean function.
- Taehl
- Dreaming in associative arrays
- Posts: 1025
- Joined: Mon Jan 11, 2010 5:07 am
- Location: CA, USA
- Contact:
Re: Quick Lua math question
Better, but each coordinate needs a different list of pseudorandom numbers. They don't have to be very strong, but they do need to be different enough that a human won't see repetitions. Hence, I was trying to seed with a number derived from the coordinates.
By the way, for anyone else who wants to make suggestions on that front, please note that my coordinates are three-dimensional (my project-in-progress is 3D (even if it uses 2D graphics)).
By the way, for anyone else who wants to make suggestions on that front, please note that my coordinates are three-dimensional (my project-in-progress is 3D (even if it uses 2D graphics)).
Earliest Love2D supporter who can't Love anymore. Let me disable pixel shaders if I don't use them, dammit!
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Lenovo Thinkpad X60 Tablet, built like a tank. But not fancy enough for Love2D 0.10.0+.
Who is online
Users browsing this forum: Bing [Bot] and 8 guests