POV-Ray : Newsgroups : povray.text.scene-files : pseudo-random number generator Server Time
1 Nov 2024 07:25:12 EDT (-0400)
  pseudo-random number generator (Message 1 to 6 of 6)  
From: Pete
Subject: pseudo-random number generator
Date: 11 Aug 2001 14:31:43
Message: <5305.623T1870T6815291PeterC@nym.alias.net>
This is an attempt at a "random" number generator in povray.
I have not tested it that much but the results *look* random
to me.  The actual random number generator only works with
8 bit values so I call it four times multiply those results
to get a single float value.

Dunno if it will work under mega pov: might have to rename
some of the variables first.

Enjoy

Pete
-- 
#version 3.1;


#declare I = 0; // 1st index
#declare J = 0; // second index
#declare S = array[256] // thrash array
#declare K = array[256] // thrash init array
// this next array is where you put the starting seed.
// Put in four positive integer numbers, each in the
// range 0 to 99999999.
#declare thrash_seed = array[4]{
  68726648,
  05634878,
  77888472,
  98989388
}


// pop seeds into init array
#declare K[0] = int(thrash_seed[0] / (256 * 256 * 256));
#declare K[1] = mod(int(thrash_seed[0] / (256 * 256)), 256);
#declare K[2] = mod(int(thrash_seed[0] / 256), 256);
#declare K[3] = mod(thrash_seed[0], 256);

#declare K[4] = int(thrash_seed[1] / (256 * 256 * 256));
#declare K[5] = mod(int(thrash_seed[1] / (256 * 256)), 256);
#declare K[6] = mod(int(thrash_seed[1] / 256), 256);
#declare K[7] = mod(thrash_seed[1], 256);

#declare K[8] = int(thrash_seed[2] / (256 * 256 * 256));
#declare K[9] = mod(int(thrash_seed[2] / (256 * 256)), 256);
#declare K[10] = mod(int(thrash_seed[2] / 256), 256);
#declare K[11] = mod(thrash_seed[2], 256);

#declare K[12] = int(thrash_seed[3] / (256 * 256 * 256));
#declare K[13] = mod(int(thrash_seed[3] / (256 * 256)), 256);
#declare K[14] = mod(int(thrash_seed[3] / 256), 256);
#declare K[15] = mod(thrash_seed[3], 256);


// copy/spread out the seeds into the thrasher array
#declare cc = 0;
#while (cc < (256 / 16))
  #declare K[cc + 16] = K[cc];
  #declare K[cc + 32] = K[cc];
  #declare K[cc + 48] = K[cc];
  #declare K[cc + 64] = K[cc];
  #declare K[cc + 80] = K[cc];
  #declare K[cc + 96] = K[cc];
  #declare K[cc + 112] = K[cc];
  #declare K[cc + 128] = K[cc];
  #declare K[cc + 144] = K[cc];
  #declare K[cc + 160] = K[cc];
  #declare K[cc + 176] = K[cc];
  #declare K[cc + 192] = K[cc];
  #declare K[cc + 208] = K[cc];
  #declare K[cc + 224] = K[cc];
  #declare K[cc + 240] = K[cc];
  #declare cc = cc + 1;
#end


// now initialize S array
#declare cc = 0;
#while (cc < 256)
  #declare S[cc] = cc;
  #declare cc = cc + 1;
#end


// shuffle S using K
#render "shuffle S using K ... \n"
#declare I = 0;
#while (I < 256)
  #declare J = mod((J + S[I] + K[I]), 256);
  #declare swap_temp = S[I];
  #declare S[I] = S[J];
  #declare S[J] = swap_temp;
  #declare I = I + 1;
#end


// you could toss the K array at this point since we won't use it.


#declare I = 0;
#declare J = 0;


#macro fetch_one_256() // returns integer value in range 0-255
  #declare I = mod((I + 1), 256);
  #declare J = mod((J + S[I]), 256);
  #declare swap_temp = S[I];
  #declare S[I] = S[J];
  #declare S[J] = swap_temp;
  #local T = mod((S[I] + S[J]), 256);
  S[T]
