def setup_factor_graph(self): self.vecfac = dai.VecFactor() elem_map = {} for elem in self.variable_map: if elem.variable_name not in elem_map: elem_map[elem.variable_name] = { elem.variable_type: elem.variable_id } else: elem_map[elem.variable_name][ elem.variable_type] = elem.variable_id #dai_var_map[elem.variable] = dai.Var(elem.variable, elem.dim) for cpt in sorted(self.cpt_map.keys(), key=lambda x: x.factor_id): cpt_value = self.cpt_map[cpt] var_list = dai.VarSet() v_list = list(cpt_value.variables) v_list.sort() for v_id in v_list: v = self.variable_map.get_variable_by_id(v_id) if v not in self.dai_variables: self.dai_variables[v] = dai.Var(v.variable_id, v.dim) var_list.append(self.dai_variables[v]) dai_factor = dai.Factor(var_list) for i, v in enumerate(cpt_value.cpt_linear_table()): dai_factor[i] = v self.vecfac.append(dai_factor)
def build_single_node_factor(variables, fixed_variables, var_idx, f): ''' copied from https://github.com/jkuck/mrf_nesting_ub/blob/master/Factor_Graphs/libdai_ising_model.py Inputs: - variables: (list of dai.Var) available variables. - fixed_variables: (dictionary) key: (int) 0 to N-1 variable index value: (int) -1 or 1, the value the variable is fixed to - var_idx: (int) variable index, 0 to N-1, for this factor's node - f: (float) local field at this node Outputs: - factor: (dai.Factor) ''' clause_variables = dai.VarSet(variables[var_idx]) factor = dai.Factor(clause_variables) if var_idx in fixed_variables: factor[0] = np.exp(fixed_variables[var_idx] * f) #the single fixed factor value else: factor[0] = np.exp(-f) #corresponding to the node taking value -1 factor[1] = np.exp(f) #corresponding to the node taking value 1 return factor
def build_libdaiFactor_fromClause(clause, variables): ''' Inputs: - clause (list of integers): literals in the clause - variables (list of dai.Var): list of all dai variables in the sat problem. variable i (where i can be in [1, N]) is stored at variables[i-1] Outputs: - factor (dai.Factor) ''' dai_vars_list = [variables[abs(literal) - 1] for literal in clause] if len(clause) == 1: dai_vars = dai.VarSet(dai_vars_list[0]) else: dai_vars = dai.VarSet(dai_vars_list[-1], dai_vars_list[-2]) #have to reverse the order of the variables because of the way libdai #stores factor potentials with respect to variable ordering # see https://github.com/dbtsai/libDAI/blob/master/swig/example_sprinkler.py for var in reversed(dai_vars_list[:-2]): dai_vars.append(var) factor = dai.Factor(dai_vars) #Create a tensor for the 2^state_dimensions states state = np.zeros([2 for i in range(len(clause))]) #Iterate over the 2^state_dimensions variable assignments and set those to 1 that satisfy the clause for indices in np.ndindex(state.shape): set_to_1 = False for dimension, index_val in enumerate(indices): if clause[dimension] > 0 and index_val == 1: set_to_1 = True elif clause[dimension] < 0 and index_val == 0: set_to_1 = True if set_to_1: state[indices] = 1 else: state[indices] = 0 for idx, state_val in enumerate(state.flatten()): factor[idx] = state_val return factor
def build_pairwise_factor(variables, fixed_variables, var_idx1, var_idx2, c): ''' copied from https://github.com/jkuck/mrf_nesting_ub/blob/master/Factor_Graphs/libdai_ising_model.py Inputs: - variables: (list of dai.Var) available variables. - fixed_variables: (dictionary) key: (int) 0 to N-1 variable index value: (int) -1 or 1, the value the variable is fixed to - var_idx1: (int) variable index, 0 to N-1, for the first node in this factor - var_idx2: (int) variable index, 0 to N-1, for the second node in this factor - c: (float) coupling strength for this factor Outputs: - factor: (dai.Factor) ''' clause_variables = dai.VarSet(variables[var_idx1], variables[var_idx2]) factor = dai.Factor(clause_variables) #this 'pairwise' factor is over two fixed variables and has only 1 state if (var_idx1 in fixed_variables) and (var_idx2 in fixed_variables): factor[0] = np.exp(fixed_variables[var_idx1] * fixed_variables[var_idx2] * c) #this 'pairwise' factor is over one fixed variable and one binary variable and has 2 states elif (var_idx1 in fixed_variables) and (var_idx2 not in fixed_variables): factor[0] = np.exp(-fixed_variables[var_idx1] * c) # V2 = -1 factor[1] = np.exp(fixed_variables[var_idx1] * c) # V2 = -1 #this 'pairwise' factor is over one fixed variable and one binary variable and has 2 states elif (var_idx1 not in fixed_variables) and (var_idx2 in fixed_variables): factor[0] = np.exp(-fixed_variables[var_idx2] * c) # V1 = -1 factor[1] = np.exp(fixed_variables[var_idx2] * c) # V1 = -1 #this pairwise factor is over two binary variables and has 4 states elif (var_idx1 not in fixed_variables) and (var_idx2 not in fixed_variables): factor[0] = np.exp(c) # V1 = -1, V2 = -1 factor[1] = np.exp(-c) # V1 = -1, V2 = 1 factor[2] = np.exp(-c) # V1 = 1, V2 = -1 factor[3] = np.exp(c) # V1 = 1, V2 = 1 else: assert (False), "This shouldn't happen!!?" return factor
# Copyright (C) 2009 Joris Mooij [joris dot mooij at libdai dot org] # This example program illustrates how to construct a factorgraph # by means of the sprinkler network example discussed at # http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html # using the SWIG python wrapper of libDAI import dai C = dai.Var(0, 2) # Define binary variable Cloudy (with label 0) S = dai.Var(1, 2) # Define binary variable Sprinkler (with label 1) R = dai.Var(2, 2) # Define binary variable Rain (with label 2) W = dai.Var(3, 2) # Define binary variable Wetgrass (with label 3) # Define probability distribution for C P_C = dai.Factor(C) P_C[0] = 0.5 # C = 0 P_C[1] = 0.5 # C = 1 # Define conditional probability of S given C P_S_given_C = dai.Factor(dai.VarSet(S, C)) P_S_given_C[0] = 0.5 # C = 0, S = 0 P_S_given_C[1] = 0.9 # C = 1, S = 0 P_S_given_C[2] = 0.5 # C = 0, S = 1 P_S_given_C[3] = 0.1 # C = 1, S = 1 # Define conditional probability of R given C P_R_given_C = dai.Factor(dai.VarSet(R, C)) P_R_given_C[0] = 0.8 # C = 0, R = 0 P_R_given_C[1] = 0.2 # C = 1, R = 0 P_R_given_C[2] = 0.2 # C = 0, R = 1