def mutual_information(p_x: np.ndarray, p_yx: np.ndarray) -> float: assert MF.check_matrix_simple_stochastic(p_yx), "conditional matrix p_yx is not \ simple stochastic." assert check_l1_norm(p_x), "p_x is not l1-normed" p_y = np.dot(np.transpose(p_yx), p_x) assert check_l1_norm(p_y), "p_y is not l1-normed" return classical_entropy(p_y) - conditional_entropy(p_x, p_yx)
def conditional_entropy(p_x: np.ndarray, p_yx: np.ndarray) -> float: assert MF.check_matrix_simple_stochastic(p_yx), "conditional matrix p_yx is not \ simple stochastic." assert check_l1_norm(p_x), "p_x is not l1-normed" H = 0 for i, p in enumerate(p_x): H += p * classical_entropy(p_yx[i]) return H
def get_conditional_prob_from_joint_prob(p_xy: np.ndarray) -> np.ndarray: assert check_joint_probability_matrix(p_xy), "p_xy is not a joint probability \ matrix." size_a, size_b = p_xy.shape p_x = np.dot(p_xy, np.ones(size_b)) assert check_l1_norm(p_x), "p_x is not l1-normed." for i in range(size_a): p_xy[i] *= 1/p_x[i] assert MF.check_matrix_simple_stochastic(p_xy), "after calculation the matrix \ is not a conditional probability matrix" return p_xy
def test_check_matrix_simple_stochastic(self): m = np.array([[0.70, 0.20, 0.10], [0.05, 0.80, 0.15], [0.10, 0.10, 0.80]]) self.assertTrue(MF.check_matrix_simple_stochastic(m)) m = np.array([[1.0, 0.2, 0.3], [0.0, 0.8, 0.7]]) self.assertFalse(MF.check_matrix_simple_stochastic(m))