docs: def computePerturbedFreeEnergies(self, u_ln, compute_uncertainty=True, uncertainty_method=None, warning_cutoff=1.0e-10):
          """Compute the free energies for a new set of states.
  
          Here, we desire the free energy differences among a set of new states, as well as the uncertainty estimates in these differences.
  
          Parameters
          ----------
          u_ln : np.ndarray, float, shape=(L, Nmax)
              u_ln[l,n] is the reduced potential energy of uncorrelated
              configuration n evaluated at new state k.  Can be completely indepednent of the original number of states.
          compute_uncertainty : bool, optional, default=True
              If False, the uncertainties will not be computed (default: True)
          uncertainty_method : string, optional
              Choice of method used to compute asymptotic covariance method, or None to use default
              See help for computeAsymptoticCovarianceMatrix() for more information on various methods. (default: None)
          warning_cutoff : float, optional
              Warn if squared-uncertainty is negative and larger in magnitude than this number (default: 1.0e-10)
  
          Returns
          -------
          result_vals : dictionary
  
          Possible keys in the result_vals dictionary:
  
          'Delta_f' : np.ndarray, float, shape=(L, L)
              result_vals['Delta_f'] = f_j - f_i, the dimensionless free energy difference between new states i and j
          'dDelta_f' : np.ndarray, float, shape=(L, L)
              result_vals['dDelta_f'] is the estimated statistical uncertainty in result_vals['Delta_f']
              or not included if `compute_uncertainty` is False
  
          Examples
          --------
          >>> from pymbar import testsystems
          >>> (x_n, u_kn, N_k, s_n) = testsystems.HarmonicOscillatorsTestCase().sample(mode='u_kn')
          >>> mbar = MBAR(u_kn, N_k)
          >>> results = mbar.computePerturbedFreeEnergies(u_kn)
          """
  
          # Convert to np matrix.
          u_ln = np.array(u_ln, dtype=np.float64)
  
          # Get the dimensions of the matrix of reduced potential energies, and convert if necessary
          if len(np.shape(u_ln)) == 3:
              u_ln = kln_to_kn(u_ln, N_k=self.N_k)
  
          [L, N] = u_ln.shape
  
          # Check dimensions.
          if (N < self.N):
              raise DataError("There seems to be too few samples in u_kn. You must evaluate at the new potential with all of the samples used originally.")
  
          state_list = np.arange(L)   # need to get it into the correct shape
          A_in = np.array([0])
          inner_results = self.computeExpectationsInner(A_in, u_ln, state_list,
                                                        return_theta=compute_uncertainty,
                                                        uncertainty_method=uncertainty_method,
                                                        warning_cutoff=warning_cutoff)
  
          Deltaf_ij, dDeltaf_ij = None, None
  
          f_k = np.matrix(inner_results['f'])
  
          result_vals = dict()
          result_vals['Delta_f'] = np.array(f_k - f_k.transpose())
  
          if (compute_uncertainty):
              result_vals['dDelta_f'] = self._ErrorOfDifferences(inner_results['Theta'],warning_cutoff=warning_cutoff)
  
          # Return matrix of free energy differences and uncertainties.
          return result_vals