class_docstr: Construct for Markov chain of variables designed for efficient elimination of Markov
  dimensions using the parallel-scan algorithm. Whenever permissible,
  :class:`~pyro.contrib.funsor.vectorized_markov` is interchangeable with
  :class:`~pyro.contrib.funsor.markov`.
  
  The for loop generates both :class:`int` and 1-dimensional :class:`torch.Tensor` indices:
  :code:`(0, ..., history-1, torch.arange(0, size-history), ..., torch.arange(history, size))`.
  :class:`int` indices are used to initiate the Markov chain and :class:`torch.Tensor` indices
  are used to construct vectorized transition probabilities for efficient elimination by
  the parallel-scan algorithm.
  
  When ``history==0`` :class:`~pyro.contrib.funsor.vectorized_markov` behaves
  similar to :class:`~pyro.contrib.funsor.plate`.
  
  After the for loop is run, Markov variables are identified and then the ``step``
  information is constructed and added to the trace. ``step`` informs inference algorithms
  which variables belong to a Markov chain.
  
  .. code-block:: py
  
      data = torch.ones(3, dtype=torch.float)
  
      def model(data, vectorized=True):
  
          init = pyro.param("init", lambda: torch.rand(3), constraint=constraints.simplex)
          trans = pyro.param("trans", lambda: torch.rand((3, 3)), constraint=constraints.simplex)
          locs = pyro.param("locs", lambda: torch.rand(3,))
  
          markov_chain = \
              pyro.vectorized_markov(name="time", size=len(data), dim=-1) if vectorized \
              else pyro.markov(range(len(data)))
          for i in markov_chain:
              x_curr = pyro.sample("x_{}".format(i), dist.Categorical(
                  init if isinstance(i, int) and i < 1 else trans[x_prev]),
  
              pyro.sample("y_{}".format(i),
                          dist.Normal(Vindex(locs)[..., x_curr], 1.),
                          obs=data[i])
              x_prev = x_curr
  
      #  trace.nodes["time"]["value"]
      #  frozenset({('x_0', 'x_slice(0, 2, None)', 'x_slice(1, 3, None)')})
      #
      #  pyro.vectorized_markov trace
      #  ...
      #  Sample Sites:
      #      locs dist               | 3
      #          value               | 3
      #       log_prob               |
      #       x_0 dist               |
      #          value     3 1 1 1 1 |
      #       log_prob     3 1 1 1 1 |
      #       y_0 dist     3 1 1 1 1 |
      #          value               |
      #       log_prob     3 1 1 1 1 |
      #  x_slice(1, 3, None) dist   3 1 1 1 1 2 |
      #          value 3 1 1 1 1 1 1 |
      #       log_prob 3 3 1 1 1 1 2 |
      #  y_slice(1, 3, None) dist 3 1 1 1 1 1 2 |
      #          value             2 |
      #       log_prob 3 1 1 1 1 1 2 |
      #
      #  pyro.markov trace
      #  ...
      #  Sample Sites:
      #      locs dist             | 3
      #          value             | 3
      #       log_prob             |
      #       x_0 dist             |
      #          value   3 1 1 1 1 |
      #       log_prob   3 1 1 1 1 |
      #       y_0 dist   3 1 1 1 1 |
      #          value             |
      #       log_prob   3 1 1 1 1 |
      #       x_1 dist   3 1 1 1 1 |
      #          value 3 1 1 1 1 1 |
      #       log_prob 3 3 1 1 1 1 |
      #       y_1 dist 3 1 1 1 1 1 |
      #          value             |
      #       log_prob 3 1 1 1 1 1 |
      #       x_2 dist 3 1 1 1 1 1 |
      #          value   3 1 1 1 1 |
      #       log_prob 3 3 1 1 1 1 |
      #       y_2 dist   3 1 1 1 1 |
      #          value             |
      #       log_prob   3 1 1 1 1 |
  
  .. warning::  This is only valid if there is only one Markov
      dimension per branch.
  
  :param str name: A unique name of a Markov dimension to help inference algorithm
      eliminate variables in the Markov chain.
  :param int size: Length (size) of the Markov chain.
  :param int dim: An optional dimension to use for this Markov dimension.
      If specified, ``dim`` should be negative, i.e. should index from the
      right. If not specified, ``dim`` is set to the rightmost dim that is
      left of all enclosing :class:`~pyro.contrib.funsor.plate` contexts.
  :param int history: Memory (order) of the Markov chain. Also the number
      of previous contexts visible from the current context. Defaults to 1.
      If zero, this is similar to :class:`~pyro.contrib.funsor.plate`.
  :return: Returns both :class:`int` and 1-dimensional :class:`torch.Tensor` indices:
      ``(0, ..., history-1, torch.arange(size-history), ..., torch.arange(history, size))``.
class_docstr_tok: ["Construct","for","Markov","chain","of","variables","designed","for","efficient","elimination","of","Markov","dimensions","using","the","parallel-scan","algorithm",".","Whenever","permissible",",",":","class",":","`","~pyro.contrib.funsor.vectorized_markov","`","is","interchangeable","with",":","class",":","`","~pyro.contrib.funsor.markov","`",".","The","for","loop","generates","both",":","class",":","`","int","`","and","1-dimensional",":","class",":","`","torch.Tensor","`","indices",":",":","code",":","`","(","0",",","...",",","history-1",",","torch.arange","(","0",",","size-history",")",",","...",",","torch.arange","(","history",",","size",")",")","`",".",":","class",":","`","int","`","indices","are","used","to","initiate","the","Markov","chain","and",":","class",":","`","torch.Tensor","`","indices","are","used","to","construct","vectorized","transition","probabilities","for","efficient","elimination","by","the","parallel-scan","algorithm",".","When","``","history==0","``",":","class",":","`","~pyro.contrib.funsor.vectorized_markov","`","behaves","similar","to",":","class",":","`","~pyro.contrib.funsor.plate","`",".","After","the","for","loop","is","run",",","Markov","variables","are","identified","and","then","the","``","step","``","information","is","constructed","and","added","to","the","trace",".","``","step","``","informs","inference","algorithms","which","variables","belong","to","a","Markov","chain",".","..","code-block",":",":","py","data","=","torch.ones","(","3",",","dtype=torch.float",")","def","model","(","data",",","vectorized=True",")",":","init","=","pyro.param","(","``","init","''",",","lambda",":","torch.rand","(","3",")",",","constraint=constraints.simplex",")","trans","=","pyro.param","(","``","trans","''",",","lambda",":","torch.rand","(","(","3",",","3",")",")",",","constraint=constraints.simplex",")","locs","=","pyro.param","(","``","locs","''",",","lambda",":","torch.rand","(","3",",",")",")","markov_chain","=","\\","pyro.vectorized_markov","(","name=","''","time","''",",","size=len","(","data",")",",","dim=-1",")","if","vectorized","\\","else","pyro.markov","(","range","(","len","(","data",")",")",")","for","i","in","markov_chain",":","x_curr","=","pyro.sample","(","``","x_","{","}","''",".format","(","i",")",",","dist.Categorical","(","init","if","isinstance","(","i",",","int",")","and","i","<","1","else","trans","[","x_prev","]",")",",","pyro.sample","(","``","y_","{","}","''",".format","(","i",")",",","dist.Normal","(","Vindex","(","locs",")","[","...",",","x_curr","]",",","1",".",")",",","obs=data","[","i","]",")","x_prev","=","x_curr","#","trace.nodes","[","``","time","''","]","[","``","value","''","]","#","frozenset","(","{","(","'x_0","'",",","'x_slice","(","0",",","2",",","None",")","'",",","'x_slice","(","1",",","3",",","None",")","'",")","}",")","#","#","pyro.vectorized_markov","trace","#","...","#","Sample","Sites",":","#","locs","dist","|","3","#","value","|","3","#","log_prob","|","#","x_0","dist","|","#","value","3","1","1","1","1","|","#","log_prob","3","1","1","1","1","|","#","y_0","dist","3","1","1","1","1","|","#","value","|","#","log_prob","3","1","1","1","1","|","#","x_slice","(","1",",","3",",","None",")","dist","3","1","1","1","1","2","|","#","value","3","1","1","1","1","1","1","|","#","log_prob","3","3","1","1","1","1","2","|","#","y_slice","(","1",",","3",",","None",")","dist","3","1","1","1","1","1","2","|","#","value","2","|","#","log_prob","3","1","1","1","1","1","2","|","#","#","pyro.markov","trace","#","...","#","Sample","Sites",":","#","locs","dist","|","3","#","value","|","3","#","log_prob","|","#","x_0","dist","|","#","value","3","1","1","1","1","|","#","log_prob","3","1","1","1","1","|","#","y_0","dist","3","1","1","1","1","|","#","value","|","#","log_prob","3","1","1","1","1","|","#","x_1","dist","3","1","1","1","1","|","#","value","3","1","1","1","1","1","|","#","log_prob","3","3","1","1","1","1","|","#","y_1","dist","3","1","1","1","1","1","|","#","value","|","#","log_prob","3","1","1","1","1","1","|","#","x_2","dist","3","1","1","1","1","1","|","#","value","3","1","1","1","1","|","#","log_prob","3","3","1","1","1","1","|","#","y_2","dist","3","1","1","1","1","|","#","value","|","#","log_prob","3","1","1","1","1","|","..","warning",":",":","This","is","only","valid","if","there","is","only","one","Markov","dimension","per","branch",".",":","param","str","name",":","A","unique","name","of","a","Markov","dimension","to","help","inference","algorithm","eliminate","variables","in","the","Markov","chain",".",":","param","int","size",":","Length","(","size",")","of","the","Markov","chain",".",":","param","int","dim",":","An","optional","dimension","to","use","for","this","Markov","dimension",".","If","specified",",","``","dim","``","should","be","negative",",","i.e",".","should","index","from","the","right",".","If","not","specified",",","``","dim","``","is","set","to","the","rightmost","dim","that","is","left","of","all","enclosing",":","class",":","`","~pyro.contrib.funsor.plate","`","contexts",".",":","param","int","history",":","Memory","(","order",")","of","the","Markov","chain",".","Also","the","number","of","previous","contexts","visible","from","the","current","context",".","Defaults","to","1",".","If","zero",",","this","is","similar","to",":","class",":","`","~pyro.contrib.funsor.plate","`",".",":","return",":","Returns","both",":","class",":","`","int","`","and","1-dimensional",":","class",":","`","torch.Tensor","`","indices",":","``","(","0",",","...",",","history-1",",","torch.arange","(","size-history",")",",","...",",","torch.arange","(","history",",","size",")",")","``","."]
docstr: At the last step of the for loop identify markov variables.
code: def _pyro_post_sample(self, msg):
      """
      At the last step of the for loop identify markov variables.
      """
      if type(msg["fn"]).__name__ == "_Subsample":
          return
      # if last step in the for loop
      if str(self._suffix) == str(self._suffixes[-1]):
          funsor_log_prob = (
              msg["funsor"]["log_prob"]
              if "log_prob" in msg.get("funsor", {})
              else to_funsor(
                  msg["fn"].log_prob(msg["value"]), output=funsor.Real
              )
          )
          # for auxiliary sites in the log_prob
          for name in set(funsor_log_prob.inputs) & set(
              self._auxiliary_to_markov
          ):
              # add markov var name prefix to self._markov_vars
              markov_var = self._auxiliary_to_markov[name]
              self._markov_vars.add(markov_var)
  
imports: from collections import OrderedDict
  from numbers import Number
  import funsor
  from pyro.contrib.funsor.handlers.named_messenger import DimRequest, DimType, GlobalNamedMessenger, NamedMessenger
  from pyro.contrib.funsor.handlers.primitives import to_data, to_funsor
  from pyro.distributions.util import copy_docs_from
  from pyro.poutine.broadcast_messenger import BroadcastMessenger
  from pyro.poutine.indep_messenger import CondIndepStackFrame
  from pyro.poutine.messenger import Messenger
  from pyro.poutine.runtime import effectful
  from pyro.poutine.subsample_messenger import SubsampleMessenger
  from pyro.util import ignore_jit_warnings
label_desc: Use image node_id 5 for calling the VectorizedMarkovMessenger obj's underlying member method code with example usage: obj._pyro_post_sample(msg) without return types