class_docstr: A dense matrix exponential bijective transform (Hoogeboom et al., 2020) with
  equation,
  
      :math:`\mathbf{y} = \exp(M)\mathbf{x}`
  
  where :math:`\mathbf{x}` are the inputs, :math:`\mathbf{y}` are the outputs,
  :math:`\exp(\cdot)` represents the matrix exponential, and the learnable
  parameters are :math:`M\in\mathbb{R}^D\times\mathbb{R}^D` for input dimension
  :math:`D`. In general, :math:`M` is not required to be invertible.
  
  Due to the favourable mathematical properties of the matrix exponential, the
  transform has an exact inverse and a log-determinate-Jacobian that scales in
  time-complexity as :math:`O(D)`. Both the forward and reverse operations are
  approximated with a truncated power series. For numerical stability, the
  norm of :math:`M` can be restricted with the `normalization` keyword argument.
  
  Example usage:
  
  >>> base_dist = dist.Normal(torch.zeros(10), torch.ones(10))
  >>> transform = MatrixExponential(10)
  >>> pyro.module("my_transform", transform)  # doctest: +SKIP
  >>> flow_dist = dist.TransformedDistribution(base_dist, [transform])
  >>> flow_dist.sample()  # doctest: +SKIP
  
  :param input_dim: the dimension of the input (and output) variable.
  :type input_dim: int
  :param iterations: the number of terms to use in the truncated power series that
      approximates matrix exponentiation.
  :type iterations: int
  :param normalization: One of `['none', 'weight', 'spectral']` normalization that
      selects what type of normalization to apply to the weight matrix. `weight`
      corresponds to weight normalization (Salimans and Kingma, 2016) and
      `spectral` to spectral normalization (Miyato et al, 2018).
  :type normalization: string
  :param bound: a bound on either the weight or spectral norm, when either of
      those two types of regularization are chosen by the `normalization`
      argument. A lower value for this results in fewer required terms of the
      truncated power series to closely approximate the exact value of the matrix
      exponential.
  :type bound: float
  
  References:
  
  [1] Emiel Hoogeboom, Victor Garcia Satorras, Jakub M. Tomczak, Max Welling. The
      Convolution Exponential and Generalized Sylvester Flows. [arXiv:2006.01910]
  [2] Tim Salimans, Diederik P. Kingma. Weight Normalization: A Simple
      Reparameterization to Accelerate Training of Deep Neural Networks.
      [arXiv:1602.07868]
  [3] Takeru Miyato, Toshiki Kataoka, Masanori Koyama, Yuichi Yoshida. Spectral
      Normalization for Generative Adversarial Networks. ICLR 2018.
code: def __init__(
      self, input_dim, iterations=8, normalization="none", bound=None
  ):
      super().__init__(
          iterations=iterations,
          normalization=normalization,
          bound=bound,
      )
  
      self.weights = nn.Parameter(torch.Tensor(input_dim, input_dim))
      self.reset_parameters()
  
imports: import math
  from functools import partial
  import torch
  import torch.nn
  from torch.distributions import Transform, constraints
  from pyro.nn import DenseNN
  from ..conditional import ConditionalTransformModule
  from ..torch_transform import TransformModule
  from ..util import copy_docs_from
label_desc: Use image node_id 1 to create a new MatrixExponential object from inherited base classes: ConditionedMatrixExponential, TransformModule with example: obj = MatrixExponential(input_dim, iterations, normalization, bound)