class_docstr: A scheduler for vector quantized diffusion.
  
  This model inherits from [`SchedulerMixin`] and [`ConfigMixin`]. Check the superclass documentation for the generic
  methods the library implements for all schedulers such as loading and saving.
  
  Args:
      num_vec_classes (`int`):
          The number of classes of the vector embeddings of the latent pixels. Includes the class for the masked
          latent pixel.
      num_train_timesteps (`int`, defaults to 100):
          The number of diffusion steps to train the model.
      alpha_cum_start (`float`, defaults to 0.99999):
          The starting cumulative alpha value.
      alpha_cum_end (`float`, defaults to 0.00009):
          The ending cumulative alpha value.
      gamma_cum_start (`float`, defaults to 0.00009):
          The starting cumulative gamma value.
      gamma_cum_end (`float`, defaults to 0.99999):
          The ending cumulative gamma value.
docstr: Calculates the log probabilities for the predicted classes of the image at timestep `t-1`:
  
  ```
  p(x_{t-1} | x_t) = sum( q(x_t | x_{t-1}) * q(x_{t-1} | x_0) * p(x_0) / q(x_t | x_0) )
  ```
  
  Args:
      log_p_x_0 (`torch.FloatTensor` of shape `(batch size, num classes - 1, num latent pixels)`):
          The log probabilities for the predicted classes of the initial latent pixels. Does not include a
          prediction for the masked class as the initial unnoised image cannot be masked.
      x_t (`torch.LongTensor` of shape `(batch size, num latent pixels)`):
          The classes of each latent pixel at time `t`.
      t (`torch.Long`):
          The timestep that determines which transition matrix is used.
  
  Returns:
      `torch.FloatTensor` of shape `(batch size, num classes, num latent pixels)`:
          The log probabilities for the predicted classes of the image at timestep `t-1`.
