docs: def policy_iteration(self, v_init=None, max_iter=None):
          """
          Solve the optimization problem by policy iteration. See the
          `solve` method.
  
          """
          if self.beta == 1:
              raise NotImplementedError(self._error_msg_no_discounting)
  
          if max_iter is None:
              max_iter = self.max_iter
  
          # What for initial condition?
          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):
              # Policy evaluation
              v_sigma = self.evaluate_policy(sigma)
              # Policy improvement
              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