#end


#macro waste_1000() // toss the first 1000 random numbers
  // to make a better random
  #render "waste_1000 starting\n"
  #local cc = 0;
  #while (cc < 1000)
    #local dummy = fetch_one_256();
    #local cc = cc + 1;
  #end
  #render "waste_1000 finishing\n"
#end



#macro fetch_float() // same output as rand(), but no input parameter
  // first build a float value from 4 bytes
  #local ff_result = fetch_one_256() * (256 * 256 * 256) +
                     fetch_one_256() * (256 * 256) +
                     fetch_one_256() * 256 +
                     fetch_one_256();
  // second scale to 0.0 - 1.0 range
  #local ff_result = ff_result / (256 * 256 * 256 * 256);
  ff_result   // done
#end


waste_1000()


// new test the random
#declare ntsc = false;


global_settings {
  assumed_gamma 2.2
}


camera {
  location 0
  direction <0, 0, 1.5>
  #if (ntsc = true)
    right <(640 / 400) * (10/11), 0, 0>
  #else
    right <(640/480), 0, 0>
  #end
  up <0, 1, 0>
  rotate x*50
  rotate y*-20
  translate <14, 50, -34>
}


#macro rrange(rlo, rhi) // return rand float in specified range
  #local real_low = min(rlo, rhi);
  #local real_high = max(rlo, rhi);
  #local rresult = real_low + fetch_float() * (real_high - real_low);
  rresult
#end


#macro rnd_rotate()
  rotate <360 * fetch_float(), 360 * fetch_float(), 360 * fetch_float()>
#end


#macro rnd_translate()
  translate <
    4 - 8 * fetch_float(),
    4 - 8 * fetch_float(),
    4 - 8 * fetch_float()
  >
#end


#macro perturb()
  rnd_translate()
  rnd_rotate()
#end


plane { // floor
  <0, 1, 0>, 0
  pigment {
    checker
     color rgb 1,
     color rgb 0.8
    scale 8
  }
  finish { ambient 0.5 diffuse 0.5 }
  normal {
    agate
    bump_size -0.2
    perturb()
  }
}
#render "floor done\n"


#declare cc = 0;
#while (cc < 400)
  #declare xx = rrange(-7.5, 7.5);
  #declare yy = rrange(0.5, 15.5);
  #declare zz = rrange(-7.5, 7.5);
  #local orange = fetch_float();
  #local sky_blue = fetch_float();
  sphere {
    <xx, yy, zz>, 0.5
    pigment { color rgb orange * <1, 0.5, 0> + sky_blue * <0, 0.5, 1> }
    finish { ambient 0.4 diffuse 0.6 }
  }
  #declare cc = cc + 1;
#end


light_source {
  <0, 0, -3000>
  color rgb 0.5
  rotate x*34
  rotate y*41
}


light_source {
  <0, 0, -3000>
  color rgb 0.5
  rotate x*90
}


/* actual end of this file */


Post a reply to this message

From: Warp
Subject: Re: pseudo-random number generator
Date: 11 Aug 2001 15:03:21
Message: <3b758178@news.povray.org>
How about just using rand()? It's easier, faster and cleaner. You can also
use several random number streams with it.

-- 
#macro N(D,I)#if(I<6)cylinder{M()#local D[I]=div(D[I],104);M().5,2pigment{
rgb M()}}N(D,(D[I]>99?I:I+1))#end#end#macro M()<mod(D[I],13)-6,mod(div(D[I
],13),8)-3,10>#end blob{N(array[6]{11117333955,
7382340,3358,3900569407,970,4254934330},0)}//                     - Warp -


Post a reply to this message

From: Peter Popov
Subject: Re: pseudo-random number generator
Date: 12 Aug 2001 01:14:36
Message: <s04cntg6vlpe1855ekamp5n9il1ajgpnam@4ax.com>
On 11 Aug 2001 15:03:21 -0400, Warp <war### [at] tagpovrayorg> wrote:

