class_docstr: Hidden Markov Model with linear dynamics and observations and arbitrary
  noise for initial, transition, and observation distributions.  Each of
  those distributions can be e.g.
  :class:`~pyro.distributions.MultivariateNormal` or
  :class:`~pyro.distributions.Independent` of
  :class:`~pyro.distributions.Normal`,
  :class:`~pyro.distributions.StudentT`, or :class:`~pyro.distributions.Stable` .
  Additionally the observation distribution may be constrained, e.g.
  :class:`~pyro.distributions.LogNormal`
  
  This corresponds to the generative model::
  
      z = initial_distribution.sample()
      x = []
      for t in range(num_events):
          z = z @ transition_matrix + transition_dist.sample()
          y = z @ observation_matrix + obs_base_dist.sample()
          x.append(obs_transform(y))
  
  where ``observation_dist`` is split into ``obs_base_dist`` and an optional
  ``obs_transform`` (defaulting to the identity).
  
  This implements a reparameterized :meth:`rsample` method but does not
  implement a :meth:`log_prob` method. Derived classes may implement
  :meth:`log_prob` .
  
  Inference without :meth:`log_prob` can be performed using either
  reparameterization with :class:`~pyro.infer.reparam.hmm.LinearHMMReparam`
  or likelihood-free algorithms such as
  :class:`~pyro.infer.energy_distance.EnergyDistance` .  Note that while
  stable processes generally require a common shared stability parameter
  :math:`\alpha` , this distribution and the above inference algorithms allow
  heterogeneous stability parameters.
  
  The event_shape of this distribution includes time on the left::
  
      event_shape = (num_steps,) + observation_dist.event_shape
  
  This distribution supports any combination of homogeneous/heterogeneous
  time dependency of ``transition_dist`` and ``observation_dist``. However at
  least one of the distributions or matrices must be expanded to contain the
  time dimension.
  
  :ivar int hidden_dim: The dimension of the hidden state.
  :ivar int obs_dim: The dimension of the observed state.
  :param initial_dist: A distribution over initial states. This should have
      batch_shape broadcastable to ``self.batch_shape``.  This should have
      event_shape ``(hidden_dim,)``.
  :param ~torch.Tensor transition_matrix: A linear transformation of hidden
      state. This should have shape broadcastable to ``self.batch_shape +
      (num_steps, hidden_dim, hidden_dim)`` where the rightmost dims are
      ordered ``(old, new)``.
  :param transition_dist: A distribution over process noise. This should have
      batch_shape broadcastable to ``self.batch_shape + (num_steps,)``.  This
      should have event_shape ``(hidden_dim,)``.
  :param ~torch.Tensor observation_matrix: A linear transformation from hidden
      to observed state. This should have shape broadcastable to
      ``self.batch_shape + (num_steps, hidden_dim, obs_dim)``.
  :param observation_dist: A observation noise distribution. This should have
      batch_shape broadcastable to ``self.batch_shape + (num_steps,)``.  This
      should have event_shape ``(obs_dim,)``.
  :param int duration: Optional size of the time axis ``event_shape[0]``.
      This is required when sampling from homogeneous HMMs whose parameters
      are not expanded along the time axis.
