def sum_out(var, factors): new_factor_list = [] for f in factors: if var in f.variables: new_variables = list(f.variables) new_variables.remove(var) name = '' for v in new_variables: name += v.name new_f = Factor(name,new_variables) new_f.phi = np.zeros((0,)) # DIRECTIONS # Must check that the other x assignments match, then add together v_index = f.variables.index(var) # WE NEED A MORE CREATIVE WAY TO DO THIS # IS INDEX TO ASSIGNMENT ACTUALLY WORKING?? for i in range(0, len(f.phi)): assignment1 = list(f.index_to_assignment(i)) #print 'assignment 1: ' + str(assignment1) is_sum = False next_sum = f.phi[i] for j in range(i, len(f.phi)): assignment2 = list(f.index_to_assignment(j)) summable = True #print'assignment 2: ' + str(assignment2) for k in range(0, len(assignment2)): idx2 = assignment2[k] idx1 = assignment1[k] #print assignment1, assignment2 if k == v_index: #print k, idx1, idx2 if idx2 == idx1: #print 'not summable, a1[k] == a2[k]' summable = False break if k != v_index: #print 'NOT', k, idx1, idx2 if idx2 != idx1: #print 'not summable, a1[k] != a2[k]' summable = False break if summable == True: is_sum = True next_sum += f.phi[j] if is_sum == True: new_f.phi = np.append(new_f.phi, next_sum) new_factor_list.append(new_f) #can't sum this factor out on this variable else: new_factor_list.append(f) return new_factor_list
def instantiate(var, factors): new_factor_list = [] for f in factors: if var in f.variables: new_variables = list(f.variables) new_variables.remove(var) name = '' for v in new_variables: name += v.name new_f = Factor(name,new_variables) new_f.phi = np.zeros((0,)) v_index = f.variables.index(var) for i in range(0, len(f.phi)): assignment = f.index_to_assignment(i) if assignment[v_index] == var.value: # print f.phi[i] new_f.phi = np.append(new_f.phi, f.phi[i]) new_factor_list.append(new_f) else: new_factor_list.append(f) return new_factor_list
def factorProduct(f1, f2, mnCards): """ Multiply two factors by finding same variable assignments and multiplying their phi together. """ # Get the unique variables across both factors uniqueVars = f2.variables[:] for i in range(len(f1.variables)): if f1.variables[i] not in uniqueVars: uniqueVars.insert(0, f1.variables[i]) # Create the new product factor factor = Factor(uniqueVars) for i in range(len(factor.variables)): factor.setCard(i, mnCards[factor.variables[i]]) factor.calculateStrides() j, k = 0, 0 psi = [] assignment = [0 for i in range(len(factor.variables))] factorSize = 1 # Size of new factor will be product of each variable's cardinality for i in range(len(factor.card)): factorSize *= factor.card[i] for i in range(factorSize): if debug: print "multiplying", j, k, f1.phi[j], f2.phi[k] psi.append(f1.phi[j] * f2.phi[k]) # Loop from last to first since values are 000, 001, 010, 011 instead of 000, 100, 010, 110 for v in range(len(factor.variables)-1,-1,-1): curVariable = factor.variables[v] assignment[v] += 1 if assignment[v] == factor.card[v]: assignment[v] = 0 if curVariable in f1.variables: j = j - (factor.card[v] - 1) * f1.stride[f1.variables.index(curVariable)] if curVariable in f2.variables: k = k - (factor.card[v] - 1) * f2.stride[f2.variables.index(curVariable)] else: if curVariable in f1.variables: j = j + f1.stride[f1.variables.index(curVariable)] if curVariable in f2.variables: k = k + f2.stride[f2.variables.index(curVariable)] break factor.phi = psi[:] return factor
def readFunctionTables(mnCards, mnCliques): """ Reads function tables defined in the input file """ mnFactors = [] factorIndex, factorNum = 0, 0 fClass = Factor(mnCliques[factorIndex]) for i in range(len(fClass.variables)): fClass.setCard(i, mnCards[fClass.variables[i]]) fClass.calculateStrides() factor = [] done = False while not done: inputRow = inFile.readline().strip() if inputRow == "": continue else: if " " in inputRow: splitRow = inputRow.split() if factorNum == 0: factorNum = int(splitRow[0]) for i in range(1, len(splitRow)): factor.append(float(splitRow[i])) else: for i in range(len(splitRow)): factor.append(float(splitRow[i])) if factorNum == len(factor): factorNum = 0 fClass.phi = factor mnFactors.append(fClass) factor = [] factorIndex += 1 if factorIndex < len(mnCliques): fClass = Factor(mnCliques[factorIndex]) for i in range(len(fClass.variables)): fClass.setCard(i, mnCards[fClass.variables[i]]) fClass.calculateStrides() else: factorNum = int(inputRow) if len(mnFactors) >= len(mnCliques): # We have read in all the cliques so break out of while loop done = True return mnFactors
def readFunctionTables(): """ Reads function tables defined in the input file """ global mnFactors mnFactors = [] factorIndex, factorNum = 0, 0 fClass = Factor(mnCliques[factorIndex], mnCards) factor = [] done = False while not done: inputRow = inFile.readline().strip() if inputRow == "": continue else: if " " in inputRow: splitRow = inputRow.split() if factorNum == 0: factorNum = int(splitRow[0]) for i in range(1, len(splitRow)): factor.append(float(splitRow[i])) else: for i in range(len(splitRow)): factor.append(float(splitRow[i])) if factorNum == len(factor): # Reset for next factor factorNum = 0 fClass.phi = factor mnFactors.append(fClass) factor = [] factorIndex += 1 if factorIndex < len(mnCliques): fClass = Factor(mnCliques[factorIndex], mnCards) else: factorNum = int(inputRow) if len(mnFactors) >= len(mnCliques): # All cliques have been read so break out of while loop done = True if debug: for i in range(len(mnFactors)): mnFactors[i].printF()
def sumOutVariable(factor, variable): """ Sum out a variable for variable elimination """ if debug: print "eliminating factor" newVars = [x for x in factor.variables if x != variable] if debug: print "new vars: ", newVars newF = Factor(newVars, mnCards) if len(newVars) > 0: varIndex = factor.variables.index(variable) if debug: print "var index: ", varIndex newF.printF() usedVar = [False for x in range(factor.size)] if debug: print "used var: ", usedVar print "stride: ", factor.stride[varIndex], ", card: ", factor.card[varIndex] psi = [] for i in range(newF.size): psi.append(0) start = 0 for k in range(factor.size): if usedVar[k] == False: start = k break for j in range(factor.card[varIndex]): if debug: print "start: ", start, " stride: ", factor.stride[varIndex], " j: ", j psi[i] += factor.phi[start + factor.stride[varIndex] * j] usedVar[start + factor.stride[varIndex] * j] = True if debug: print "psi: ", i, " ", psi[i] newF.phi = psi[:] return newF