>  How about just using rand()? It's easier, faster and cleaner. You can also
>use several random number streams with it.

You among all should know the symptoms of Programmer's Tickle (Proof
of Concept Syndrome) when you see them :)


Peter Popov ICQ : 15002700
Personal e-mail : pet### [at] vipbg
TAG      e-mail : pet### [at] tagpovrayorg


Post a reply to this message

From: Pete
Subject: Re: pseudo-random number generator
Date: 13 Aug 2001 20:21:16
Message: <564.624T2954T13255843PeterC@nym.alias.net>
Warp wrote.

>  How about just using rand()? It's easier, faster and cleaner. You can also
>use several random number streams with it.

        Yes, rand() is much easier, much faster, and MUCH cleaner than
the mess I wrote.  I'll probably keep using rand().  :-)
        The only reason I posted it is because (A) some weird pov-er
out there might look at it and get inspired to some weird idea .,.. and
(b) some people here a few months ago were complaining about rand() not
being "random" enough and the code I posted *should* be *very* (pseudo)
random.


Pete


Post a reply to this message

From: Warp
Subject: Re: pseudo-random number generator
Date: 14 Aug 2001 19:21:28
Message: <3b79b278@news.povray.org>
Pete <Pet### [at] nymaliasnet> wrote:
: the code I posted *should* be *very* (pseudo) random.

  Which algorithm does it use? Can you give some values, like standard
deviation, mean deviation and variance?

  Or did you just came up with the algorithm by trying yourself? Sorry for
being sceptical, but as a student of computing science I know that making a
good pseudorandom number generator needs expertise and knowledge.
  A generator made by "trying things" can give results that look quite random,
but when properly measured can be quite poor. (Of course I'm not saying that
a very good algorithm cannot be found by chance...)

-- 
#macro N(D,I)#if(I<6)cylinder{M()#local D[I]=div(D[I],104);M().5,2pigment{
rgb M()}}N(D,(D[I]>99?I:I+1))#end#end#macro M()<mod(D[I],13)-6,mod(div(D[I
],13),8)-3,10>#end blob{N(array[6]{11117333955,
7382340,3358,3900569407,970,4254934330},0)}//                     - Warp -


Post a reply to this message

From: Pete
Subject: Re: pseudo-random number generator
Date: 17 Aug 2001 19:37:45
Message: <1610.627T573T11803550PeterC@nym.alias.net>
>Pete <Pet### [at] nymaliasnet> wrote:
>: the code I posted *should* be *very* (pseudo) random.

>  Which algorithm does it use? Can you give some values, like standard
>deviation, mean deviation and variance?

        It's the pseudo random number generator for Arc Four, as
described in Bruce Schniers "Applied Cryptography".  Papers and
analysis have been written about this by far better minds than mine!

>  Or did you just came up with the algorithm by trying yourself? Sorry for
>being sceptical, but as a student of computing science I know that making a
>good pseudorandom number generator needs expertise and knowledge.

        Years ago I tried to invent pseudo random algorithms and over
time I realized how lame they were.  So I gave up trying to invent
them.  Now I use "known" "tried and tested" "proven" algorithms
created by people who are much more clever than I am.  This is a port
of an existing algorithm to povray, not a new half-baked home-made
algorithm.

>  A generator made by "trying things" can give results that look quite
>  random,
>but when properly measured can be quite poor. (Of course I'm not saying that
>a very good algorithm cannot be found by chance...)

        The odds of stumbling on to a good algorithm (especially a
good psuedo random generator) are very small.  At least for me.  :)

>--
>#macro N(D,I)#if(I<6)cylinder{M()#local D[I]=div(D[I],104);M().5,2pigment{
>rgb M()}}N(D,(D[I]>99?I:I+1))#end#end#macro M()<mod(D[I],13)-6,mod(div(D[I
>],13),8)-3,10>#end blob{N(array[6]{11117333955,
>7382340,3358,3900569407,970,4254934330},0)}//                     - Warp -


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.