def factor_max_marginalize(factor, var): """Marginalize over a list of variables by taking the max. Args: factor (Factor): Input factor var (List): Variable to marginalize out. Returns: out: Factor with variables in 'var' marginalized out. The factor's .val_argmax field should be a list of dictionary that keep track of the maximizing values of the marginalized variables. e.g. when out.val_argmax[i][j] = k, this means that when assignments of out is index_to_assignment[i], variable j has a maximizing value of k. See test_lab1.py::test_factor_max_marginalize() for an example. """ out = Factor() """ YOUR CODE HERE Marginalize out the variables given in var. You should make use of val_argmax to keep track of the location with the maximum probability. """ out.var = np.setxor1d(factor.var, np.array(var)) for out_var in out.var: index = np.where(factor.var == out_var) out.card = np.append(out.card, factor.card[index]) assignment = factor.get_all_assignments() index = [] out.val_argmax = [] for single_var in var: index.append(np.where(factor.var == single_var)) delete_assignment = np.delete(assignment, index, axis=1) out.val = np.zeros(np.prod(out.card)) for i in np.unique(delete_assignment, axis=0): index_set = np.array(np.where(np.all(i == delete_assignment, axis=1))) index_set_max_index = np.argmax(factor.val[index_set]) max_index_assignment = index_set[:, index_set_max_index][0] single_assignment = assignment_to_index(i, out.card) out.val[single_assignment] = factor.val[max_index_assignment] temp_dict = {} for single_var in var: index = np.argwhere(factor.var == single_var)[0][0] temp_dict[single_var] = assignment[max_index_assignment][index] out.val_argmax.append(temp_dict) return out