Is the randominteger( Function Truly Random?

Greetings Pan X Experts!

Recently, while using the randominteger( function, I became suspicious that this function was not entirely random. So, I created the following database to test this theory.

image

In this database, I created the following procedure.

local iLoop
for iLoop,1,10000
selectall
select «Record ID»=randominteger(1,10)
«Frequency»=«Frequency»+1
endloop

Here are the results of this procedure:

image

I zeroed out the Frequency field, and tried again. Here are the results of the second test.

image

I repeated this test a few times. Each time, the results are approximately the same.

Is the randominteger( not random, or is there something I don’t understand about the use of this function?

Thank you for your help!

Paul

I used a slightly different version of the code that uses Find instead of the Select to set the values of the Frequency field. Starting this with a noshow speeded things up and prevented all the blinking screen activity.

noshow
for iLoop,1,10000
find «Record ID»=randominteger(1,10)
«Frequency»=«Frequency»+1
endloop
showpage
endnoshow

The results of several runs were pretty consistent and showed a general graduated frequency return from the highest for 1 and the least for 10 with 1 being returned almost three times as often as 10.

These tests may point to a problem with Select, and Find, rather than RandomInteger(.

This is the procedure I ran.

let x = rep(cr(),999999)
x = arrayfilter(x,cr(),"randominteger(1,10)")
importtext x, "ExistingData","Replace"
Field "A"
groupup
count
outlinelevel 1
Field "B"
FormulaFill seq()

I ran it with sample sizes of 10,000 100,000 and 1,000,000 respectively, and got these results.

image

image

image

It takes longer to Find or Select a record at the bottom than it does one at the top. The statement that increments the frequency, may not be waiting for the Find or Select to finish, and it’s incrementing the first record, while it’s still active.

This issue might be the same as Jim Cook’s in disguise.

It sounds like you might be equating “random” with “equal distribution”. I’m not sure they are exactly the same - or how many samples are required to achieve an equal distribution.

Language can be a little fuzzy here. For example, I can image a random generator that gives numbers in a Gaussian (Bell Shaped Curve) distribution.

Hmm, I don’t think so. One would expect measurements of natural phenomena to exhibit a bell shaped curve. But for randomly generated numbers, over large test sizes, the results obtained by Dave are reasonable.

In the examples provided by Gary, one can see a definite pattern, which by definition, is not random.

Good observation. To further explore this theory, I ran two more procedures.

The following procedure puts a delay between the record selection, and the statement that increments the frequency.

local iLoop,iRandom
noshow
for iLoop,1,1000
selectall
select «Record ID»=randominteger(1,10)
delay 0.016
«Frequency»=«Frequency»+1
endloop
selectall
show

The results were not random.

Screenshot 2024-02-08 at 10.34.10 AM

Next, I ran the following procedure.

local iLoop,iRandom
noshow
for iLoop,1,1000
selectall
iRandom=randominteger(1,10)
delay 0.016
select «Record ID»=iRandom
«Frequency»=«Frequency»+1
endloop
selectall
show

Which yielded the following results.

image

From these tests, it appears the Select function is not waiting for randomintegar( to complete it’s function.

I can imagine one too. In fact I once created one with a binomial distribution. If randominteger( were intended to do something fancy like that, I’m sure it would have been documented, rather than expect us to use our imaginations, and guess right.

The procedure I wrote, which doesn’t do any finding or selecting is producing results that I believe are consistent with an even probability distribution function.

Yes - with enough samples, as your test showed, the distribution levels out - I once tried the martingale system on a roulette wheel that gave 8 reds in a row (I had bet on black :neutral_face: ); the number of trials matters.

But a random bell curve distribution has its place. You might even say it’s normal.

Could this be Benford’s Law at work?

The original example shows code that uses pre-existing data and then counts it in a suspect way, but it’s not really testing the randominteger function directly. Unless we’re sure the data in the OP’s database us actually random. It could in fact be data that falls under the scope of Benford’s law, and thats why the data looks skewed.

Dave’s method seems to be a better test of the function.

cw

Benford’s law applies to numbers that span several orders of magnitude. The examples that Paul Overby, and Gary Yonaites gave had only the numbers 1 through 10, so Benfords law doesn’t really apply.

It’s not supposed to be random. It’s simply 10 records containing the numbers 1 through 10. What they were doing was equivalent to rolling a 10 sided die 10,000 times and counting the number of times each number appeared. Their procedures would Select/Find the record containing the random number generated by randominteger(, and then add 1 to the number in that records Frequency field.

My method was designed to be faster, which allowed me to use larger sample sizes in a reasonable amount of time, but mathematically, the concept was no different from theirs.

I think the skewed results they got were due to a bug in Panorama. It just isn’t the randominteger( function that was the cause. My results weren’t skewed because randominteger( was about the only thing my code had in common with theirs.

  1. The randominteger( function is indeed random.
  2. There is something you don’t understand about the select statement.

Let’s look at this line:

select «Record ID»=randominteger(1,10)

I think you are assuming that a random integer is calculated, then all records that match that integer are selected. But that is NOT what is happening.

What actually happens is that starts with the first record, calculates a random integer, then checks to see if the first record matches that random integer. Then Panorama goes to the second record, calculates a different random integer, and checks to see if the second record matches this new value. Another random integer is calculated for the third record, another for the fourth record, etc. So it’s very likely that multiple records will be selected. If that happens, only the first of the multiple records will have the frequency bumped, so the records closer to the top of the database will get bumped more. Exactly what you saw.

Here is a fixed version of this code. With this code the random number is calculated once per iteration of the loop, not 100,000 times.

local iLoop
for iLoop,1,100000
    let r = randominteger(1,10)
    select «Record ID»=r
    «Frequency»=«Frequency»+1
endloop
selectall

Note that I also removed the selectall statement above the select statement. This wasn’t accomplishing anything other than wasting time.

Here’s the result - nice and random.

Note: Just to make sure, I also tried this with the time wasting selectall statement - no difference.

TLDR; there’s no bug in randominteger(, and no bug in find/select :slight_smile: At least as far as this thread is concerned.

1 Like

That explains why this one produced reasonable results then.

In that case, Select was comparing the Record ID to the variable, whose value wasn’t changing.

There is also a 35% chance that no records will be selected (0.9^10). In that case, the first record will remain the active record.

Good point. That’s why the first record was so out of whack, then the others gradually decreased. I think the chance of the first record being incremented was 35%+10%, which is almost exactly the result he got (4483).