• To: mathgroup at smc.vnet.net
• From: "Ray Koopman" <koopman at sfu.ca>
• Date: Thu, 13 Apr 2006 02:19:49 -0400 (EDT)
• References: <e1ijuv\$3oh\$1@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```rjmachado3 wrote:
> I need to know the formula for the random function that return random
> numbers in a range of a and b integers [a,b] but that obey on a custom
> probability (possibly different!) for each integer number on this [a,b]
> range (of course the sum of all integer number probabilities are = 1!).
> Finally, what i want is the general function formula that simulate the
> random behavior (based on a custom probability value for each integer
>
> what i know so far is that the function formula for generating a "pure"
> random number between [a,b] range is:
>
> rand()*(b-a)+a
>
> where rand() return a random number between 0 and 1.

Here is a generator based on Mark Fisher's MakeDiscreteRandomFunction
[mg53424]. It avoids the built-in Random[], which is known to have
problems.

relprobs is a list of relative probabities, which should be positive
but need not sum to 1.
vals is a list of the values that the random variable may take on.
If vals is omitted then the integers 1,2,... are used.

In[1]:=
MakeDiscreteRandomFunk[relprobs_List] :=
MakeDiscreteRandomFunk[relprobs, Range@Length@relprobs]

In[2]:=
MakeDiscreteRandomFunk[relprobs_List, vals_List] :=
With[{M2 = 2^27 - 2, m1 = 2^26 - 1., m2 = 2^26 - 2},
With[{fun = Block[{x,p,v},
{p,v} = Transpose@Sort@Transpose@{relprobs,vals};
Function @@ {x, Piecewise @ Transpose @
{Reverse@v, Map[ x >= # &,
Reverse@Most@#*(M2*m1+m2)/Last@#&[FoldList[Plus,0,p]]]} } ] },
Compile[{{n, _Integer}},
Table[fun[Random[Integer,M2]*m1 + Random[Integer,m2]], {n}] ] ]]

In[3]:= getdata = MakeDiscreteRandomFunk[{1,2,3,2,1}];

In[4]:= getdata[20]
Out[4]= {1,5,4,3,2,3,3,2,2,3,5,2,5,3,3,4,2,5,4,4}

Sometimes we don't need the actual observations, just their frequency
distribution. The following generates the frequencies, always taking
vals = Range@Length@probs.

In[5]:=
MakeDiscreteRandomFreqFunk[relprobs_List] :=
With[{M2 = 2^27 - 2, m1 = 2^26 - 1., m2 = 2^26 - 2},
With[{k = Length@relprobs, fun = Block[{x,p,v},
{p,v} = Transpose@Sort@MapIndexed[{#1,#2[[1]]}&,relprobs];
Function @@ {x, Piecewise @ Transpose @
{Reverse@v, Map[ x >= # &,
Reverse@Most@#*(M2*m1+m2)/Last@#&[FoldList[Plus,0,p]]] } } ] },
Compile[{{n, _Integer}}, Module[{i, f = Table[0,{k}]},
Do[i = fun[Random[Integer,M2]*m1 + Random[Integer,m2]];
f[[i]]++, {n}]; f], {{i,_Integer},{f,_Integer,1}} ] ]]

In[6]:= getfreqs = MakeDiscreteRandomFreqFunk[{1,2,3,4}];

In[7]:= getfreqs[1*^5]
Out[7]= {9956,19892,29983,40169}

```

• Prev by Date: Re: FindFit / NonlinearFit Problems