-->

Friday, 25 October 2013

Ipython Notebook Playing with Probability

In [2]:
%pylab inline
%autocall
from matplotlib import mpl,pyplot,colors
import numpy as np
import itertools
Populating the interactive namespace from numpy and matplotlib
Automatic calling is: Smart

The next cell imports the or and and operators. We then give these more convenient names for when we call them in the future.
In [3]:
import operator

OR = operator.__or__
AND =operator.__and__
In [4]:
# list
class Prob(object):
    def __init__(self, vals):
        self.vals = vals
        
    def values(self):
        return self.vals
    
    def size(self):
        return len(self.vals)
    
    @staticmethod
    def function(string):
        def f(x):
            return eval (string)
        return f
    
    

def combs(a,b):
    """returns all combinations of two probability objects"""
    return list(itertools.product(*[a.values(),b.values()]))   
        
    
class Dice(Prob):
    def __init__(self, sides = 6):
        Prob.__init__(self, arange(1,sides+1))
    
    # check if a value is odd
    @staticmethod
    def odd():
        def isOdd(n):
            return n % 2 == 1
        return isOdd
    
    # check if a value is even
    @staticmethod
    def even():
        def isEven(n):
            return n % 2 == 0
        return isEven
    
    
        
        
class Coin(Prob):
    vals = ['Heads', 'Tails']
    def __init__(self):
        Prob.__init__(self,Coin.vals)
    
    # check if a coin came up 'Heads'
    @staticmethod
    def heads():
        def isHead(side):
            return side == 'Heads'
        return isHead
    
    # check if a coin came up 'Tails'
    @staticmethod   
    def tails():
        def isTail(side):
            return side == 'Tails'
        return isTail
            

def evaluate(t1,t2, op):
    # get all combinations of the probability objects
    each = combs(t1[0], t2[0])
    
    # turns true or false into +/-5 for Colour Map
    def g(x):
        if x:
            return 5 
        else:
            return -5
    
    # run the rules on the elements of each and use op to combine them
    bools = [op(t1[1](element[0]) , t2[1](element[1])) for element in each]
    
    # use g to convert to number
    # convert list to numpy array so it can be reshaped
    zvals = np.array([g(boolean) for boolean in bools])
    
    return zvals.reshape(t1[0].size(), t2[0].size())
In [5]:
def show(a,b,op):
    zvals = evaluate(a,b,op)
    plot(a[0],b[0], zvals)
    
def compare(d1, d2, rule):
        c = combs(d1, d2) 
        print [(x,y, eval(rule)) for x,y in c]
        
        
        def g(x):
            if x:
                return 5 
            else:
                return -5
            
        zvals = np.array([g(eval(rule)) for x,y in c]).reshape(d1.size(), d2.size())
        
        plot(d1,d2, zvals)
    


def plot(p2,p1,zvals):
    fig, ax = pyplot.subplots()
    
    # make a color map of fixed colors
    cmap = mpl.colors.ListedColormap(['blue','red'])
    bounds=[2,6,2,6]
    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)


    # tell imshow about color map so that only set colors are used
    img = pyplot.pcolormesh(zvals, cmap = cmap,norm=norm)

    #pyplot.grid(b=True, which='major', color='black', linestyle='-')
    
    m = max(p1.size(), p2.size())

    pyplot.axis([0,m,0,m])
    
    
    ax.tick_params(axis='x',which='minor',bottom='off') 
    ax.tick_params(axis='y',which='minor',bottom='off')  
   
    
    px = p1.size()
    xlocations = np.array(range(px))
    xminorlocations = np.array(range(px))+0.5
    
    py = p2.size()
    ylocations = np.array(range(py))
    yminorlocations = np.array(range(py))+0.5
    
    pyplot.xticks(xminorlocations, p1.values(), rotation=0, size=15)
    ax.set_xticks(xlocations, minor=True)
    
    pyplot.yticks(yminorlocations, p2.values(), rotation=0, size=15)
    ax.set_yticks(ylocations, minor=True)
    grid(True, which='minor', linestyle='-')

    pyplot.show()
    
    
    

Creating Our Probability Objects

A coin or dice can be created by calling Coin() or Dice() respectively. A different-sided dice can be created by pass ing a number to Dice(). Here we will create a 12-sided dice.
In [6]:
d = Dice()
d12 = Dice(12)
c = Coin()

Creating (Probability Object, Rule) 2-Tuples




An n-tuple is similar to a list with n objects in it. We are going to create 2-tuples so we can pair a Probability Object with a rule for evaluating it.
In [7]:
c = Coin() # created in above cell
head_rule = c.heads()

print "Heads is", head_rule('Heads')
print "Tails is", head_rule('Tails')

t = (c, head_rule)
Heads is True
Tails is False

For dice we call Dice.function and pass it a string such as 'x < 3'.
We can use '<', '<=', '>', '>=', '=', and '!='. The last meaning not equal.
To use specific numbers we could pass 'x in [1,4]' or alternatively to avoid those numbers we could use 'x not in [1,4]'
In [8]:
r = Dice.function('x not in [1,4]')

print "One is", r(1)
print "Two is", r(2)
One is False
Two is True

Getting Combinations

