       • To: mathgroup at smc.vnet.net
• Subject: [mg23538] Reply to [mg23530]
• From: "Johannes Ludsteck" <ludsteck at zew.de>
• Date: Sat, 20 May 2000 03:10:17 -0400 (EDT)
• Organization: Zentr. f. Europ. Wirtschaftsforsch
• Sender: owner-wri-mathgroup at wolfram.com

```Dear Wagner,

The solution to you problem is simple if you use Mathematica's
<<Statistics`MultiDiscreteStatistics`

md=MultinomialDistribution[1,{0.2,0.4,0.1,0.3}]

Random[md]
{0,1,0,0}

N[Apply[Plus, RandomArray[md, 1000]]/1000]
{0.209, 0.398, 0.084, 0.309}
shows that you get the desired probabilities.

Therefore you get an index drawn from the above distribution by
typing.
Flatten[Position[Random[md], 1]]

If you need many repeated draws, you should use RandomArray for
efficiency reasons. For example, the following code makes 15
draws:
Flatten[Map[Position[#, 1] &, RandomArray[md, 15]]]
{3, 4, 4, 1, 2, 2, 2, 4, 3, 2, 2, 4, 4, 2, 4}

If you are interested in the algorithm used in the Mathematica
Package, just search for <Random[MultinomialDistribution> in the
code of the Package.
The code there seems at least to be shorter than the code in your
Module.
If you need a <very> fast implementation, you can speed up this
function by substituting the call to Random[BinomialDistribution...
inside of Random[MultinomialDistribution] by the code you find
there.

Hope that helps,
Johannes

> Howdy everyone,
>
> I have a list of probabilities (whose sum is 1.0), each associated
> with an index. I'd like to randomly choose an index based on
those
> probabilities. For example, suppose
>
> m = {0.2, 0.4, 0.1, 0.3}
>
> which dictates that index 1 should be selected with prob 0.2,
index 2
> with prob 0.4, index 3 with prob 0.1, and index 4 with prob 0.3.
>
> I've already written a function that works, but I think there should
> be a simpler, more elegant, and more efficient way of
accomplishing
>
> Here's my solution:
>
> randomIndexPick[ m_ ] :=
>      Module[ { r, s },
>        r = Random[];
>        s = Sort[ Thread[ { m, Range[ Length[m] ] } ] ];
>        s = Table[ { Sum[ s[[i, 1]], { i, 1, k } ], s[[k, 2]] },
>                   { k, 1, Length[m] } ];
>        s = Map[ ( { r ¾ First[#], Last[#] } ) &, s ];
>        s = Select[ s, ( First[#] ) & ];
>        Return[ s[[1, 2]] ] ];
>
> Table[ randomIndexPick[ {0.2, 0.4, 0.1, 0.3} ], {20} ]
>
> {4, 4, 1, 2, 2, 4, 4, 1, 4, 4, 2, 3, 1, 2, 2, 2, 4, 3, 2, 3}
>
> Does anybody have a better solution?
>
> Thanks!
> Wagner

Johannes Ludsteck
Centre for European Economic Research (ZEW)
Department of Labour Economics,
Human Resources and Social Policy
Phone (+49)(0)621/1235-157
Fax (+49)(0)621/1235-225

P.O.Box 103443
D-68034 Mannheim
GERMANY

Email: ludsteck at zew.de

```

• Prev by Date: Re: need little help
• Next by Date: Re: Question on version 4 and long Pi calculations.....
• Previous by thread: Fit and InverseLaplaceTransform
• Next by thread: RE: Fit and InverseLaplaceTransform. Improvement