7

I want to run a simulation that uses as parameter a value generated from a triangular probability distribution with lower limit A, mode B and and upper limit C. How can I generate this value in Python? Is there something as simple as expovariate(lambda) (from random) for this distribution or do I have to code this thing?

andandandand
  • 21,946
  • 60
  • 170
  • 271

3 Answers3

9

If you download the NumPy package, it has a function numpy.random.triangular(left, mode, right[, size]) that does exactly what you are looking for.

erik
  • 1,238
  • 3
  • 12
  • 23
6

Since, I was checking random's documentation from Python 2.4 I missed this:

random.triangular(low, high, mode)¶ Return a random floating point number N such that low <= N <= high and with the specified mode between those bounds. The low and high bounds default to zero and one. The mode argument defaults to the midpoint between the bounds, giving a symmetric distribution. New in version 2.6.

andandandand
  • 21,946
  • 60
  • 170
  • 271
  • This is probably a better answer than the accepted one for most use cases. It's kind of annoying that the API has a different order to the NumPy one though! – Jamie Bull Apr 04 '16 at 15:51
3

Let's say that your distribution wasn't handled by NumPy or the Python Standard Library.

In situations where performance is not very important, rejection sampling is a useful hack for getting draws from a distribution you don't have using one you do have.

For your triangular distribution, you could do something like

from random import random, uniform

def random_triangular(low, high, mode):
    while True:
        proposal = uniform(low, high)
        if proposal < mode:
            acceptance_prob = (proposal - low) / (mode - low)
        else:
            acceptance_prob = (high - proposal) / (high - mode)
        if random() < acceptance_prob: break
    return proposal

You can plot some samples

pylab.hist([random_triangular(1, 6, 5) for t in range(10000)])

to make sure that everything looks okay.

othercriteria
  • 431
  • 2
  • 4
  • Nice general purpose hinting! for OP, idea here is relating the uniform to the density of the desired distribution. – Gregg Lind Jan 01 '12 at 20:49