original_docstring: r"""
          This function computes an upper bound of the rate distortion function
          :math:`R(D)` for the random variable, where :math:`D` defines a
          quadratic distortion function,
  
          ..math:
              x\mapsto x^t D^{-1} x.
  
          The variable :math:`D` can be a symmetric matrix, the diagonal of a
          diagonal matrix, or a scalar defining a spherical distortion function.
          Which case is determined by the shape of :math:`D`.
  
          The upper bound is calculated by replacing the random variable with a
          multi-variate normal distribution with the same mean and covariance
          matrix.
  
          Parameters
          ==========
          D : {float, (n,) array, (n, n) array}
              defines the distortion function.
          gaussian_approx : bool, optional
              determines whether to use a Gaussian distribution of the RV.
          V : (m, n) array, optional
              defines a linear map embedding the random variable.
  
          Returns
          =======
          R : float
              the bound of the rate for the given distortion, in nats.
          
docstring: r"""
  This function computes an upper bound of the rate distortion function
docstring_tokens: r " " " This function computes an upper bound of the rate distortion function
code: def rate_fn_bound(self, D, V=None, gaussian_approx=True):
          r"""
          This function computes an upper bound of the rate distortion function
          :math:`R(D)` for the random variable, where :math:`D` defines a
          quadratic distortion function,
  
          ..math:
              x\mapsto x^t D^{-1} x.
  
          The variable :math:`D` can be a symmetric matrix, the diagonal of a
          diagonal matrix, or a scalar defining a spherical distortion function.
          Which case is determined by the shape of :math:`D`.
  
          The upper bound is calculated by replacing the random variable with a
          multi-variate normal distribution with the same mean and covariance
          matrix.
  
          Parameters
          ==========
          D : {float, (n,) array, (n, n) array}
              defines the distortion function.
          gaussian_approx : bool, optional
              determines whether to use a Gaussian distribution of the RV.
          V : (m, n) array, optional
              defines a linear map embedding the random variable.
  
          Returns
          =======
          R : float
              the bound of the rate for the given distortion, in nats.
          """
          if not gaussian_approx:
              raise NotImplementedError("No exact rate distortion function.")
              
          # First compute the covariance matrix
          if V is None:
              Sigma = self.covar
          else:
              m, n = V.shape
              if m != self.m:
                  raise ValueError("Dimension mismatch")
              Sigma = V.T.dot(self.covar).dot(V)
  
          # Now find coordinate change so that S = I
          if len(np.shape(D)) == 2:  # full covariance
              sqrtS = np.linalg.cholesky(D)
              invsqrtS = np.linalg.inv(sqrtS)
          else:
              invsqrtS = 1 / np.sqrt(D) * np.eye(Sigma.shape[0])
  
          # Transform the covariance matrix
          Sigma = invsqrtS.T.dot(Sigma).dot(invsqrtS)
  
          # Compute the (real) eigenvalues
          variances = np.linalg.eigvals(Sigma).real
  
          return rate_dist_ind_Gaussians(1, variances)
code_tokens: def rate_fn_bound ( self , D , V = None , gaussian_approx = True ) : if not gaussian_approx : raise NotImplementedError ( "No exact rate distortion function." ) if V is None : Sigma = self . covar else : m , n = V . shape if m != self . m : raise ValueError ( "Dimension mismatch" ) Sigma = V . T . dot ( self . covar ) . dot ( V ) if len ( np . shape ( D ) ) == 2 : sqrtS = np . linalg . cholesky ( D ) invsqrtS = np . linalg . inv ( sqrtS ) else : invsqrtS = 1 / np . sqrt ( D ) * np . eye ( Sigma . shape [ 0 ] ) Sigma = invsqrtS . T . dot ( Sigma ) . dot ( invsqrtS ) variances = np . linalg . eigvals ( Sigma ) . real return rate_dist_ind_Gaussians ( 1 , variances )
short_docstring: r"""
  This function computes an upper bound of the rate distortion function
short_docstring_tokens: r " " " This function computes an upper bound of the rate distortion function
comment: r"""
          This function computes an upper bound of the rate distortion function
          :math:`R(D)` for the random variable, where :math:`D` defines a
          quadratic distortion function,
  
          ..math:
              x\mapsto x^t D^{-1} x.
  
          The variable :math:`D` can be a symmetric matrix, the diagonal of a
          diagonal matrix, or a scalar defining a spherical distortion function.
          Which case is determined by the shape of :math:`D`.
  
          The upper bound is calculated by replacing the random variable with a
          multi-variate normal distribution with the same mean and covariance
          matrix.
  
          Parameters
          ==========
          D : {float, (n,) array, (n, n) array}
              defines the distortion function.
          gaussian_approx : bool, optional
              determines whether to use a Gaussian distribution of the RV.
          V : (m, n) array, optional
              defines a linear map embedding the random variable.
  
          Returns
          =======
          R : float
              the bound of the rate for the given distortion, in nats.
          """$SEP$# First compute the covariance matrix$SEP$# Now find coordinate change so that S = I$SEP$# full covariance$SEP$# Transform the covariance matrix$SEP$# Compute the (real) eigenvalues