'Solve the optimization problem by policy iteration. See the
`solve` method.'

def policy_iteration(self, v_init=None, max_iter=None):

    if (self.beta == 1):
        raise NotImplementedError(self._error_msg_no_discounting)
    if (max_iter is None):
        max_iter = self.max_iter
    if (v_init is None):
        v_init = self.s_wise_max(self.R)
    sigma = self.compute_greedy(v_init)
    new_sigma = np.empty(self.num_states, dtype=int)
    for i in range(max_iter):
        v_sigma = self.evaluate_policy(sigma)
        self.compute_greedy(v_sigma, sigma=new_sigma)
        if np.array_equal(new_sigma, sigma):
            break
        sigma[:] = new_sigma
    num_iter = (i + 1)
    res = DPSolveResult(v=v_sigma, sigma=sigma, num_iter=num_iter, mc=self.controlled_mc(sigma), method='policy    iteration', max_iter=max_iter)
    return res
