## A224
## Solution SXD

'''
With the notations of T0.10, let PY be list of probabilities of the events Yj 
(the hypotheses) and L the list of the probabilities P(X|Yj) (the likelihoods of X). 
Define a function that yields the list of condicional probabilities P(Yj|X) 
taking PY and L as inputs.
'''

# We assume that PY and L are lists of positive numbers of the same length
def list_bayes(PY, L):
    q = [p*l for p, l in zip(PY, L)]
    s = sum(q)
    return [t/s for t in q]
    
    
'''
If X is itself a list of events Xi and L is the matrix of likelihoods P(Xi|Yj), 
write a function that gives the matrix of conditional probablilities P(Yj|Xi) 
taking PY and L as inputs.
'''
# We assume that L is a matrix of positive numbers whose rows have
# the same length as PY
def matrix_bayes(PY, LL): return [list_bayes(PY,L) for L in LL]
    
    
## Tests

# 1) list_bayes
print("Test list_bayes")
# Let us use the setup of the coin exercise on T0.11.
# Prior probabililites:
PY = 3*[1/3]

# likelihoods of 3 heads
L = [(1/2)**3,(1/2)**3,(2/3)**3]

# posterior probabilities after observing HHH
Q = list_bayes(PY,L)
print('Posterior probabililitis after observing HHH:\n', round(Q,3))

# 2) matrix_bayes
print("\nTest matrix_bayes")

# likelihoods of n heads, n = 1,...,5
LL = [[(1/2)**n,(1/2)**n,(2/3)**n] for n in range(1,6)]

# We can now tabulate the posterior probabilities of having
# chosen each of the three coins after having observed
# n heads, n = 1,...,5

Q = matrix_bayes(PY,LL)
print('Posterior probabililitis after observing n heads, n = 1,...,5:\n')
for L in Q: print(round(L,3))

print('\n',[sum(L) for L in Q])
