romuTrio64 PRNG

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

romuTrio64 PRNG

Post by MrSwiss »

Another new PRNG (c) Mark A. Overton, transated/converted to FB (c) MrSwiss.
For more information, check: fomu-random.org
A 'quick and dirty' FreeBASIC implementation, with a short DEMO ...

Conditions to post here (in this thread) are:
everyone, except: d..r..[...], jj... and S...F... (personae's non grata here)

Of course NOT thread-safe (for speed), thread-safe means of course, slower (more overhead) ...
No one still sane, wants un-needed overhead (slow-down)!

code:

Code: Select all

' romuTrio64_rand.bas -- (c) 2021-07-27, MrSwiss (FreeBASIC translation/implementation)

' rotate-left macro 32 & 64-bits tested
#Define ROTL(v,r)    CULngInt(v) Shl (r) Or CULngInt(v) Shr (8 * SizeOf(v) - (r))
' end macro

Type romu3_t                            ' 64-bit PRNG (c) Mark A. Overton, https://www.romu-random.org
  Private:
    Const DmulF = 1d / CDbl(&hFFFFFFFFFFFFFFFFull)  ' small error, negligible
    As ULongInt xState, yState, zState              ' 192-bit State
  Public:
    declare Constructor ()
    Declare Constructor (ByVal As ULongInt, ByVal As ULongInt, _
                         ByVal As ULongInt, ByVal As UShort = 4e3)
    Declare Function    r_u64() As ULongInt
    Declare Function    r_f64() As Double
End Type

Constructor romu3_t()                   ' default ctor (fixed initializers: 11, 22, 33)
    With This
    .xState = 11 : .yState = 22 : zState = 33
    For i As UInteger = 0 To 999        ' 4000 call's (warm-up)
        .r_u64() : .r_u64() : .r_u64() : .r_u64()
    Next
    End With
End Constructor

Constructor romu3_t( _                  ' copy ctor (user defined initializers)
    ByVal x_    As ULongInt,    _       ' mandatory
    ByVal y_    As ULongInt,    _       ' mandatory
    ByVal z_    As ULongInt,    _       ' mandatory
    ByVal nrun  As UShort = 4e3 _       ' optional, default 4000 call's (warm-up)
    )
    With This
    .xState = x_ : .yState = y_ : zState = z_
    For i As UInteger = 1 To nrun Shr 2 ' integer division by 4
        .r_u64() : .r_u64() : .r_u64() : .r_u64()
    Next
    End With
End Constructor

Function romu3_t.r_u64() As ULongInt
    With This
    Dim As ULongInt xp = .xState, _
                    yp = .yState, _
                    zp = .zState

    .xState = 15241094284759029579ull * zp
    .yState = yp - xp : .yState = ROTL(.yState, 12)
    .zState = zp - yp : .zState = ROTL(.zState, 44)
    
    Return xp
    End With 
End Function

Function romu3_t.r_f64() As Double
    Return This.r_u64() * This.DmulF
End Function
' end type

' ===== DEMO =====
Dim As romu3_t  rnd1 = Type<romu3_t>(1001, 2039, 50733)
Dim As ULongInt cnt = 1

Print "running ... for 10 seconds, please wait."
Locate ,, 0
Var et = Timer + 10

While Timer < et
    rnd1.r_f64 : cnt += 1
Wend

Locate ,, 1
Print : Print "running at: " + Str(CSng(cnt / 1e7)) + " MHz"
Print : Print : Print "... done ... "; 
Sleep
' ===== end DEMO =====
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: romuTrio64 PRNG

Post by dafhi »

cool! i think your megahertz is off; if i run for less time, the rating goes down almost linearly
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: romuTrio64 PRNG

Post by MrSwiss »

Please explain your logic ... why off?
div 1e6 = one/million, however down to 1/sec = 1e7 if run = 10 sec.
I've tested wih 20 sec first, no significant difference noted ...
The shorter the test-time, the less accuracy can be expected ...
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: romuTrio64 PRNG

Post by dafhi »

oh i see what you're doing. dividing by 1e7 rather than delta vars. 10 seconds seems kinda long ..
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: romuTrio64 PRNG

Post by MrSwiss »

dafhi wrote:oh i see what you're doing. dividing by 1e7 rather than delta vars. 10 seconds seems kinda long ..
Ain't that, what it's typically called: moaning/groaning/complaining at a high level?
After all, it's clearly marked as 'DEMO' code ...
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: romuTrio64 PRNG

Post by dodicat »

I added
dim as romu3_t ranger
#define rangeI(f,l) clngint((ranger.r_u64() mod (((l)-(f))+(1))) + (f))
I added the practrand bit

Code: Select all

Dim Shared S As String * 1048576
Dim As Ulong Ptr SPtr, BasePtr
Dim As Long j

SPtr = Cptr(Ulong Ptr, StrPtr( S ))
BasePtr = SPtr
 
Do
  For j = 1 to 262144
    *SPtr = rangeI(0,4294967295)
    SPtr += 1
  Next
  print S;
  SPtr = BasePtr
Loop
  
I called the file swiss.bas (although really swiss+daphi), compiled it with 64 bit fb -Wc -O3
Results to 1 tb

Code: Select all

Microsoft Windows [Version 10.0.19042.1110]
(c) Microsoft Corporation. All rights reserved.

C:\Users\Computer\Desktop\fb\test\practrand\msvc12_64bit>swiss.exe | rng_test stdin32 -multithreaded
RNG_test using PractRand version 0.94
RNG = RNG_stdin32, seed = unknown
test set = core, folding = standard (32 bit)

rng=RNG_stdin32, seed=unknown
length= 512 megabytes (2^29 bytes), time= 3.0 seconds
  no anomalies in 178 test result(s)

rng=RNG_stdin32, seed=unknown
length= 1 gigabyte (2^30 bytes), time= 6.2 seconds
  no anomalies in 192 test result(s)

rng=RNG_stdin32, seed=unknown
length= 2 gigabytes (2^31 bytes), time= 11.8 seconds
  no anomalies in 204 test result(s)

rng=RNG_stdin32, seed=unknown
length= 4 gigabytes (2^32 bytes), time= 22.5 seconds
  no anomalies in 216 test result(s)

rng=RNG_stdin32, seed=unknown
length= 8 gigabytes (2^33 bytes), time= 45.3 seconds
  no anomalies in 229 test result(s)

rng=RNG_stdin32, seed=unknown
length= 16 gigabytes (2^34 bytes), time= 89.0 seconds
  no anomalies in 240 test result(s)

rng=RNG_stdin32, seed=unknown
length= 32 gigabytes (2^35 bytes), time= 172 seconds
  no anomalies in 251 test result(s)

rng=RNG_stdin32, seed=unknown
length= 64 gigabytes (2^36 bytes), time= 357 seconds
  no anomalies in 263 test result(s)

rng=RNG_stdin32, seed=unknown
length= 128 gigabytes (2^37 bytes), time= 733 seconds
  no anomalies in 273 test result(s)

rng=RNG_stdin32, seed=unknown
length= 256 gigabytes (2^38 bytes), time= 1447 seconds
  no anomalies in 284 test result(s)

rng=RNG_stdin32, seed=unknown
length= 512 gigabytes (2^39 bytes), time= 2990 seconds
  no anomalies in 295 test result(s)

rng=RNG_stdin32, seed=unknown
length= 1 terabyte (2^40 bytes), time= 6096 seconds
  no anomalies in 304 test result(s)

 
I had an inkling of a bury the hatchet week, but after seeing mrSwiss's approach (personae's non grata here), I have changed my mind.
Great idea.
My list would include many higher up the echelons, I would tend not to include foot soldiers in the main.
I notice that some members have not posted since Albert's sacking.
But I am still here at the moment and I would like to ask for Albert's return, I have no idea whether he wants to return or not, so maybe I am out on a limb here.
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: romuTrio64 PRNG

