Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

General FreeBASIC programming questions.
Post Reply
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

MrSwiss wrote:I don't code, to win elegance competitions (I want correctly working code).
You should aim higher - as in both.
What's your case? That problem was easily solved! (with inelegant method)
My case is your CULngInt suggestion still rounded up - qualifying it as "a matter of underestimating the problem".

Would you answer my question: "Can you give an example - I cannot prove that statement." Thanks.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

deltarho[1859] wrote:My case is your CULngInt suggestion still rounded up
???
I don't care which way it rounds (in my case probably both ways), the results matter:

Code: Select all

0       9092543
1       9089030
2       9090667
3       9091446
4       9093429
5       9093451
6       9091621
7       9093796
8       9093080
9       9084842
10      9086095

to high: 0   to low: 0   count: 100000000
out of range: 0

press a key to EXIT ...
And yes, the set range is: 0 to 10 (in case you've not noticed).
deltarho[1859] wrote:Would you answer my question: "Can you give an example"
What example? It's simple logic (signed 32 bit type) - sign bit ...
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

MrSwiss wrote:And yes, the set range is: 0 to 10 (in case you've not noticed).
I noticed.
I don't care which way in rounds (in my case probably both ways), the results matter:
Of course, the results matter but your results came after I showed you CULngInt was wrong.

It seems that you have a problem admitting you made a mistake. That has never bothered me.
What example? It's simple logic (signed 32 bit type) - sign bit ...
In 32-bit mode:

Code: Select all

Dim As Double a = 2^203 - 123456789.123
Print Int(a) ' gives  1.285550435407192e+061 From Online Calulator = 1.285550435407192220433E+61
Sleep
Print SizeOf( Int(a) ) => 8.

Print Bin( Int(a) ) => 1111111111111111111111111111111111111000101001000011000000000000

31 bit granularity?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

31 bit granularity?
You obviously don't read posts carefully, or understand them well.
Reread my previous post, stating that: the problem (31 bit) is with FBC 32,
and doesn't apply in FBC 64!!!
deltarho[1859] wrote:It seems that you have a problem admitting you made a mistake. That has never bothered me.
Best laugh I've had, in a long time ...
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

Houston, we have a problem.

My last post used the official FBC 32.

With regard range 0 to 10 my method gives:

Code: Select all

9084508
9085640
9093734
9088211
9091668
9094198
9093347
9093699
9092386
9091369
9091240
Oh, look Ma, don't they look like MrSwiss' figures and with an efficiency scale of 1 to 10 of 3!
Best laugh I've had, in a long time ...
You are in denial - I am not the only one reading these posts.

Added: BTW, your code will not handle a signed range. My efficiency of 3 does via the inelegant inclusion of '- (First>=0)'. <smile>
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

Added: BTW, your code will not handle a signed range.
What did you expect with CULngInt(), you surely must be joking!
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

MrSwiss wrote:What did you expect with CULngInt(), you surely must be joking!
Another reason not to use CULngInt().

I expect your code to compete with mine.

I am getting close to suggesting the following be added to the help file under RND.

Code: Select all

Function rnd_range Overload (first As Double, last As Double) As Double
    Function = Rnd * (last - first) + first
End Function

Function rnd_range Overload (first As Longint, last As Longint) As LongInt
    Function = Int( Rnd * (last - first - (first>=0)) + first )
End Function
I need someone else to check the Longint validity especially its distribution. I am testing using rnd_range(-5,5), rnd_range(-11,-1), rnd_range(0,9) and rnd_range(1,10).
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

I expect your code to compete with mine.
Yet another wrong expectation ...
(you do your thing and, I do mine)
IMO, signed range isn't wanted, nor useful (most generators, incl. PCG32 use unsigned only).
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

MrSwiss wrote:IMO, signed range isn't wanted, nor usefull
Yours truly wrote:I don't think that I have ever used an unsigned range and why I used UlongInt. However, some folk might so I have changed UlongInt to LongInt.
I did, of course, mean 'signed' and not 'unsigned'.
most generators, incl. PCG32 use unsigned only).
The fact that generators are unsigned is irrelevant.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by dafhi »

Int() is notoriously slow. even gcc -O 3 doesn't optimize it out

use this instead

Code: Select all

dim as integer result = rnd*(hi+1 - lo) - .5 + lo
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

Thanks, dafhi

Your method fails the distribution test if lo < 0.

However, this works:

Code: Select all

Function = Rnd*(hi-(lo>=0) - lo) - .5 + lo
That is replace +1 with '-(lo>=0)'

Using FBC's official 32-bit distribution and Mersenne Twister:

FB's Double range comes in at 101MHz. I am using badidea's loop overhead filter to get the speed. My Int approach for LongInt comes in at 34MHz. Your method comes in at 63MHz; 85% faster than my method.

Using FBC's official 64-bit distribution and Mersenne Twister.

FB's Double range comes in at 191MHz. My Int approach for LongInt comes in at 191MHz. Your method comes in at 191MHz.

I repeated the above in a different order just to make sure that I did them correctly.

So Int working with LongInt in 32-bit mode is a disaster area. Not entirely surprising.

Int working with LongInt in 64-bit mode is as fast as Double and there is no difference between your method and mine. The latter surprised me because just looking at the two methods would suggest that your code should be faster - I am using Int and you have the extra factor of '- .5'. "Int() is notoriously slow" doesn't seem to be the case when working on LongInt in 64-bit mode. Perhaps that is not entirely surprising either.

I am going to buy into your code because not everyone is 'into' 64-bit.

FB's rnd_range using LongInt could look like this:

Code: Select all

Function rnd_range Overload (first As Longint, last As Longint) As LongInt
  Function = Rnd * (last - first -(first>=0)) - .5 + first
End Function
That covers [-first, -last], [-first, last] and [first, last].

If fxm is reading this he may want to include that in the Help file.

Your code is slightly less elegant than mine but it is more efficient. MrSwiss may give it a 4, or even a 5, compared to my paltry 3. No doubt he would give his code a 9 for what I see as a right 'dog's dinner'. <smile>

Thanks again.
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

Opening post MsWs.bas has been revised using dafhi's more efficient code for LongInt range.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

@deltarho[],

The proposed Function (Double range) is, by your own Standards: NOK!
Due to 'equal distribution' failure ... (Banker's rounding).

In any case, I'd use a #Define:

Code: Select all

' range: -/+ OK, +/+ OK, 0.0/+ OK, -/0.0 NOK, -/- NOK || distribution OK
#Define D_Rng(l, h)     ( Int(Rnd() * ((h+1) - (l)) + (l)) )
' range: any || distribution NOK, due to rounding, +/- 0.5 approx. 50% 
#Define sD_Rng(l, h)    ( Rnd() * ((h) - (l)) + (l) )
deltarho[1859]
Posts: 4310
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by deltarho[1859] »

MrSWiss wrote:I don't code, to win elegance competitions (I want correctly working code).
Two tables - the second column is the drift from the theoretical value. There is nothing between them and they could easily have been produced by the same code.

Code: Select all

9092543  1634
9089030 -1879
9090667 - 242
9091446   537
9093429  2520
9093451  2542
9091621   712
9093796  2887
9093080  2171
9084842 -6067
9086095 -4814
 
9084508  6401
9085640 -5269
9093734  2825
9088211 -2698
9091668   759
9094198  3289
9093347  2438
9093699  2790
9092386  1477
9091369   460
9091240   331
In fact the first table is MrSWiss' figures and the second table is my figures.

So much for Banker's rounding. <ROFL>
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Bernard Widynski's Middle Square Weyl Sequence RNG (MsWs)

Post by MrSwiss »

deltarho[1859] wrote:In fact the first table is MrSWiss' figures
Just so much:
they're NOT my figures, my figures are Doubles ...
Post Reply