[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-apl] RNG
From: |
Xiao-Yong Jin |
Subject: |
Re: [Bug-apl] RNG |
Date: |
Wed, 18 May 2016 17:35:37 -0500 |
We need reproducibility, so /dev/urandom isn’t an option.
⎕FIO is a wonderful thing in gnu apl.
I still want something easy to manipulate in apl so I can play with different
ideas easily.
> On May 18, 2016, at 11:56 AM, Juergen Sauermann <address@hidden> wrote:
>
> Hi Elias,
>
> yes, even better! I was thinking of */dev/random *but that one blocks
> immediately
> due to lack of entropy.
>
> /// Jürgen
>
>
> On 05/18/2016 06:41 PM, Elias Mårtenson wrote:
>>
>> In that case, one can just open /dev/urandom and read random data from
>> there. That algorithm is supposed to be cryptographically secure.
>>
>> On 19 May 2016 12:39 a.m., "Juergen Sauermann" <address@hidden
>> <mailto:address@hidden>> wrote:
>>
>> Hi,
>>
>> does not work because Xiao-Yong is looking for a portable solution.
>>
>> A simple and fast - although not portable - solution is this:
>>
>> 1. write your favourite RNG in C/C++ (ie. copy the source code
>> from Numerical Recipes
>> and write the random number, say 8 bytes each, to stdout,
>>
>> 2. *popen()* the C/C++ program with ⎕FIO like:
>>
>> * Handle←⎕FIO[24] 'path-to-the**-C-program'*
>>
>> Every chunk of 8 bytes *fread()* with, say,
>>
>> * 256⊥8 ⎕FIO[6] Handle**
>> *
>> will then be one (signed) random number.
>> You can also read several random numbers in one go).
>>
>> The above essentially pipes the output of your C/C++ RND directly
>> into GNU APL.
>>
>> The code below will probably run faster if you can avoid to
>> convert between integers and bit vectors
>> too often (like in bit∆mult) and pre-compute constants like
>> *(⌽¯1+⍳64)* beforehand.
>>
>> /// Jürgen
>>
>>
>> On 05/18/2016 05:44 PM, Elias Mårtenson wrote:
>>> How about implementing this as a native quad-function?
>>>
>>> On 18 May 2016 at 23:09, Xiao-Yong Jin <address@hidden
>>> <mailto:address@hidden>> wrote:
>>>
>>> I translated a simple RNG from the book, Numerical Recipes.
>>> APL code is slow, probably because of the bit operations. The bit
>>> operations are not portable, relying on ¯1=2⊥64⍴1
>>> (always a 64-bit signed integer), for which Dyalog does
>>> differently. I’d welcome some suggestions. Full code follows.
>>>
>>> ∇z←x bit∆add y
>>> ⍝ 64-bit-vector addition as unsigned int.
>>> z←(64⍴2)⊤2⊥x+y
>>> ∇
>>>
>>> ∇z←x bit∆mul y
>>> ⍝ 64-bit-vector multiplication as unsigned int.
>>> z←⊃bit∆add/(⌽¯1+⍳64)bit∆shift¨⊂[1]x∘.∧y
>>> ∇
>>>
>>> ∇z←n bit∆shift x
>>> ⍝ Shift vector x by n positions with filler ↑0↑x.
>>> ⍝ Shift direction is (1 ¯1=×n)/'left' 'right'.
>>> →(n≠0)/nonzero
>>> z←x
>>> →0
>>> nonzero: z←((×n)×⍴x)↑n↓x
>>> ∇
>>>
>>> ∇r←ran∆bits;u;v;w
>>> (u v w)←ran∆state
>>> u←((64⍴2)⊤7046029254386353087) bit∆add u bit∆mul
>>> ((64⍴2)⊤2862933555777941757)
>>> v←v≠¯17 bit∆shift v
>>> v←v≠31 bit∆shift v
>>> v←v≠¯8 bit∆shift v
>>> w←(¯32 bit∆shift w) bit∆add ((64⍴2)⊤4294957665) bit∆mul
>>> w∧¯64↑32⍴1
>>> ran∆state←u v w
>>> r←u≠21 bit∆shift u
>>> r←r≠¯35 bit∆shift r
>>> r←r≠4 bit∆shift r
>>> r←w≠r bit∆add v
>>> ∇
>>>
>>> ∇r←ran∆double
>>> ⍝ Returns a random 64-bit floating point number in the range
>>> of [0,1).
>>> r←5.42101086242752217E¯20×ran∆int64
>>> →(r≥0)/0
>>> r←r+1
>>> ∇
>>>
>>> ∇ran∆init j;u;v;w
>>> v←(64⍴2)⊤4101842887655102017
>>> w←(64⍴2)⊤1
>>> u←v≠(64⍴2)⊤j
>>> ran∆state←u v w
>>> ⊣ran∆int64
>>> ran∆state[2]←ran∆state[1]
>>> ⊣ran∆int64
>>> ran∆state[3]←ran∆state[2]
>>> ⊣ran∆int64
>>> ∇
>>>
>>> ∇r←ran∆int32
>>> r←2⊥¯32↑ran∆bits
>>> ∇
>>>
>>> ∇r←ran∆int64
>>> r←2⊥ran∆bits
>>> ∇
>>>
>>> ∇pass←ran∆test;n;r;x;y;z;ran∆state;expected;⎕CT
>>> ran∆init 12345
>>> n←0
>>> r←⍳0
>>> loop:x←ran∆int64
>>> y←ran∆double
>>> z←ran∆int32
>>> →(∧/n≠0 3 99)/nosave
>>> r←r,x,y,z
>>> nosave:→(10000>n←n+1)/loop
>>> nosave:→(100>n←n+1)/loop
>>> expected←¯2246894694364600497 0.9394142395716724714
>>> 1367803369 2961111174787631927 0.1878554618793005226
>>> 3059533365 ¯1847334932704710330 0.7547241536014889229 1532567919
>>> ⎕CT←1E¯15
>>> pass←(r=expected),0 1 2 9 10 11 297 298 299,r,[1.5]expected
>>> ∇
>>>
>>> > On May 17, 2016, at 1:41 PM, Juergen Sauermann
>>> <address@hidden
>>> <mailto:address@hidden>> wrote:
>>> >
>>> > Hi Xiao-Yong,
>>> >
>>> > I have fixed the redundant %, see SVN 728.
>>> >
>>> > Regarding length, the GNU APL generator is 64-bit long (and
>>> so are
>>> > GNU APL integers), which should suffice for most purposes.
>>> >
>>> > Regarding bit vectors in APL, most people use integer 0/1
>>> vectors
>>> > for that (and then you have all boolean functions
>>> available) and
>>> > 2⊥ resp. 2 2 2 ... 2⊤ for conversions between 0/1 vectors
>>> and integers
>>> > You can also call into C/C++ libraries from GNU APL using
>>> native functions.
>>> >
>>> > /// Jürgen
>>> >
>>> >
>>> >
>>> >
>>> > On 05/17/2016 07:44 PM, Xiao-Yong Jin wrote:
>>> >> Hi,
>>> >>
>>> >>
>>> >>> On May 17, 2016, at 12:06 PM, Juergen Sauermann
>>> <address@hidden
>>> <mailto:address@hidden>>
>>> >>> wrote:
>>> >>>
>>> >>> Hi Xiao-Yong,
>>> >>>
>>> >>> the reason is that ⎕RL is defined as a single integer in
>>> the ISO standard.
>>> >>> That prevents generators with a too large state.
>>> >>>
>>> >> Okay. I was thinking whether ⎕RL can be an integer
>>> vector. Even a combined generator with a 3-int-state would
>>> be quite useful for numerical simulations if it could be.
>>> >>
>>> >>> For somebody seriously into simulations a general purpose
>>> generator
>>> >>> will never suffice, but it is fairly easy to program one
>>> in APL.
>>> >>>
>>> >> We definitely don’t want to make it cryptographically
>>> strong, but as a general purpose one, I would hope for decent
>>> high quality for relatively long monte carlo simulations.
>>> >>
>>> >> I don’t see an easy implementation because we don’t have
>>> exact 64bit unsigned integers and bit operations in APL. If
>>> any of you on this list have suggestions in implementing a
>>> good RNG in APL, please let me know.
>>> >>
>>> >>>
>>> >>> c++11 is currently not an option because I would like to
>>> not reduce the
>>> >>> portability of GNU APL onto different platforms.
>>> >>>
>>> >>> I'll have a look at the % usage.
>>> >>>
>>> >>> /// Jürgen
>>> >>>
>>> >>>
>>> >>>
>>> >>>
>>> >>> On 05/17/2016 06:16 PM, Xiao-Yong Jin wrote:
>>> >>>
>>> >>>> Hi,
>>> >>>>
>>> >>>> The LCG used for roll may be fine for some casual uses,
>>> but I would really like to see a higher quality RNG adopted
>>> here. Since speed may not be the main concern here, employing
>>> the use of c++11 <random> and preferably using the
>>> std::mt19937_64 seems to be much better for any monte carlo
>>> type calculations. It could be a trivial change to Quad_RL
>>> class, although saving the RNG state in a workspace may
>>> require a bit more code. What do you say?
>>> >>>>
>>> >>>> By the way, since in Workspace::get_RL 'return rand %
>>> mod;', you can remove the same ‘%’ in all the bif_roll
>>> definitions.
>>> >>>>
>>> >>>> Best,
>>> >>>> Xiao-Yong
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>
>>> >
>>>
>>>
>>>
>>
>
- [Bug-apl] RNG, Xiao-Yong Jin, 2016/05/17
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/17
- Re: [Bug-apl] RNG, Xiao-Yong Jin, 2016/05/17
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/17
- Re: [Bug-apl] RNG, Xiao-Yong Jin, 2016/05/18
- Re: [Bug-apl] RNG, Elias Mårtenson, 2016/05/18
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/18
- Re: [Bug-apl] RNG, Elias Mårtenson, 2016/05/18
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/18
- Re: [Bug-apl] RNG,
Xiao-Yong Jin <=
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/19
- Re: [Bug-apl] RNG, Kacper Gutowski, 2016/05/18
- Re: [Bug-apl] RNG, Juergen Sauermann, 2016/05/18
- Re: [Bug-apl] RNG, Xiao-Yong Jin, 2016/05/18
- Re: [Bug-apl] RNG, Kacper Gutowski, 2016/05/19