We can use combs(a,b) to get all the combinations of two probability objects.
In [9]:
# Coin and Coin
combs(Coin(),Coin())
Out[9]:
[('Heads', 'Heads'),
 ('Heads', 'Tails'),
 ('Tails', 'Heads'),
 ('Tails', 'Tails')]
In [10]:
# Coin and Dice
combs(Coin(), Dice())
Out[10]:
[('Heads', 1),
 ('Heads', 2),
 ('Heads', 3),
 ('Heads', 4),
 ('Heads', 5),
 ('Heads', 6),
 ('Tails', 1),
 ('Tails', 2),
 ('Tails', 3),
 ('Tails', 4),
 ('Tails', 5),
 ('Tails', 6)]
In [11]:
# D4 and D6
combs(Dice(4), Dice(6))
Out[11]:
[(1, 1),
 (1, 2),
 (1, 3),
 (1, 4),
 (1, 5),
 (1, 6),
 (2, 1),
 (2, 2),
 (2, 3),
 (2, 4),
 (2, 5),
 (2, 6),
 (3, 1),
 (3, 2),
 (3, 3),
 (3, 4),
 (3, 5),
 (3, 6),
 (4, 1),
 (4, 2),
 (4, 3),
 (4, 4),
 (4, 5),
 (4, 6)]

Visualise It

First we need to ste up some tuples. Then we call show(a,b, operation) to see the chart.
Remember that operation can be AND or OR
In [12]:
t1 = (d, Dice.function('x<3'))
t2 = (c, Coin.heads())
t3 = (d, Dice.odd())
t4 =(d12, Dice.odd())

show(t1,t2, OR)
In [13]:
show(t1,t2, AND)
In [14]:
# D6 odd or D12 odd
show(t3,t4,OR)
In [15]:
# D6 odd and D12 odd
show(t3,t4,AND)

Comparing Probability Objects

The compare method takes two probability objects and a mathematical statement involving x and y
I will produce the following:
  • The sum of x and y is not 3 or 4
  • x times y is divisible by 3
  • The sum of x andy is greather than 4 but less than or eaual to 8
  • x is more than one smaller than y
In [16]:
compare(Dice(),Dice(),'x+y not in [3,4] ')
[(1, 1, True), (1, 2, False), (1, 3, False), (1, 4, True), (1, 5, True), (1, 6, True), (2, 1, False), (2, 2, False), (2, 3, True), (2, 4, True), (2, 5, True), (2, 6, True), (3, 1, False), (3, 2, True), (3, 3, True), (3, 4, True), (3, 5, True), (3, 6, True), (4, 1, True), (4, 2, True), (4, 3, True), (4, 4, True), (4, 5, True), (4, 6, True), (5, 1, True), (5, 2, True), (5, 3, True), (5, 4, True), (5, 5, True), (5, 6, True), (6, 1, True), (6, 2, True), (6, 3, True), (6, 4, True), (6, 5, True), (6, 6, True)]

In [17]:
compare(Dice(),Dice(),'x*y % 3 == 0')
[(1, 1, False), (1, 2, False), (1, 3, True), (1, 4, False), (1, 5, False), (1, 6, True), (2, 1, False), (2, 2, False), (2, 3, True), (2, 4, False), (2, 5, False), (2, 6, True), (3, 1, True), (3, 2, True), (3, 3, True), (3, 4, True), (3, 5, True), (3, 6, True), (4, 1, False), (4, 2, False), (4, 3, True), (4, 4, False), (4, 5, False), (4, 6, True), (5, 1, False), (5, 2, False), (5, 3, True), (5, 4, False), (5, 5, False), (5, 6, True), (6, 1, True), (6, 2, True), (6, 3, True), (6, 4, True), (6, 5, True), (6, 6, True)]

In [19]:
compare(Dice(),Dice(),' 4 < x+y <= 8  ')
[(1, 1, False), (1, 2, False), (1, 3, False), (1, 4, True), (1, 5, True), (1, 6, True), (2, 1, False), (2, 2, False), (2, 3, True), (2, 4, True), (2, 5, True), (2, 6, True), (3, 1, False), (3, 2, True), (3, 3, True), (3, 4, True), (3, 5, True), (3, 6, False), (4, 1, True), (4, 2, True), (4, 3, True), (4, 4, True), (4, 5, False), (4, 6, False), (5, 1, True), (5, 2, True), (5, 3, True), (5, 4, False), (5, 5, False), (5, 6, False), (6, 1, True), (6, 2, True), (6, 3, False), (6, 4, False), (6, 5, False), (6, 6, False)]

In [21]:
compare(Dice(),Dice(),'x+1 <y')
[(1, 1, False), (1, 2, False), (1, 3, True), (1, 4, True), (1, 5, True), (1, 6, True), (2, 1, False), (2, 2, False), (2, 3, False), (2, 4, True), (2, 5, True), (2, 6, True), (3, 1, False), (3, 2, False), (3, 3, False), (3, 4, False), (3, 5, True), (3, 6, True), (4, 1, False), (4, 2, False), (4, 3, False), (4, 4, False), (4, 5, False), (4, 6, True), (5, 1, False), (5, 2, False), (5, 3, False), (5, 4, False), (5, 5, False), (5, 6, False), (6, 1, False), (6, 2, False), (6, 3, False), (6, 4, False), (6, 5, False), (6, 6, False)]

Arrow Key Nav