Version 3 of Poisson distribution

Updated 2005-12-16 21:03:19

This is a discrete distribution of a random variable. An example may tell us what it can be used for:

Suppose this Wiki is visited by 12 people daily (as an average). What is the probability, that the Wiki will have 20 visitors a day? The answer is calculated using the Poisson distribution:

         20    -12
       12   * e
 p =   ------------
           20!

The answer is: p = 0.0097 which is 0.97%. Another example is: Simulating a server system.

Here is an implementation that draws integer numbers being Poisson distributed. It is based on an ecology modelling book I am currently reading and this thread on c.l.t [L1 ] helped finding a good Tcl implementation. That's a discussion on how to draw random numbers from a given probability distribution (not just the onw shown here).

 proc RandomPoisson {lambda count} {
        #
        # generate random numbers that are poisson distributed
        #
        # lambda -> expected value = "mean value" (which happens to also be the variance)
        # count -> number of numbers to be generated
        #
        # (adapted from: "Parameter Estimation in Ecology" by O. Richter & D. Söndgerath)

        # factorial f (here: the factorial of 0):
        set f 1
        # poisson probability of the value 0:
        set su [expr {exp(-$lambda)}]
        set p(0) $su
        # probabilities of the integers up to the math limits of Tcl:
        # (computed as the discrete density function)
        set i 0
        while {1} {
                incr i
                set f [expr {$f*$i}]
                set su [expr {$su + exp(-$lambda) * pow($lambda,$i)/double($f)}]
                if {$su > 1} {
                        # we cannot calculate more precisely here,
                        # so we assume 1 is ok for the final density:
                        set p($i) 1
                        break
                }
                set p($i) $su
        }
        # calculate random values according to the 
        # given discrete probability density function:
        # (this does work for all dicrete distributions,
        # not only for poisson)
        for {set c 0} {$c < $count} {incr c} {
                # random number in the interval [0,1]:
                set x [expr {rand()}]
                # transform this number to the correct target interval:
                for {set j 0} {$j <= $i} {incr j} {
                        if {$p($j) > $x} {
                                lappend result $j
                                break
                        }
                }
        }
        return $result
 }

We run into a problem here when using Tcl's normal expr. The numbers in the formula quickly put expr to its limits and therefor I have added the case where the probability is just set to 1, when this point arrives. You could use mpexpr instead if you need a better approximation of the very improbable part of the Poisson distribution.

Here is a test:

 # produce 10,000 random integer numbers according to the Poisson distribution:
 set data [RandomPoisson 3.5 10000]
 # count their frequencies: 
 foreach el $data {
        if {[info exists count($el)]} {
                incr count($el) 1
        } else {
                set count($el) 1
        }
 }
 # and display their frequencies:
 foreach el [lsort -integer [array names count]] {
        puts "$el => $count($el)"
 }

See also: Gaussian Distribution


Category Mathematics