class_docstr: Indexed entropy model for location-scale family of random variables.
  
  This class is a common special case of `ContinuousIndexedEntropyModel`. The
  specified distribution is parameterized with `num_scales` values of scale
  parameters. An element-wise location parameter is handled by shifting the
  distributions to zero.
  
  This method is illustrated in Figure 10 of:
  > "Nonlinear Transform Coding"<br />
  > J. Ballé, P.A. Chou, D. Minnen, S. Singh, N. Johnston, E. Agustsson,
  > S.J. Hwang, G. Toderici<br />
  > https://doi.org/10.1109/JSTSP.2020.3034501
  
  Note: this only works for shift-invariant `tfpd.Distribution` objects, where
  the `loc` parameter really denotes a translation (i.e., not for the log-normal
  distribution).
docstr: Perturbs a tensor with (quantization) noise and estimates rate.
  
  Args:
    bottleneck: `tf.Tensor` containing the data to be compressed.
    scale_indexes: `tf.Tensor` indexing the scale parameter for each element
      in `bottleneck`. Must have the same shape as `bottleneck`.
    loc: `None` or `tf.Tensor`. If `None`, the location parameter for all
      elements is assumed to be zero. Otherwise, specifies the location
      parameter for each element in `bottleneck`. Must have the same shape as
      `bottleneck`.
    training: Boolean. If `False`, computes the Shannon information of
      `bottleneck` under the distribution computed by `self.prior_fn`,
      which is a non-differentiable, tight *lower* bound on the number of bits
      needed to compress `bottleneck` using `compress()`. If `True`, returns a
      somewhat looser, but differentiable *upper* bound on this quantity.
  
  Returns:
    A tuple (bottleneck_perturbed, bits) where `bottleneck_perturbed` is
    `bottleneck` perturbed with (quantization) noise and `bits` is the rate.
    `bits` has the same shape as `bottleneck` without the `self.coding_rank`
    innermost dimensions.
docstr_tok: ["Perturbs","a","tensor","with","(","quantization",")","noise","and","estimates","rate",".","Args",":","bottleneck",":","`","tf.Tensor","`","containing","the","data","to","be","compressed",".","scale_indexes",":","`","tf.Tensor","`","indexing","the","scale","parameter","for","each","element","in","`","bottleneck","`",".","Must","have","the","same","shape","as","`","bottleneck","`",".","loc",":","`","None","`","or","`","tf.Tensor","`",".","If","`","None","`",",","the","location","parameter","for","all","elements","is","assumed","to","be","zero",".","Otherwise",",","specifies","the","location","parameter","for","each","element","in","`","bottleneck","`",".","Must","have","the","same","shape","as","`","bottleneck","`",".","training",":","Boolean",".","If","`","False","`",",","computes","the","Shannon","information","of","`","bottleneck","`","under","the","distribution","computed","by","`","self.prior_fn","`",",","which","is","a","non-differentiable",",","tight","*","lower","*","bound","on","the","number","of","bits","needed","to","compress","`","bottleneck","`","using","`","compress","(",")","`",".","If","`","True","`",",","returns","a","somewhat","looser",",","but","differentiable","*","upper","*","bound","on","this","quantity",".","Returns",":","A","tuple","(","bottleneck_perturbed",",","bits",")","where","`","bottleneck_perturbed","`","is","`","bottleneck","`","perturbed","with","(","quantization",")","noise","and","`","bits","`","is","the","rate",".","`","bits","`","has","the","same","shape","as","`","bottleneck","`","without","the","`","self.coding_rank","`","innermost","dimensions","."]
code: def __call__(
      self, bottleneck, scale_indexes, loc=None, training=True
  ):
      """Perturbs a tensor with (quantization) noise and estimates rate.
  
      Args:
        bottleneck: `tf.Tensor` containing the data to be compressed.
        scale_indexes: `tf.Tensor` indexing the scale parameter for each element
          in `bottleneck`. Must have the same shape as `bottleneck`.
        loc: `None` or `tf.Tensor`. If `None`, the location parameter for all
          elements is assumed to be zero. Otherwise, specifies the location
          parameter for each element in `bottleneck`. Must have the same shape as
          `bottleneck`.
        training: Boolean. If `False`, computes the Shannon information of
          `bottleneck` under the distribution computed by `self.prior_fn`,
          which is a non-differentiable, tight *lower* bound on the number of bits
          needed to compress `bottleneck` using `compress()`. If `True`, returns a
          somewhat looser, but differentiable *upper* bound on this quantity.
  
      Returns:
        A tuple (bottleneck_perturbed, bits) where `bottleneck_perturbed` is
        `bottleneck` perturbed with (quantization) noise and `bits` is the rate.
        `bits` has the same shape as `bottleneck` without the `self.coding_rank`
        innermost dimensions.
      """
      if loc is None:
          return super().__call__(
              bottleneck, scale_indexes, training=training
          )
      else:
          bottleneck, bits = super().__call__(
              bottleneck - loc, scale_indexes, training=training
          )
          return bottleneck + loc, bits
  
imports: import tensorflow
  from tensorflow_compression.python.entropy_models import continuous_base
  from tensorflow_compression.python.ops import gen_ops
  from tensorflow_compression.python.ops import math_ops
  from tensorflow_compression.python.ops import round_ops
label_desc: Use image node_id 2 for calling the LocationScaleIndexedEntropyModel obj's underlying member method code with example usage: obj.__call__(bottleneck, scale_indexes, loc, training) and returns: super, unknown,  bits