def test_get_dfs_result(): model = PairWiseFiniteModel(4, 2) j = np.ones((2, 2)) model.add_interaction(2, 3, j) model.add_interaction(2, 1, j) model.get_dfs_result() # To test cache invalidation. model.add_interaction(1, 0, j) dfs_edges = model.get_dfs_result().dfs_edges assert np.allclose(dfs_edges, np.array([[0, 1], [1, 2], [2, 3]]))
def max_likelihood_tree_dp(model: PairWiseFiniteModel): """Max Likelihood for the pairwise model. Performs dynamic programming on tree. Applicable only if the interaction graph is a tree or a forest. Otherwise throws exception. :param model: Model for which to find most likely state. :return: Most likely state. np.array of ints. """ assert not model.get_dfs_result().had_cycles, "Graph has cycles." field = model.field.astype(np.float64, copy=False) dfs_edges = model.get_dfs_result().dfs_edges ints = model.get_interactions_for_edges(dfs_edges) return _max_likelihood_internal(field, dfs_edges, ints)
def infer_tree_dp(model: PairWiseFiniteModel, subtree_mp=False) -> InferenceResult: """Inference using DP on tree. Performs dynamic programming on tree. Applicable only if the interaction graph is a tree or a forest. Otherwise throws exception. :param model: Model for which to perform inference. :param subtree_mp: If true, will return marginal probabilities for subtrees, i.e. for each node will return probability of it having different values if we leave only it and its subtree. :return: InferenceResult object. """ assert not model.get_dfs_result().had_cycles, "Graph has cycles." dfs_edges = model.get_dfs_result().dfs_edges dfs_j = model.get_interactions_for_edges(dfs_edges) lz = model.field.astype(dtype=np.float64, copy=True) # log(z) lzc = np.zeros_like(lz) # log(zc) # Log(z_r). z_r is partition function for all tree except subtree of given # vertex, when value of given vertex is fixed. lzr = np.zeros((model.gr_size, model.al_size)) _dfs1(lz, lzc, dfs_edges, dfs_j) log_pf = logsumexp(lz[0, :]) if subtree_mp: return InferenceResult(log_pf, lz) _dfs2(lz, lzc, lzr, dfs_edges, dfs_j) marg_proba = np.exp(lz + lzr - log_pf) return InferenceResult(log_pf, marg_proba)