#A & B are two events occured in sample space S, where P(A) & P(B) are their corresponding probability
P_S = 1
#Given A&B are not mutually exclusive events, 
#Probability of A is 0.2  =  P_A
#Probability of B is 0.4  =  P_B
#Probability of either A or B is 0.5  =  P_AUB
P_A  =  0.2
P_B  =   0.4
P_AUB  =  0.5
#Probability of both of A&B jointly occur is P_AinterB  =  P_A+P_B-P_AUB where inter is intersection
P_AinterB  =  P_A+P_B-P_AUB
print 'Probability of both of A&B jointly occur is ',(P_AinterB)
#Probability of none of AorB are occur is P_NOAB  =  Total occurence(P_S) - Probability of either AorB(P_AUB)
P_NOAB  =  P_S-P_AUB
print 'Probability of none of AorB are occur is ',(P_NOAB)
#Probability that A will occur if B has already occurred(P_AB)  =  ratio of Probability of joint occurence of  A&B (P_A_B) & Probability of B(P_B)
#P_A_B(robability of joint occurence)  =  Probability that A&B both occur(P_AinterB)
#From given values P_AinterB  =  0.1 implies P_A_B  =  0.1 & P_B  =  0.4
P_AinterB  =  0.1
P_A_B  =  P_AinterB 
P_B  =  0.4
P_AB  =  P_A_B/P_B
#Similarly
#Probability that B will occur if A has already occurred(P_BA)  =  ratio of Probability of joint occurence of  A&B (P_A_B) & Probability of B(P_A)
#From given values P_A  =  0.2
P_A  =  0.2
P_BA  =  P_A_B/P_A
#Bayes theorem says that P_AB  =  (P_A/P_B)*P_BA
#After Calculating LHS & RHS if both are equal then bayes theorem is satisfying
#Calculating LHS
LHS  =  P_AB
#Calculating RHS
RHS  =  (P_A/P_B)*P_BA
print 'P(A/B)  =  ',(P_AB);
if LHS  ==  RHS:
    print ('LHS  =  RHS, Hence Bayes theorem is verified' );
#Given, The probability that m0 is sent is 0.7  =  P_m0
P_m0  =  0.7
#The probability that m0 is sent is 0.3  =  P_m1
P_m1  =  0.3
#The probability that r0 is received given that m0 is sent is 0.9  =  P_r0m0 where r is voltage & m is message
P_r0m0  =  0.9
#the probability that r1 is received given that m0 is sent is 0.1  =  P_r1m0 where r is voltage & m is message
P_r1m0  =  0.1
#The probability that r1 is received given that m1 is sent is 0.6  =  P_r1m1
P_r1m1  =  0.6
#the probability that r0 is received given that m1 is sent is 0.4  =  P_r0m1 where r is voltage & m is message
P_r0m1  =  0.4
#With the given values check eqations P_r0m0*P_m0(P00) > P_r0m1*P_m1(P01)
P00  =  P_r0m0*P_m0
P01  =  P_r0m1*P_m1
if P00>P01:
    print ('as P(r0|m0)*P(m0) > P(r0|m1)*P(m1) is valid, we whould select m0 whenever r0 is received')
#With the given values check eqations P_r1m1*P_m1(P11) > P_r1m0*P_m0(P10)
P11  =  P_r1m1*P_m1
P10  =  P_r1m0*P_m0
if P11>P10:
    print ('as P(r1|m1)*P(m1) > P(r1|m0)*P(m0) is valid, we whould select m1 whenever r1 is received')
