def _e_step(self):
        logging.debug('E-Step')
        if not self._lp_init:
            self._init_LP()

        nprt = len(self.parts)
        # individual potentials
        logging.debug('Obj func - indiv potentials')
        c_indiv = cvx_mat([0.0] * len(self.author_graph) * nprt)
        for a in self.author_graph:
            c_indiv[a*nprt:(a+1)*nprt] = [self._log_phi(a, p) for p in self.parts]
        objF = -cvx_dot(c_indiv, self.alpha)
        # pairwise potentials
        logging.debug('Obj func - pair potentials')
        objF -= cvx_dot(self.c_pair, self.beta2)

        lp = cvx_op(objF, self.constraints)
        # if logging.getLogger('root').level != logging.DEBUG:
        #     lp.options['show_progress'] = False
        # solve the LP
        logging.debug('Solving the LP')
        lp.solve('sparse', 'glpk')
        logging.debug('Solving the LP Done')

        # hard partitions for nodes (authors)
        self.partition = {}
        for a in self.author_graph:
            self.partition[a] = np.argmax(self.alpha.value[a*nprt:(a+1)*nprt])
        logging.debug('E-Step Done')
    def _e_step(self):
        logging.debug('E-Step')
        if not self._lp_init:
            self._init_LP()

        nprt = len(self.parts)
        # individual potentials
        logging.debug('Obj func - indiv potentials')
        c_indiv = cvx_mat([0.0] * len(self.author_graph) * nprt)
        for a in self.author_graph:
            c_indiv[a * nprt:(a + 1) *
                    nprt] = [self._log_phi(a, p) for p in self.parts]
        objF = -cvx_dot(c_indiv, self.alpha)
        # pairwise potentials
        logging.debug('Obj func - pair potentials')
        objF -= cvx_dot(self.c_pair, self.beta2)

        lp = cvx_op(objF, self.constraints)
        # if logging.getLogger('root').level != logging.DEBUG:
        #     lp.options['show_progress'] = False
        # solve the LP
        logging.debug('Solving the LP')
        lp.solve('sparse', 'glpk')
        logging.debug('Solving the LP Done')

        # hard partitions for nodes (authors)
        self.partition = {}
        for a in self.author_graph:
            self.partition[a] = np.argmax(self.alpha.value[a * nprt:(a + 1) *
                                                           nprt])
        logging.debug('E-Step Done')
    def _init_LP(self):
        logging.debug('Init LP')

        # add constraints once here
        # constraints
        self.constraints = []
        nprt = len(self.parts)
        self.alpha = cvx_var(size=len(self.author_graph) * nprt, name='alpha')
        self.beta2 = cvx_var(size=self.author_graph.size(), name='beta2')
        self.beta3 = cvx_var(size=self.author_graph.size() * nprt,
                             name='beta3')
        # node ids are integers (handled in the constructor)
        logging.debug('Init LP - indiv constraints')
        # alphas are indicator vars
        for a in self.author_graph:
            self.constraints.append(
                cvx_sum(self.alpha[a * nprt + p] for p in self.parts) == 1)
        for a in self.alpha:
            self.constraints.append(a >= 0)

        # beta2 is the sum of beta3s
        logging.debug('Init LP - pair constraints')
        for ei, (a, b) in enumerate(self.author_graph.edges()):
            #            if self.author_graph[a][b]['denom'] <= 2:
            #                continue
            self.constraints.append(
                0.5 * cvx_sum(self.beta3[ei * nprt + p]
                              for p in self.parts) == self.beta2[ei])
            for p in self.parts:
                self.constraints.append(
                    self.alpha[a * nprt + p] -
                    self.alpha[b * nprt + p] <= self.beta3[ei * nprt + p])
                self.constraints.append(
                    self.alpha[b * nprt + p] -
                    self.alpha[a * nprt + p] <= self.beta3[ei * nprt + p])

        # pre compute pair-wise costs
        logging.debug('Init LP - pair costs')
        self.c_pair = cvx_mat([0.0] * self.author_graph.size())
        s = log(1 - self.TAU) - log(self.TAU)
        for ei, (a, b) in enumerate(self.author_graph.edges()):
            #            if self.author_graph[a][b]['denom'] <= 2:
            #                continue
            self.c_pair[ei] = self.author_graph[a][b]['weight'] * s

        self._lp_init = True
        logging.debug('Init LP Done')
    def _init_LP(self):
        logging.debug('Init LP')

        # add constraints once here
        # constraints
        self.constraints = []
        nprt = len(self.parts)
        self.alpha = cvx_var(size=len(self.author_graph) * nprt, name='alpha')
        self.beta2 = cvx_var(size=self.author_graph.size(), name='beta2')
        self.beta3 = cvx_var(size=self.author_graph.size() * nprt, name='beta3')
        # node ids are integers (handled in the constructor)
        logging.debug('Init LP - indiv constraints')
        # alphas are indicator vars
        for a in self.author_graph:
            self.constraints.append(cvx_sum(self.alpha[a*nprt + p] for p in self.parts) == 1)
        for a in self.alpha:
            self.constraints.append(a >= 0)

        # beta2 is the sum of beta3s
        logging.debug('Init LP - pair constraints')
        for ei, (a, b) in enumerate(self.author_graph.edges()):
        #            if self.author_graph[a][b]['denom'] <= 2:
        #                continue
            self.constraints.append(0.5 * cvx_sum(self.beta3[ei*nprt + p] for p in self.parts) == self.beta2[ei])
            for p in self.parts:
                self.constraints.append(self.alpha[a*nprt + p] - self.alpha[b*nprt + p] <= self.beta3[ei*nprt + p])
                self.constraints.append(self.alpha[b*nprt + p] - self.alpha[a*nprt + p] <= self.beta3[ei*nprt + p])

        # pre compute pair-wise costs
        logging.debug('Init LP - pair costs')
        self.c_pair = cvx_mat([0.0] * self.author_graph.size())
        s = log(1 - self.TAU) - log(self.TAU)
        for ei, (a, b) in enumerate(self.author_graph.edges()):
        #            if self.author_graph[a][b]['denom'] <= 2:
        #                continue
            self.c_pair[ei] = self.author_graph[a][b]['weight'] * s

        self._lp_init = True
        logging.debug('Init LP Done')