class_docstr: Lossless compression for Herarchical latent variable models.
  
  Based on the Craystack (https://github.com/j-towns/craystack)
  implementation of Bits-Back coding.
  
  Args:
      model: The hierarchical latent variable model.
      data_shape: The shape [batch-size, channels, height, width]
          of the data and each latent.
      latent_prec: Coding precision.
      prior_prec: Precision for the discretization.
      obs_prec: Precision for the observation codec.
      data_prec: Precision of the discrete data.
      initial_len: Length of the random initial bitstring.
      data_min: Minimum value of the data to be fed into the model.
      data_max: Maximum value of the data to be fed into the model.
      clip_stdd: Minimum value for the stdd of the observation codec.
      track: Whether to track the message sizes at each step.
class_docstr_tok: ["Lossless","compression","for","Herarchical","latent","variable","models",".","Based","on","the","Craystack","(","https",":","\/\/github.com\/j-towns\/craystack",")","implementation","of","Bits-Back","coding",".","Args",":","model",":","The","hierarchical","latent","variable","model",".","data_shape",":","The","shape","[","batch-size",",","channels",",","height",",","width","]","of","the","data","and","each","latent",".","latent_prec",":","Coding","precision",".","prior_prec",":","Precision","for","the","discretization",".","obs_prec",":","Precision","for","the","observation","codec",".","data_prec",":","Precision","of","the","discrete","data",".","initial_len",":","Length","of","the","random","initial","bitstring",".","data_min",":","Minimum","value","of","the","data","to","be","fed","into","the","model",".","data_max",":","Maximum","value","of","the","data","to","be","fed","into","the","model",".","clip_stdd",":","Minimum","value","for","the","stdd","of","the","observation","codec",".","track",":","Whether","to","track","the","message","sizes","at","each","step","."]
docstr: Push data in [0, 2 ** self.data_prec - 1] using BB-ANS, i.e.,
  1) idx_{steps-1}, ..., idx_0 = posterior(discr_data).pop()
  2) likelihood(z_0).push(discr_data)
  3) prior.push(idx_0, ..., idx_{steps-1})
  
  Args:
      discr_data: Discrete data in [0, 2 ** self.data_prec - 1].
  Returns:
      The craystack message with the appended data.
docstr_tok: ["Push","data","in","[","0",",","2","*","*","self.data_prec","-","1","]","using","BB-ANS",",","i.e.",",","1",")","idx_","{","steps-1","}",",","...",",","idx_0","=","posterior","(","discr_data",")",".pop","(",")","2",")","likelihood","(","z_0",")",".push","(","discr_data",")","3",")","prior.push","(","idx_0",",","...",",","idx_","{","steps-1","}",")","Args",":","discr_data",":","Discrete","data","in","[","0",",","2","*","*","self.data_prec","-","1","]",".","Returns",":","The","craystack","message","with","the","appended","data","."]
code: def encode(self, discr_data: np.ndarray) -> tuple:
      """
      Push data in [0, 2 ** self.data_prec - 1] using BB-ANS, i.e.,
      1) idx_{steps-1}, ..., idx_0 = posterior(discr_data).pop()
      2) likelihood(z_0).push(discr_data)
      3) prior.push(idx_0, ..., idx_{steps-1})
  
      Args:
          discr_data: Discrete data in [0, 2 ** self.data_prec - 1].
      Returns:
          The craystack message with the appended data.
      """
      if (discr_data.min() < 0) or (
          discr_data.max() > (1 << self.data_prec) - 1
      ):
          raise ValueError(
              "The values of `discr_data` are in "
              f"[{discr_data.min()},{discr_data.max()}] "
              "but should be in [0, 2 ** self_data_prec - 1]."
          )
      if not discr_data.shape == self.data_shape:
          raise ValueError(
              f"The shape of `discr_data` is {discr_data.shape} "
              f"but should be {self.data_shape}."
          )
  
      (message,) = self.bb_ans.push(self.message, discr_data)
      self.data_count += 1
      self.message = message
      return message
  
imports: from abc import ABC, abstractmethod
  from typing import List, NamedTuple, Optional, Tuple, Union, overload
  import craystack
  import numpy
  import torch
  from craystack import codecs
  from craystack.bb_ans import BBANS
  from improved_diffusion.gaussian_diffusion import GaussianDiffusion
label_desc: Use image node_id 16 for calling the BitsBackCodec obj's underlying member method code with example usage: obj.encode(discr_data) and returns: message