#Given, the probability that r0 is received given that m0 is sent is 0.9  =  P_r0m0 where r is voltage & m is message
P_r0m0  =  0.9
#The probability that m0 is sent is 0.7  =  P_m0
P_m0  =  0.7
#The probability that r1 is received given that m1 is sent is 0.6  =  P_r1m1
P_r1m1  =  0.6
#The probability that m0 is sent is 0.3  =  P_m1
P_m1  =  0.3
#The probability that the transmitted signal is correctly read at receiver is P(c)(P_c)  =  the probability that m0 was sent when r0 was read(P_r0m0*P_m0) + the probability that m1 was sent when r1 was read(P_r1m1*P_m1)
P_c  =  P_r0m0*P_m0+P_r1m1*P_m1
#P(e)(P_e)  =  1-P(c)
P_e  =  1-P_c
print 'P(e)  =  ',P_e
print 'P(c)  =  ',P_c
#Here P(ra|mb) is denoted as P_ramb where a is 0,1,2 & b is 0,1
#P(X) is denoted as P_X where X is m0, m1, C & E
#From given values P_m0  =  0.6, P_m1  =  0.4, P_r0m0  = 0.6, P_r1m1  =  0.7, P_r0m1  =  0, P_r1m0  =  0.2, P_r2m0  =  0.2 & P_r2m1  =  0.3
P_m0  =  0.6
P_m1  =  0.4
P_r0m0  = 0.6
P_r1m1  =  0.7
P_r0m1  =  0
P_r1m0  =  0.2
P_r2m0  =  0.2
P_r2m1  =  0.3
#(a)
#Comaparing P(r0|m0)*P(m0) & P(r0|m1)*P(m1) gives result
LHS  =  P_r0m0*P_m0
RHS  =  P_r0m1*P_m1
print 'As P(r0|m0)*P(m0)[',LHS,'] > P(r0|m1)*P(m1)[',RHS,']'
print ('we select m0 whenever r0 is received')
#Similarly compare P(r1|m1)*P(m1) & P(r1|m0)*P(m0)
LHS  =  P_r1m1*P_m1
RHS  =  P_r1m0*P_m0
print 'As P(r1|m1)*P(m1)[',LHS,'] > P(r1|m0)*P(m0)[',RHS,']'
print ('we select m1 whenever r1 is received')
#compare P(r2|m0)*P(m0) & P(r2|m1)*P(m1)
LHS  =  P_r2m0*P_m0
RHS  =  P_r2m1*P_m1
print 'As P(r2|m0)*P(m0)[',LHS,']  =  P(r2|m1)*P(m1)[',RHS,']'
print ('We can accordingly make either assignment and we arbitrarily associate r2 with m0')
#(b)
#The probability of being correct is P(C)  =  P(r0|m0)*P(m0)+P(r1|m1)*P(m1)+P(r2|m0)*P(m0)
P_C  =  P_r0m0*P_m0+P_r1m1*P_m1+P_r2m0*P_m0
#The probability of error is P(E)  =  1-P(C)
P_E  =  1 - P_C;
print 'Probability of being correct is P(C)  =  ',(P_C)
print 'Probability of error is P(E)  =  ',(P_E)
import math 
from scipy.integrate import quad 
#Given, probability density function of X is fX_x where fX_x  =  a*e**(-0.2*x) for x greater than & equal to 0 &  =  0 eleswhere
#a  =  fX_x/(a*e**(-0.2*x))
#from definition integration of fX_x with limits -infinity to +infinity is 1
#As per given fX_x, integration of a*e**(-0.2*x) with limits 0 & +inffinity and obtained value be P
#a  =  1/p
def f7(x): 
	 return math.e**(-0.2*x)