class_docstr_tok: ["Hidden","Markov","Model","with","linear","dynamics","and","observations","and","arbitrary","noise","for","initial",",","transition",",","and","observation","distributions",".","Each","of","those","distributions","can","be","e.g",".",":","class",":","`","~pyro.distributions.MultivariateNormal","`","or",":","class",":","`","~pyro.distributions.Independent","`","of",":","class",":","`","~pyro.distributions.Normal","`",",",":","class",":","`","~pyro.distributions.StudentT","`",",","or",":","class",":","`","~pyro.distributions.Stable","`",".","Additionally","the","observation","distribution","may","be","constrained",",","e.g",".",":","class",":","`","~pyro.distributions.LogNormal","`","This","corresponds","to","the","generative","model",":",":","z","=","initial_distribution.sample","(",")","x","=","[","]","for","t","in","range","(","num_events",")",":","z","=","z","@","transition_matrix","+","transition_dist.sample","(",")","y","=","z","@","observation_matrix","+","obs_base_dist.sample","(",")","x.append","(","obs_transform","(","y",")",")","where","``","observation_dist","``","is","split","into","``","obs_base_dist","``","and","an","optional","``","obs_transform","``","(","defaulting","to","the","identity",")",".","This","implements","a","reparameterized",":","meth",":","`","rsample","`","method","but","does","not","implement","a",":","meth",":","`","log_prob","`","method",".","Derived","classes","may","implement",":","meth",":","`","log_prob","`",".","Inference","without",":","meth",":","`","log_prob","`","can","be","performed","using","either","reparameterization","with",":","class",":","`","~pyro.infer.reparam.hmm.LinearHMMReparam","`","or","likelihood-free","algorithms","such","as",":","class",":","`","~pyro.infer.energy_distance.EnergyDistance","`",".","Note","that","while","stable","processes","generally","require","a","common","shared","stability","parameter",":","math",":","`","\\alpha","`",",","this","distribution","and","the","above","inference","algorithms","allow","heterogeneous","stability","parameters",".","The","event_shape","of","this","distribution","includes","time","on","the","left",":",":","event_shape","=","(","num_steps",",",")","+","observation_dist.event_shape","This","distribution","supports","any","combination","of","homogeneous\/heterogeneous","time","dependency","of","``","transition_dist","``","and","``","observation_dist","``",".","However","at","least","one","of","the","distributions","or","matrices","must","be","expanded","to","contain","the","time","dimension",".",":","ivar","int","hidden_dim",":","The","dimension","of","the","hidden","state",".",":","ivar","int","obs_dim",":","The","dimension","of","the","observed","state",".",":","param","initial_dist",":","A","distribution","over","initial","states",".","This","should","have","batch_shape","broadcastable","to","``","self.batch_shape","``",".","This","should","have","event_shape","``","(","hidden_dim",",",")","``",".",":","param","~torch.Tensor","transition_matrix",":","A","linear","transformation","of","hidden","state",".","This","should","have","shape","broadcastable","to","``","self.batch_shape","+","(","num_steps",",","hidden_dim",",","hidden_dim",")","``","where","the","rightmost","dims","are","ordered","``","(","old",",","new",")","``",".",":","param","transition_dist",":","A","distribution","over","process","noise",".","This","should","have","batch_shape","broadcastable","to","``","self.batch_shape","+","(","num_steps",",",")","``",".","This","should","have","event_shape","``","(","hidden_dim",",",")","``",".",":","param","~torch.Tensor","observation_matrix",":","A","linear","transformation","from","hidden","to","observed","state",".","This","should","have","shape","broadcastable","to","``","self.batch_shape","+","(","num_steps",",","hidden_dim",",","obs_dim",")","``",".",":","param","observation_dist",":","A","observation","noise","distribution",".","This","should","have","batch_shape","broadcastable","to","``","self.batch_shape","+","(","num_steps",",",")","``",".","This","should","have","event_shape","``","(","obs_dim",",",")","``",".",":","param","int","duration",":","Optional","size","of","the","time","axis","``","event_shape","[","0","]","``",".","This","is","required","when","sampling","from","homogeneous","HMMs","whose","parameters","are","not","expanded","along","the","time","axis","."]
code: def rsample(self, sample_shape=torch.Size()):
      assert self.duration is not None
      init = self.initial_dist.rsample(sample_shape)
      trans = self.transition_dist.expand(
          self.batch_shape + (self.duration,)
      ).rsample(sample_shape)
      obs = self.observation_dist.expand(
          self.batch_shape + (self.duration,)
      ).rsample(sample_shape)
      trans_matrix = self.transition_matrix.expand(
          self.batch_shape + (self.duration, -1, -1)
      )
      z = _linear_integrate(init, trans_matrix, trans)
      x = (z.unsqueeze(-2) @ self.observation_matrix).squeeze(-2) + obs
      for t in self.transforms:
          x = t(x)
      return x
  
imports: import torch
  import torch.nn.functional
  from pyro.ops.gamma_gaussian import GammaGaussian, gamma_and_mvn_to_gamma_gaussian, gamma_gaussian_tensordot, matrix_and_mvn_to_gamma_gaussian
  from pyro.ops.gaussian import Gaussian, gaussian_tensordot, matrix_and_mvn_to_gaussian, mvn_to_gaussian, sequential_gaussian_filter_sample, sequential_gaussian_tensordot
  from pyro.ops.indexing import Vindex
  from pyro.ops.special import safe_log
  from pyro.ops.tensor_utils import cholesky_solve, safe_cholesky
  from .None import constraints
  from .torch import Categorical, Gamma, Independent, MultivariateNormal
  from .torch_distribution import TorchDistribution
  from .util import broadcast_shape, torch_jit_script_if_tracing
label_desc: Use image node_id 5 for calling the LinearHMM obj's underlying member method code with example usage: obj.rsample(sample_shape) and returns: x