docstr_tok: ["Calculates","the","log","probabilities","for","the","predicted","classes","of","the","image","at","timestep","`","t-1","`",":","``","`","p","(","x_","{","t-1","}","|","x_t",")","=","sum","(","q","(","x_t","|","x_","{","t-1","}",")","*","q","(","x_","{","t-1","}","|","x_0",")","*","p","(","x_0",")","\/","q","(","x_t","|","x_0",")",")","``","`","Args",":","log_p_x_0","(","`","torch.FloatTensor","`","of","shape","`","(","batch","size",",","num","classes","-","1",",","num","latent","pixels",")","`",")",":","The","log","probabilities","for","the","predicted","classes","of","the","initial","latent","pixels",".","Does","not","include","a","prediction","for","the","masked","class","as","the","initial","unnoised","image","can","not","be","masked",".","x_t","(","`","torch.LongTensor","`","of","shape","`","(","batch","size",",","num","latent","pixels",")","`",")",":","The","classes","of","each","latent","pixel","at","time","`","t","`",".","t","(","`","torch.Long","`",")",":","The","timestep","that","determines","which","transition","matrix","is","used",".","Returns",":","`","torch.FloatTensor","`","of","shape","`","(","batch","size",",","num","classes",",","num","latent","pixels",")","`",":","The","log","probabilities","for","the","predicted","classes","of","the","image","at","timestep","`","t-1","`","."]
code: def q_posterior(self, log_p_x_0, x_t, t):
      """
      Calculates the log probabilities for the predicted classes of the image at timestep `t-1`:
  
      ```
      p(x_{t-1} | x_t) = sum( q(x_t | x_{t-1}) * q(x_{t-1} | x_0) * p(x_0) / q(x_t | x_0) )
      ```
  
      Args:
          log_p_x_0 (`torch.FloatTensor` of shape `(batch size, num classes - 1, num latent pixels)`):
              The log probabilities for the predicted classes of the initial latent pixels. Does not include a
              prediction for the masked class as the initial unnoised image cannot be masked.
          x_t (`torch.LongTensor` of shape `(batch size, num latent pixels)`):
              The classes of each latent pixel at time `t`.
          t (`torch.Long`):
              The timestep that determines which transition matrix is used.
  
      Returns:
          `torch.FloatTensor` of shape `(batch size, num classes, num latent pixels)`:
              The log probabilities for the predicted classes of the image at timestep `t-1`.
      """
      log_onehot_x_t = index_to_log_onehot(x_t, self.num_embed)
  
      log_q_x_t_given_x_0 = self.log_Q_t_transitioning_to_known_class(
          t=t, x_t=x_t, log_onehot_x_t=log_onehot_x_t, cumulative=True
      )
  
      log_q_t_given_x_t_min_1 = (
          self.log_Q_t_transitioning_to_known_class(
              t=t,
              x_t=x_t,
              log_onehot_x_t=log_onehot_x_t,
              cumulative=False,
          )
      )
  
      # p_0(x_0=C_0 | x_t) / q(x_t | x_0=C_0)          ...      p_n(x_0=C_0 | x_t) / q(x_t | x_0=C_0)
      #               .                    .                                   .
      #               .                            .                           .
      #               .                                      .                 .
      # p_0(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1})  ...      p_n(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1})
      q = log_p_x_0 - log_q_x_t_given_x_0
  
      # sum_0 = p_0(x_0=C_0 | x_t) / q(x_t | x_0=C_0) + ... + p_0(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}), ... ,
      # sum_n = p_n(x_0=C_0 | x_t) / q(x_t | x_0=C_0) + ... + p_n(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1})
      q_log_sum_exp = torch.logsumexp(q, dim=1, keepdim=True)
  
      # p_0(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_0          ...      p_n(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_n
      #                        .                             .                                   .
      #                        .                                     .                           .
      #                        .                                               .                 .
      # p_0(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_0  ...      p_n(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_n
      q = q - q_log_sum_exp
  
      # (p_0(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_0) * a_cumulative_{t-1} + b_cumulative_{t-1}          ...      (p_n(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_n) * a_cumulative_{t-1} + b_cumulative_{t-1}
      #                                         .                                                .                                              .
      #                                         .                                                        .                                      .
      #                                         .                                                                  .                            .
      # (p_0(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_0) * a_cumulative_{t-1} + b_cumulative_{t-1}  ...      (p_n(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_n) * a_cumulative_{t-1} + b_cumulative_{t-1}
      # c_cumulative_{t-1}                                                                                 ...      c_cumulative_{t-1}
      q = self.apply_cumulative_transitions(q, t - 1)
  
      # ((p_0(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_0) * a_cumulative_{t-1} + b_cumulative_{t-1}) * q(x_t | x_{t-1}=C_0) * sum_0              ...      ((p_n(x_0=C_0 | x_t) / q(x_t | x_0=C_0) / sum_n) * a_cumulative_{t-1} + b_cumulative_{t-1}) * q(x_t | x_{t-1}=C_0) * sum_n
      #                                                            .                                                                 .                                              .
      #                                                            .                                                                         .                                      .
      #                                                            .                                                                                   .                            .
      # ((p_0(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_0) * a_cumulative_{t-1} + b_cumulative_{t-1}) * q(x_t | x_{t-1}=C_{k-1}) * sum_0  ...      ((p_n(x_0=C_{k-1} | x_t) / q(x_t | x_0=C_{k-1}) / sum_n) * a_cumulative_{t-1} + b_cumulative_{t-1}) * q(x_t | x_{t-1}=C_{k-1}) * sum_n
      # c_cumulative_{t-1} * q(x_t | x_{t-1}=C_k) * sum_0                                                                                       ...      c_cumulative_{t-1} * q(x_t | x_{t-1}=C_k) * sum_0
      log_p_x_t_min_1 = q + log_q_t_given_x_t_min_1 + q_log_sum_exp
  
      # For each column, there are two possible cases.
      #
      # Where:
      # - sum(p_n(x_0))) is summing over all classes for x_0
      # - C_i is the class transitioning from (not to be confused with c_t and c_cumulative_t being used for gamma's)
      # - C_j is the class transitioning to
      #
      # 1. x_t is masked i.e. x_t = c_k
      #
      # Simplifying the expression, the column vector is:
      #                                                      .
      #                                                      .
      #                                                      .
      # (c_t / c_cumulative_t) * (a_cumulative_{t-1} * p_n(x_0 = C_i | x_t) + b_cumulative_{t-1} * sum(p_n(x_0)))
      #                                                      .
      #                                                      .
      #                                                      .
      # (c_cumulative_{t-1} / c_cumulative_t) * sum(p_n(x_0))
      #
      # From equation (11) stated in terms of forward probabilities, the last row is trivially verified.
      #
      # For the other rows, we can state the equation as ...
      #
      # (c_t / c_cumulative_t) * [b_cumulative_{t-1} * p(x_0=c_0) + ... + (a_cumulative_{t-1} + b_cumulative_{t-1}) * p(x_0=C_i) + ... + b_cumulative_{k-1} * p(x_0=c_{k-1})]
      #
      # This verifies the other rows.
      #
      # 2. x_t is not masked
      #
      # Simplifying the expression, there are two cases for the rows of the column vector, where C_j = C_i and where C_j != C_i:
      #                                                      .
      #                                                      .
      #                                                      .
      # C_j != C_i:        b_t * ((b_cumulative_{t-1} / b_cumulative_t) * p_n(x_0 = c_0) + ... + ((a_cumulative_{t-1} + b_cumulative_{t-1}) / b_cumulative_t) * p_n(x_0 = C_i) + ... + (b_cumulative_{t-1} / (a_cumulative_t + b_cumulative_t)) * p_n(c_0=C_j) + ... + (b_cumulative_{t-1} / b_cumulative_t) * p_n(x_0 = c_{k-1}))
      #                                                      .
      #                                                      .
      #                                                      .
      # C_j = C_i: (a_t + b_t) * ((b_cumulative_{t-1} / b_cumulative_t) * p_n(x_0 = c_0) + ... + ((a_cumulative_{t-1} + b_cumulative_{t-1}) / (a_cumulative_t + b_cumulative_t)) * p_n(x_0 = C_i = C_j) + ... + (b_cumulative_{t-1} / b_cumulative_t) * p_n(x_0 = c_{k-1}))
      #                                                      .
      #                                                      .
      #                                                      .
      # 0
      #
      # The last row is trivially verified. The other rows can be verified by directly expanding equation (11) stated in terms of forward probabilities.
      return log_p_x_t_min_1
  
imports: from dataclasses import dataclass
  from typing import Optional, Tuple, Union
  import numpy
  import torch
  import torch.nn.functional
  from ..configuration_utils import ConfigMixin, register_to_config
  from ..utils import BaseOutput
  from .scheduling_utils import SchedulerMixin
label_desc: Use image node_id 4 for calling the VQDiffusionScheduler obj's underlying member method code with example usage: obj.q_posterior(log_p_x_0, x_t, t) and returns: log_p_x_t_min_1