# Path: mjhmc/misc/utils.py
# def overrides(interface_class):
#     """
#     override decorator. need to specify the super class, unfortunately
#     """
#     def overrider(method):
#         assert(method.__name__ in dir(interface_class))
#         return method
#     return overrider
# 
# def min_idx(draws):
#     """
#     selects the argmin of the row wise minimum
#     returns a list of rows where each input draw was min
#     draws: a list of the various draws
# 
#     eg: draws = [fl_draws, f_draws] where fl_draws.shape = f_draws.shape = (1, N)
#     returns fl_idx, f_idx where fl_idx (and the others) are
#     arrays of shape (nbatch,) containing the indices of the rows where each variable was
#     the minimum
#     """
#     cdraws = np.concatenate(draws, axis=0)
#     transition_idx = np.argmin(cdraws, axis=0)
#     return [np.where(transition_idx == i)[0] for i in xrange(len(draws))]
# 
# def normalize_by_row(matrix):
#     row_sums = matrix.sum(axis=1)
#     # replaces 0 with 1 to avoid divide by 0
#     np.place(row_sums, row_sums == 0, 1)
#     norm_matrix = matrix / row_sums[:, np.newaxis]
#     return norm_matrix


import numpy as np
import copy
import itertools
from mjhmc.misc.utils import overrides, min_idx, normalize_by_row
        """
        if self.n < self.burn_in_steps:
            raise RuntimeWarning("Not burned in yet")
        norm = np.sum(self.distr)
        return self.distr / norm

    def get_empirical_transition_matrix(self, full=False):
        """Normalizes and returns the transition matrix
        """
        if self.n < self.burn_in_steps:
            raise RuntimeWarning("Not burned in yet")
        if full:
            return normalize_by_row(self.transitions)
        else:
            reduced = self.reduce_full_transition_matrix(self.transitions)
            return normalize_by_row(reduced)

    def calculate_true_transition_matrix(self, full=True):
        """
        Returns the analytic transition matrix for this distribution
        Uses transition probabilities to build matrix for full state space (flipped states too)
        and then sums out flipped states and returns the matrix for energy states only
        """
        # no nice way to have private variables...
        T_full = np.zeros((self.order, self.order))

        for idx in xrange(self.order):
            self.update_transition_matrix(idx, T_full)

        if full:

# Path: mjhmc/misc/utils.py
# def overrides(interface_class):
#     """
#     override decorator. need to specify the super class, unfortunately
#     """
#     def overrider(method):
#         assert(method.__name__ in dir(interface_class))
#         return method
#     return overrider
# 
# def min_idx(draws):
#     """
#     selects the argmin of the row wise minimum
#     returns a list of rows where each input draw was min
#     draws: a list of the various draws
# 
#     eg: draws = [fl_draws, f_draws] where fl_draws.shape = f_draws.shape = (1, N)
#     returns fl_idx, f_idx where fl_idx (and the others) are
#     arrays of shape (nbatch,) containing the indices of the rows where each variable was
#     the minimum
#     """
#     cdraws = np.concatenate(draws, axis=0)
#     transition_idx = np.argmin(cdraws, axis=0)
#     return [np.where(transition_idx == i)[0] for i in xrange(len(draws))]
# 
# def normalize_by_row(matrix):
#     row_sums = matrix.sum(axis=1)
#     # replaces 0 with 1 to avoid divide by 0
#     np.place(row_sums, row_sums == 0, 1)
#     norm_matrix = matrix / row_sums[:, np.newaxis]
#     return norm_matrix


# Path: mjhmc/samplers/algebraic_hmc.py
import numpy as np
import copy
import itertools
from mjhmc.misc.utils import overrides, min_idx, normalize_by_row

        """
        if self.n < self.burn_in_steps:
            raise RuntimeWarning("Not burned in yet")
        norm = np.sum(self.distr)
        return self.distr / norm

    def get_empirical_transition_matrix(self, full=False):
        """Normalizes and returns the transition matrix
        """
        if self.n < self.burn_in_steps:
            raise RuntimeWarning("Not burned in yet")
        if full:
            return normalize_by_row(self.transitions)
        else:
            reduced = self.reduce_full_transition_matrix(self.transitions)
            return normalize_by_row(reduced)

    def calculate_true_transition_matrix(self, full=True):
        """
        Returns the analytic transition matrix for this distribution
        Uses transition probabilities to build matrix for full state space (flipped states too)
        and then sums out flipped states and returns the matrix for energy states only
        """
        # no nice way to have private variables...
        T_full = np.zeros((self.order, self.order))

        for idx in xrange(self.order):
            self.update_transition_matrix(idx, T_full)

        if full:

            return normalize_by_row(T_full)