class_docstr: Non-normalized GammaGaussian distribution:
  
      GammaGaussian(x, s) ~ (concentration + 0.5 * dim - 1) * log(s)
                            - rate * s - s * 0.5 * info_vec.T @ inv(precision) @ info_vec)
                            - s * 0.5 * x.T @ precision @ x + s * x.T @ info_vec,
  
  which will be reparameterized as
  
      GammaGaussian(x, s) =: alpha * log(s) + s * (-0.5 * x.T @ precision @ x + x.T @ info_vec - beta).
  
  The `s` variable plays the role of a mixing variable such that
  
      p(x | s) ~ Gaussian(s * info_vec, s * precision).
  
  Conditioned on `s`, this represents an arbitrary semidefinite quadratic function,
  which can be interpreted as a rank-deficient Gaussian distribution.
  The precision matrix may have zero eigenvalues, thus it may be impossible
  to work directly with the covariance matrix.
  
  :param torch.Tensor log_normalizer: a normalization constant, which is mainly used to keep
      track of normalization terms during contractions.
  :param torch.Tensor info_vec: information vector, which is a scaled version of the mean
      ``info_vec = precision @ mean``. We use this represention to make gaussian contraction
      fast and stable.
  :param torch.Tensor precision: precision matrix of this gaussian.
  :param torch.Tensor alpha: reparameterized shape parameter of the marginal Gamma distribution of
      `s`. The shape parameter Gamma.concentration is reparameterized by:
  
          alpha = Gamma.concentration + 0.5 * dim - 1
  
  :param torch.Tensor beta: reparameterized rate parameter of the marginal Gamma distribution of
      `s`. The rate parameter Gamma.rate is reparameterized by:
  
          beta = Gamma.rate + 0.5 * info_vec.T @ inv(precision) @ info_vec
docstr: Integrates out all latent state (i.e. operating on event dimensions) of Gaussian component.
docstr_tok: ["Integrates","out","all","latent","state","(","i.e",".","operating","on","event","dimensions",")","of","Gaussian","component","."]
code: def event_logsumexp(self):
      """
      Integrates out all latent state (i.e. operating on event dimensions) of Gaussian component.
      """
      n = self.dim()
      chol_P = torch.linalg.cholesky(self.precision)
      chol_P_u = torch.linalg.solve_triangular(
          chol_P, self.info_vec.unsqueeze(-1), upper=False
      ).squeeze(-1)
      u_P_u = chol_P_u.pow(2).sum(-1)
      # considering GammaGaussian as a Gaussian with precision = s * precision, info_vec = s * info_vec,
      # marginalize x variable, we get
      #   logsumexp(s) = alpha * log(s) - s * beta + 0.5 n * log(2 pi) + \
      #       0.5 s * uPu - 0.5 * log|P| - 0.5 n * log(s)
      # use the original parameterization of Gamma, we get
      #   logsumexp(s) = (concentration - 1) * log(s) - s * rate + 0.5 n * log(2 pi) - 0.5 * |P|
      # Note that `(concentration - 1) * log(s) - s * rate` is unnormalized log_prob of
      #   Gamma(concentration, rate)
      concentration = self.alpha - 0.5 * n + 1
      rate = self.beta - 0.5 * u_P_u
      log_normalizer_tmp = 0.5 * n * math.log(
          2 * math.pi
      ) - chol_P.diagonal(dim1=-2, dim2=-1).log().sum(-1)
      return Gamma(
          self.log_normalizer + log_normalizer_tmp, concentration, rate
      )
  
imports: import math
  import torch
  from torch.distributions.utils import lazy_property
  from torch.nn.functional import pad
  from pyro.distributions.multivariate_studentt import MultivariateStudentT
  from pyro.distributions.torch import MultivariateNormal
  from pyro.distributions.util import broadcast_shape
  from pyro.ops.tensor_utils import precision_to_scale_tril
label_desc: Use image node_id 15 for calling the GammaGaussian obj's underlying member method code with example usage: obj.event_logsumexp() and returns: Gamma