Commit b72662a6 authored by Peter Billam's avatar Peter Billam

introduce zipf_rand

parent 2709e5a8
......@@ -67,6 +67,8 @@ random.ps - Some useful random-number stuff in PostScript
[ <I>an array</I> 5 ] <A HREF="#randomgetn">randomgetn</A> % 5 random elements
[ <I>an array</I> ] <A HREF="#zipf_rand">zipf_rand</A> % Zipf distribution
</PRE>
<A NAME="description"><HR></A><H3>DESCRIPTION</H3>
......@@ -84,7 +86,8 @@ for generating random numbers according to various distributions.
<A HREF="#urand">urand</A>, &nbsp;
<A HREF="#rayleigh_rand">rayleigh_rand</A>, &nbsp;
<A HREF="#randomget">randomget</A>, &nbsp;
<A HREF="#randomgetn">randomgetn</A>
<A HREF="#randomgetn">randomgetn</A>, &nbsp;
<A HREF="#zipf_rand">zipf_rand</A>
</H3>
<DL>
......@@ -164,6 +167,18 @@ so that if the elements of the given array are all distinct,
the elements of the returned array will also be distinct.
</P>
</DD><DT>
<B><A NAME="zipf_rand">
[ an array ] zipf_rand</A></B>
</DT><DD><P>
This example leaves on the stack
an element from the given array according to the Zipf distribution<BR>
&nbsp; &nbsp;
<A HREF="https://en.wikipedia.org/wiki/Zipf%27s_law">
en.wikipedia.org/wiki/Zipf%27s_law</A><BR>
with the first element being the most frequent.
</P>
</DD></DL>
<A NAME="install"> <HR> </A>
......@@ -203,6 +218,7 @@ www.pjb.com.au/comp/contact.html</A>
</P>
<A NAME="changes"><HR></A><H3>CHANGES</H3><PRE>
20180712 introduce <A HREF="#zipf_rand">zipf_rand</A>
20170706 introduce <A HREF="#rayleigh_rand">rayleigh_rand</A>
20170512 introduce <A HREF="#urand">urand</A>
20170511 the old code deleted; much neater
......@@ -222,6 +238,9 @@ www.design.caltech.edu/erik/Misc/Gaussian.html</A>
<A HREF="https://en.wikipedia.org/wiki/Rayleigh_distribution">
en.wikipedia.org/wiki/Rayleigh_distribution</A>
</LI><LI>
<A HREF="https://en.wikipedia.org/wiki/Zipf%27s_law">
en.wikipedia.org/wiki/Zipf%27s_law</A><BR>
</LI><LI>
<A HREF="line_drawing.html">line_drawing.ps</A>
</LI><LI>
<A HREF="brownian.html">brownian.ps</A>
......
......@@ -85,3 +85,32 @@ gauss_rand pop % initialise, and discard the resulting zero
/rayleigh_rand { % usage: sigma rayleigh_rand
1.0 urand sub ln -2 mul sqrt mul
} bind def
/zipf_rand { % usage: [ an array ] zipf_rand
20 dict begin /arr_in exch def
/n arr_in length def
/rel_freq n dict def
/sum 0.0 def
/i 0 def {
i n ge { exit } if
rel_freq i 1 i 1 add div put
/sum sum rel_freq i get add def
/i i 1 add def
} loop
/switchpoints n dict def
switchpoints 0 1 sum div put % first element is 1/sum
/i 1 def { % start loop at second element
i n 1 sub ge { exit } if
switchpoints i switchpoints i 1 sub get rel_freq i get sum div add put
/i i 1 add def
} loop
/r urand def
/return_index n 1 sub def % in case it's not found earlier
/i 0 def {
i n 1 sub ge { exit } if
r switchpoints i get lt { /return_index i def exit } if
/i i 1 add def
} loop
arr_in return_index get % return
end
} bind def
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment