from graph.graph import Graph
import numpy as np

graph = Graph()

# add variable nodes
G = graph.add_var_node('Grade',2)
D = graph.add_var_node('Course Difficulty',2)
I = graph.add_var_node('Intelligence', 2)
# connecting factor
P_G_DI = np.array([[[0.5,0.1],[0.9,0.4]],[[0.5,0.9],[0.1,0.6]]])
graph.add_factor_node(P_G_DI, G, D, I)
# run sum-product and get marginals for variables
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']

# reset before altering graph further
graph.reset_all_messages()
################ UPON EXPLICIT CONDITIONING #############

# condition on variables
graph.vars['Intelligence'].condition(1)
graph.vars['Course Difficulty'].condition(0)
# Now compute all marginals using sum product
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']
G = graph.add_var_node(
    'Grade', 3)  # Grade on GPA scale - 0 - 1.5(0)/ 1.5 - 3(1)/3 - 4(2)
D = graph.add_var_node('Course Difficulty',
                       3)  # Easy(0)/ Moderate(1) / Hard(2)
I = graph.add_var_node('Intelligence',
                       3)  # Poor(0) / Average(1) / Exceptional(2)
R = graph.add_var_node('Recommondation Letter',
                       3)  # Bad(0) / Average(1) / Excellent(2)
S = graph.add_var_node('SAT Performance',
                       3)  # Poor(0)/ Average(1) / Excellent(1)

for iteration in range(0, 10):
    print 'Iteration :', iteration
    # Expectation Step - Initialize Grade using the sum-product algorithm using Bel-Prop
    # Form the factor graph from the present distribution
    graph.add_factor_node(P_DI_G, D, I, G)
    graph.add_factor_node(P_G_R, G, R)
    graph.add_factor_node(P_I_S, I, S)
    graph.add_factor_node(P_D, D)
    graph.add_factor_node(P_I, I)
    # Now the hidden value is Grade
    map_DI_G = {}
    map_DI = {}
    map_R_G = {}
    map_G = {}
    index = 0
    G_val = []
    log_likelihood = 0
    for d,i,s,r in zip(data_frame['D'].values, data_frame['I'].values, \
                    data_frame['S'].values,data_frame['R'].values):
        if (index % 100 == 0):
######################## Initialize the Factor Graph ######################
graph = Graph()

# add variable nodes
G = graph.add_var_node('Grade',3) # Grade on GPA scale - 0 - 1.5(0)/ 1.5 - 3(1)/3 - 4(2)
D = graph.add_var_node('Course Difficulty',3) # Easy(0)/ Moderate(1) / Hard(2)
I = graph.add_var_node('Intelligence', 3) # Poor(0) / Average(1) / Exceptional(2)
R = graph.add_var_node('Recommondation Letter', 3) # Bad(0) / Average(1) / Excellent(2)
S = graph.add_var_node('SAT Performance', 3) # Poor(0)/ Average(1) / Excellent(1)

for iteration in range(0,10):
    print 'Iteration :', iteration
    # Expectation Step - Initialize Grade using the sum-product algorithm using Bel-Prop
    # Form the factor graph from the present distribution
    graph.add_factor_node(P_DI_G, D, I, G)
    graph.add_factor_node(P_G_R, G, R)
    graph.add_factor_node(P_I_S, I, S)
    graph.add_factor_node(P_D, D)
    graph.add_factor_node(P_I, I)
    # Now the hidden value is Grade
    map_DI_G = {}
    map_DI = {}
    map_R_G = {}
    map_G = {}
    index = 0
    G_val = []
    log_likelihood = 0
    for d,i,s,r in zip(data_frame['D'].values, data_frame['I'].values, \
                    data_frame['S'].values,data_frame['R'].values):
        if(index % 100 == 0):
from graph.graph import Graph
import numpy as np

graph = Graph()

# add variable nodes
G = graph.add_var_node('Grade', 2)
D = graph.add_var_node('Course Difficulty', 2)
I = graph.add_var_node('Intelligence', 2)
# connecting factor
P_G_DI = np.array([[[0.5, 0.1], [0.9, 0.4]], [[0.5, 0.9], [0.1, 0.6]]])
graph.add_factor_node(P_G_DI, G, D, I)
# run sum-product and get marginals for variables
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']

# reset before altering graph further
graph.reset_all_messages()
################ UPON EXPLICIT CONDITIONING #############

# condition on variables
graph.vars['Intelligence'].condition(1)
graph.vars['Course Difficulty'].condition(0)
# Now compute all marginals using sum product
graph.compute_all_marginals()
marginal_dict = graph.get_all_marginals()
print 'distribution (Grade) :'
print marginal_dict['Grade']