Post by Imortis »

MrSwiss wrote:Conditions to post here (in this thread) are:
everyone, except: d..r..[...], jj... and S...F... (personae's non grata here)
dodicat wrote:I had an inkling of a bury the hatchet week, but after seeing mrSwiss's approach (personae's non grata here), I have changed my mind.
Great idea.
My list would include many higher up the echelons, I would tend not to include foot soldiers in the main.
Please, be civil and polite. We expect you to show respect for all other members of the community here. We do not want flaming of any sort. Do not insult or flame other forum members. Additionally, do not write posts that will incite flames.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: romuTrio64 PRNG

Post by dodicat »

Up to 2TB now

Code: Select all

rng=RNG_stdin32, seed=unknown
length= 2 terabytes (2^41 bytes), time= 11835 seconds
  no anomalies in 313 test result(s) 
deltarho[1859]
Posts: 4301
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: romuTrio64 PRNG

Post by deltarho[1859] »

@dafhi

Having a counter executing in the same loop as a random float request will have a profound effect on the generator's ability to respond.

When I saw the value '0.9752647 MHz' I very nearly wet myself laughing.

I could advise on a better way, but I see from the opening post that I am not welcome here, so I will leave that for someone else.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: romuTrio64 PRNG

Post by MrSwiss »

@dodicat, thanks for the test, 2TB should suffice for most of those small app's.
deltarho[1859]
Posts: 4301
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: romuTrio64 PRNG

Post by deltarho[1859] »

@dodicat

Perhaps you don't know this, but with PractRand you can use stdin64.
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: romuTrio64 PRNG

Post by Imortis »

deltarho[1859] wrote:I could advise on a better way, but I see from the opening post that I am not welcome here, so I will leave that for someone else.
Please do not stir this pot any more than it has already been stirred...
Post Reply