P  =   quad(f7,0,100)[0]
a  =  1./P
print 'a  =  ',round(a,4)
import math 
#We know that, Probabilty of error(P_error) for the signal correpted by Gaussian channel variance sigma**2 where signal having voltage levels as 0&V is (1/2)*erfc(V/(2*math.sqrt(2)*sigma))
#P_error for V  =  4 & sigma**2  = 2
V  =  4
sigma  =  math.sqrt(2)
P_error  =  (1./2)*math.erfc(V/(2*math.sqrt(2)*sigma))
print 'Probabilty of error for V  =  4 & sigma**2  = 2 is %.4f'%P_error
#P_error for V  =  2 & sigma**2  = 2
V  =  2
sigma  =  math.sqrt(2)
P_error  =  (1./2)*math.erfc(V/(2*math.sqrt(2)*sigma))
print 'Probabilty of error for V  =  2 & sigma**2  = 2 is %.4f'%P_error
#P_error for V  =  4 & sigma**2  = 4
V  =  4
sigma  =  math.sqrt(4)
P_error  =  (1./2)*math.erfc(V/(2*math.sqrt(2)*sigma))
print 'Probabilty of error for V  =  4 & sigma**2  = 4 is %.4f'%P_error
#P_error for V  =  8 & sigma**2  = 2
V  =  8
sigma  =  math.sqrt(2)
P_error  =  (1./2)*math.erfc(V/(2*math.sqrt(2)*sigma))
print 'Probabilty of error for V  =  8 & sigma**2  = 2 is %.4f'%P_error
import math 
#(a)
#out of n attempts the probability of message reaching correctly for k times is given by binomial distribution pX(k)  =  nCk*(q**k)*(1-q)**(n-k) where q is probability of correctly reaching
#Here n  =  10, k  =  1, q  =  0.001
n  =  10.
k  =  1.
q  =  0.001
#pX(k) is denoted as p_X_1
#10C1  = 10
p_X_1  =  10*(q**k)*(1-q)**(n-k)
print 'The probability that out of 10 transmissions 9 are corrent and 1 is incorrect is %.4f'%p_X_1
#probability that more than two erroneous out of 100 transmissions(p_100_2)  =  1-probability of less than or equal to two error in transmission
#p_100_2  =  1-pX(0)-pX(1)-pX(2)
#p_100_2  = 1-100C0*((0.001)**0)*((1-0.001)**100)-100C1*((0.001)**1)*((1-0.001)**99)-100C0*((0.001)**2)*((1-0.001)**98)
#Since, calculation of above is cumbersome we may use Poisson ditribution to approximate above
#Poisson distribution  =  pX(k)  =  (alfa**k)*(e**-alfa)/k!, where alfa  =  n*T
#Here n  =  100 & q  =  0.001
n  =  100
q  =  0.001
alfa  =  n*q
p_100_2  =  1-(alfa**0)*(math.e**-0.1)/math.factorial(0)-(alfa**1)*(math.e**-0.1)/math.factorial(1)-(alfa**2)*(math.e**-0.1)/math.factorial(2)
print 'probability that more than two erroneous out of 100 transmissions is %.4f'%p_100_2
#(c)
#from(b), required probability i.e probability of more than one are erroneous out of 100 transmission(p_100_1) is
p_100_1  =  1-(alfa**0)*(math.e**-0.1)/math.factorial(0)-(alfa**1)*(math.e**-0.1)/math.factorial(1)
print 'probability that more than one erroneous out of 100 transmissions is %.4f'%p_100_1
#Given, Error probability is 10**-4  =  P_e, no of ecperiments conducted  =  N  =  4*10**5 & estimated probability of error p does not differ from P_e by more than 50%
P_e  =  10.**-4
N  =  4.*10**5
#Tchebycheff's inequality is P(|p-Pe|> = E)< = P_e/(N*E**2)
#From given values we can find that E  =  50*10**-4
E  =  50.*10**-4
#Here R.H.S of Tchebycheff's inequality is denoted as Tc_RHS
Tc_RHS  =  P_e/(N*E**2)
#Tc_RHS in persentage is Tc_RHSper
Tc_RHSper  =  Tc_RHS/100
#print (Tc_RHSper,Tc_RHS,'or P(|p-10**-4|> = 0.5*10**-2)< = ',Tc_RHS,'The probability of estimated probability of error p does not differ from P_e by more than 50% is less than equal to')
#given solution has been computed wrong, obtaines solution is 10**-7
print 'The probability of estimated probability of error p does not differ from P_e by more \
\nthan 50% is less than equal to ',Tc_RHS,'or P(|p-10**-4|> = 0.5*10**-2)< = ',Tc_RHS,'  =  ',Tc_RHSper,'%'