def factor_sum(A, B): """Same as factor_product, but sums instead of multiplies """ if A.is_empty(): return B if B.is_empty(): return A # Create output factor. Variables should be the union between of the # variables contained in the two input factors out = Factor() out.var = np.union1d(A.var, B.var) # Compute mapping between the variable ordering between the two factors # and the output to set the cardinality out.card = np.zeros(len(out.var), np.int64) mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1) mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1) out.card[mapA] = A.card out.card[mapB] = B.card # For each assignment in the output, compute which row of the input factors # it comes from out.val = np.zeros(np.prod(out.card)) assignments = out.get_all_assignments() idxA = assignment_to_index(assignments[:, mapA], A.card) idxB = assignment_to_index(assignments[:, mapB], B.card) """ YOUR CODE HERE You should populate the .val field with the factor sum. The code for this should be very similar to the factor_product(). """ out.val = A.val[idxA] + B.val[idxB] return out
def factor_product(A, B): """Compute product of two factors. Suppose A = phi(X_1, X_2), B = phi(X_2, X_3), the function should return phi(X_1, X_2, X_3) """ if A.is_empty(): return B if B.is_empty(): return A # Create output factor. Variables should be the union between of the # variables contained in the two input factors out = Factor() out.var = np.union1d(A.var, B.var) # Compute mapping between the variable ordering between the two factors # and the output to set the cardinality out.card = np.zeros(len(out.var), np.int64) mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1) mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1) out.card[mapA] = A.card out.card[mapB] = B.card # For each assignment in the output, compute which row of the input factors # it comes from out.val = np.zeros(np.prod(out.card)) assignments = out.get_all_assignments() idxA = assignment_to_index(assignments[:, mapA], A.card) idxB = assignment_to_index(assignments[:, mapB], B.card) out.val = A.val[idxA] * B.val[idxB] """ YOUR CODE HERE You should populate the .val field with the factor product Hint: The code for this function should be very short (~1 line). Try to understand what the above lines are doing, in order to implement subsequent parts. """ return out
def factor_product(A, B): """ Computes the factor product of A and B e.g. A = f(x1, x2); B = f(x1, x3); out=f(x1, x2, x3) = f(x1, x2)f(x1, x3) Args: A: first Factor B: second Factor Returns: Returns the factor product of A and B """ out = Factor() """ YOUR CODE HERE, HINT: copy from lab2 part 1! """ if A.is_empty(): return B if B.is_empty(): return A out = Factor() # Set the variables of the output out.var = np.union1d(A.var, B.var) # Set the cardinality of the output out.card = np.zeros(len(out.var), np.int64) mapA = np.argmax(out.var[None, :] == A.var[:, None], axis=-1) mapB = np.argmax(out.var[None, :] == B.var[:, None], axis=-1) out.card[mapA] = A.card out.card[mapB] = B.card # Initialize the factor values to zero out.val = np.zeros(np.prod(out.card)) assignments = out.get_all_assignments() idxA = assignment_to_index(assignments[:, mapA], A.card) idxB = assignment_to_index(assignments[:, mapB], B.card) # Populate the factor values out.val = A.val[idxA] * B.val[idxB] """ END YOUR CODE HERE """ return out