def test_self_factor_product(f1, f2): f = get_product(f1, f1) f = get_product(f, f1) f = get_product(f, f1) f = get_product(f, f1) assert np.allclose(f.scope, np.array([1])) assert np.allclose(f.card, np.array([2])) assert np.allclose(f.val, np.array([0.11**5, 0.89**5]))
def test_f1_f2_product_commuative(f1, f2): ''' f2 [2 1 phi] ------------ [0 0 0.59] [1 0 0.41] [0 1 0.22] [1 1 0.78] f1 [1 phi] --------- [0 0.11] [1 0.89] f1 * f2 [1 2 phi] ----------- [0 0 0.11 * 0.59] [1 0 0.89 * 0.22] [0 1 0.11 * 0.41] [1 1 0.89 * 0.78] ''' f = get_product(f2, f1) assert np.allclose(f.scope, np.array([1, 2])) assert np.allclose(f.card, np.array([2, 2])) assert np.allclose( f.val, np.array([0.11 * 0.59, 0.89 * 0.22, 0.11 * 0.41, 0.89 * 0.78]))
def test_f1_f2_product_log_space(f1, f2): f = get_product(log(f1), log(f2), use_log_space=True) f = exp(f) assert np.allclose(f.scope, np.array([1, 2])) assert np.allclose(f.card, np.array([2, 2])) assert np.allclose( f.val, np.array([0.11 * 0.59, 0.89 * 0.22, 0.11 * 0.41, 0.89 * 0.78]))
def test_another_marg(): f1 = Factor(scope=np.array([0]), card=np.array([2], dtype=np.int32), val=np.array([0.57, 0.43])) f2 = Factor(scope=np.array([1, 0]), card=np.array([2, 2], dtype=np.int32), val=np.array([0.4, 0.6, 0.13, 0.87])) f = get_product(f1, f2) f_marg = get_marg(f, 1) assert np.array_equal(f_marg.scope, np.array([0])) assert np.array_equal(f_marg.card, np.array([2])) assert np.allclose(f_marg.val, np.array([0.57, 0.43]))
def test_f2_f3_factor_product(f2, f3): ''' f2 [2 1 phi] ------------ [0 0 0.59] [1 0 0.41] [0 1 0.22] [1 1 0.78] f3 [3 2 phi] ------------ [0 0 0.39] [1 0 0.61] [0 1 0.06] [1 1 0.94] f2 * f3 [1 2 3 phi] -------------- [0 0 0 0.59 * 0.39] [1 0 0 0.22 * 0.39] [0 1 0 0.41 * 0.06] [1 1 0 0.78 * 0.06] [0 0 1 0.59 * 0.61] [1 0 1 0.22 * 0.61] [0 1 1 0.41 * 0.94] [1 1 1 0.78 * 0.94] ''' f = get_product(f2, f3) assert np.allclose(f.scope, np.array([1, 2, 3])) assert np.allclose(f.card, np.array([2, 2, 2])) assert np.allclose( f.val, np.array([ 0.59 * 0.39, 0.22 * 0.39, 0.41 * 0.06, 0.78 * 0.06, 0.59 * 0.61, 0.22 * 0.61, 0.41 * 0.94, 0.78 * 0.94 ]))
def test_f1_f3_product(f1, f3): ''' f1 [1 phi] --------- [0 0.11] [1 0.89] f3 [3 2 phi] ------------ [0 0 0.39] [1 0 0.61] [0 1 0.06] [1 1 0.94] f1 * f3 [1 2 3 phi] -------------- [0 0 0 0.11 * 0.39] [1 0 0 0.89 * 0.39] [0 1 0 0.11 * 0.06] [1 1 0 0.89 * 0.06] [1 0 1 0.11 * 0.61] [1 0 1 0.89 * 0.61] [1 1 1 0.11 * 0.94] [1 1 1 0.89 * 0.94] ''' f = get_product(f1, f3) assert np.allclose(f.scope, np.array([1, 2, 3])) assert np.allclose(f.card, np.array([2, 2, 2])) assert np.allclose( f.val, np.array([ 0.11 * 0.39, 0.89 * 0.39, 0.11 * 0.06, 0.89 * 0.06, 0.11 * 0.61, 0.89 * 0.61, 0.11 * 0.94, 0.89 * 0.94 ]))
def test_f3_f4_product(f3, f4): f = get_product(f3, f4) assert np.allclose(f.scope, np.array([2, 3, 4, 5])) assert np.allclose(f.card, np.array([2, 2, 2, 2]))
def get_clique_graph(elim_order, induced_graph, to_name): clique_graph = nx.Graph() factors = dict() f_count = 1 # Store factors in dictionary for name, dict_ in induced_graph.nodes_iter(data=True): factor = dict_['factor'] factor_scope = set([to_name[i] for i in factor.scope]) factors[f_count] = {'factor': factor, 'scope': factor_scope} f_count += 1 for node_name in elim_order: # Any previous messages that should be included # in this scope? (generated from other cliques) edges = [] clique_scope = set() for name, dict_ in clique_graph.nodes_iter(data=True): # Do not connect to used messages if dict_['msg_used']: continue if node_name in dict_['msg_scope']: clique_scope.update(dict_['msg_scope']) edges.append(name) dict_['msg_used'] = True # Find factors with node name # in scope fs = [] nodes_used = set() factor_names = factors.keys() for n in factor_names: if node_name in factors[n]['scope']: fs.append(factors[n]['factor']) nodes_used.add(n) del factors[n] factor = None if len(fs) > 0: factor = get_product_from_list(fs, use_log_space=True) factor_scope = set([to_name[i] for i in factor.scope]) clique_scope.update(factor_scope) msg_scope = clique_scope.copy() msg_scope.remove(node_name) attr_dict = {'scope': clique_scope, 'msg_scope': msg_scope, 'nodes_used': nodes_used, 'msg_used': False, 'factor': factor, 'msg_upward': [], 'msg_downward': [], 'belief': None, 'children': [], 'parent': None} clique_name = 'C' + str(len(clique_graph) + 1) clique_graph.add_node(n=clique_name, attr_dict=attr_dict) for e in edges: sepset = clique_graph.node[e]['scope'].intersection(clique_scope) d = {'sepset': sepset} clique_graph.add_edge(e, clique_name, d) # See if any cliques are isolated # if so, they had non-overlapping scopes # So we can place them into any clique isolated = [] C = None for name, dict_ in clique_graph.nodes_iter(data=True): if len(clique_graph.neighbors(name)) == 0: isolated.append(name) elif C is None: C = name for name in isolated: factor = clique_graph.node[name]['factor'] f = clique_graph.node[C]['factor'] s = clique_graph.node[C]['scope'] f = get_product(f, factor, use_log_space=True) clique_scope = set([to_name[i] for i in f.scope]) scope = clique_scope.update(s) clique_graph.node[C]['factor'] = f clique_graph.node[C]['scope'] = scope clique_graph.remove_node(name) # print("IS_CONNECTED: {0}".format(nx.is_connected(clique_graph))) return clique_graph