class_docstr: An implementation of the bijective transform of Inverse Autoregressive Flow
  (IAF), using by default Eq (10) from Kingma Et Al., 2016,
  
      :math:`\mathbf{y} = \mu_t + \sigma_t\odot\mathbf{x}`
  
  where :math:`\mathbf{x}` are the inputs, :math:`\mathbf{y}` are the outputs,
  :math:`\mu_t,\sigma_t` are calculated from an autoregressive network on
  :math:`\mathbf{x}`, and :math:`\sigma_t>0`.
  
  If the stable keyword argument is set to True then the transformation used is,
  
      :math:`\mathbf{y} = \sigma_t\odot\mathbf{x} + (1-\sigma_t)\odot\mu_t`
  
  where :math:`\sigma_t` is restricted to :math:`(0,1)`. This variant of IAF is
  claimed by the authors to be more numerically stable than one using Eq (10),
  although in practice it leads to a restriction on the distributions that can be
  represented, presumably since the input is restricted to rescaling by a number
  on :math:`(0,1)`.
  
  Together with :class:`~pyro.distributions.TransformedDistribution` this provides
  a way to create richer variational approximations.
  
  Example usage:
  
  >>> from pyro.nn import AutoRegressiveNN
  >>> base_dist = dist.Normal(torch.zeros(10), torch.ones(10))
  >>> transform = AffineAutoregressive(AutoRegressiveNN(10, [40]))
  >>> pyro.module("my_transform", transform)  # doctest: +SKIP
  >>> flow_dist = dist.TransformedDistribution(base_dist, [transform])
  >>> flow_dist.sample()  # doctest: +SKIP
  
  The inverse of the Bijector is required when, e.g., scoring the log density of a
  sample with :class:`~pyro.distributions.TransformedDistribution`. This
  implementation caches the inverse of the Bijector when its forward operation is
  called, e.g., when sampling from
  :class:`~pyro.distributions.TransformedDistribution`. However, if the cached
  value isn't available, either because it was overwritten during sampling a new
  value or an arbitrary value is being scored, it will calculate it manually. Note
  that this is an operation that scales as O(D) where D is the input dimension,
  and so should be avoided for large dimensional uses. So in general, it is cheap
  to sample from IAF and score a value that was sampled by IAF, but expensive to
  score an arbitrary value.
  
  :param autoregressive_nn: an autoregressive neural network whose forward call
      returns a real-valued mean and logit-scale as a tuple
  :type autoregressive_nn: callable
  :param log_scale_min_clip: The minimum value for clipping the log(scale) from
      the autoregressive NN
  :type log_scale_min_clip: float
  :param log_scale_max_clip: The maximum value for clipping the log(scale) from
      the autoregressive NN
  :type log_scale_max_clip: float
  :param sigmoid_bias: A term to add the logit of the input when using the stable
      tranform.
  :type sigmoid_bias: float
  :param stable: When true, uses the alternative "stable" version of the transform
      (see above).
  :type stable: bool
  
  References:
  
  [1] Diederik P. Kingma, Tim Salimans, Rafal Jozefowicz, Xi Chen, Ilya Sutskever,
  Max Welling. Improving Variational Inference with Inverse Autoregressive Flow.
  [arXiv:1606.04934]
  
  [2] Danilo Jimenez Rezende, Shakir Mohamed. Variational Inference with
  Normalizing Flows. [arXiv:1505.05770]
  
  [3] Mathieu Germain, Karol Gregor, Iain Murray, Hugo Larochelle. MADE: Masked
  Autoencoder for Distribution Estimation. [arXiv:1502.03509]
docstr: :param y: the output of the bijection
  :type y: torch.Tensor
  
  Inverts y => x. Uses a previously cached inverse if available, otherwise
  performs the inversion afresh.
docstr_tok: [":","param","y",":","the","output","of","the","bijection",":","type","y",":","torch.Tensor","Inverts","y","=",">","x",".","Uses","a","previously","cached","inverse","if","available",",","otherwise","performs","the","inversion","afresh","."]
code: def _inverse(self, y):
      """
      :param y: the output of the bijection
      :type y: torch.Tensor
  
      Inverts y => x. Uses a previously cached inverse if available, otherwise
      performs the inversion afresh.
      """
      x_size = y.size()[:-1]
      perm = self.arn.permutation
      input_dim = y.size(-1)
      x = [torch.zeros(x_size, device=y.device)] * input_dim
  
      # NOTE: Inversion is an expensive operation that scales in the dimension of the input
      for idx in perm:
          mean, log_scale = self.arn(torch.stack(x, dim=-1))
          inverse_scale = torch.exp(
              -clamp_preserve_gradients(
                  log_scale[..., idx],
                  min=self.log_scale_min_clip,
                  max=self.log_scale_max_clip,
              )
          )
          mean = mean[..., idx]
          x[idx] = (y[..., idx] - mean) * inverse_scale
  
      x = torch.stack(x, dim=-1)
      log_scale = clamp_preserve_gradients(
          log_scale,
          min=self.log_scale_min_clip,
          max=self.log_scale_max_clip,
      )
      self._cached_log_scale = log_scale
      return x
  
imports: from functools import partial
  import torch
  import torch.nn
  from pyro.nn import AutoRegressiveNN, ConditionalAutoRegressiveNN
  from ..None import constraints
  from ..conditional import ConditionalTransformModule
  from ..torch_transform import TransformModule
  from ..util import copy_docs_from
  from .utils import clamp_preserve_gradients
label_desc: Use image node_id 3 for calling the AffineAutoregressive obj's underlying member method code with example usage: obj._inverse(y) and returns: x