class_docstr: Auxiliary variable reparameterizer for symmetric
  :class:`~pyro.distributions.Stable` random variables (i.e. those for which
  ``skew=0``).
  
  This is useful in inference of symmetric
  :class:`~pyro.distributions.Stable` variables because the
  :meth:`~pyro.distributions.Stable.log_prob` is not implemented.
  
  This reparameterizes a symmetric :class:`~pyro.distributions.Stable` random
  variable as a totally-skewed (``skew=1``)
  :class:`~pyro.distributions.Stable` scale mixture of
  :class:`~pyro.distributions.Normal` random variables. See Proposition 3. of
  [1] (but note we differ since :class:`Stable` uses Nolan's continuous S0
  parameterization).
  
  [1] Alvaro Cartea and Sam Howison (2009)
      "Option Pricing with Levy-Stable Processes"
      https://pdfs.semanticscholar.org/4d66/c91b136b2a38117dd16c2693679f5341c616.pdf
class_docstr_tok: ["Auxiliary","variable","reparameterizer","for","symmetric",":","class",":","`","~pyro.distributions.Stable","`","random","variables","(","i.e",".","those","for","which","``","skew=0","``",")",".","This","is","useful","in","inference","of","symmetric",":","class",":","`","~pyro.distributions.Stable","`","variables","because","the",":","meth",":","`","~pyro.distributions.Stable.log_prob","`","is","not","implemented",".","This","reparameterizes","a","symmetric",":","class",":","`","~pyro.distributions.Stable","`","random","variable","as","a","totally-skewed","(","``","skew=1","``",")",":","class",":","`","~pyro.distributions.Stable","`","scale","mixture","of",":","class",":","`","~pyro.distributions.Normal","`","random","variables",".","See","Proposition","3.","of","[","1","]","(","but","note","we","differ","since",":","class",":","`","Stable","`","uses","Nolan","'s","continuous","S0","parameterization",")",".","[","1","]","Alvaro","Cartea","and","Sam","Howison","(","2009",")","``","Option","Pricing","with","Levy-Stable","Processes","''","https",":","\/\/pdfs.semanticscholar.org\/4d66\/c91b136b2a38117dd16c2693679f5341c616.pdf"]
code: def apply(self, msg):
      name = msg["name"]
      fn = msg["fn"]
      value = msg["value"]
      is_observed = msg["is_observed"]
  
      fn, event_dim = self._unwrap(fn)
      assert isinstance(fn, dist.Stable) and fn.coords == "S0"
      if is_validation_enabled():
          if not (fn.skew == 0).all():
              raise ValueError(
                  "SymmetricStableReparam found nonzero skew"
              )
          if not (fn.stability < 2).all():
              raise ValueError(
                  "SymmetricStableReparam found stability >= 2"
              )
  
      # Draw parameter-free noise.
      proto = fn.stability
      half_pi = proto.new_tensor(math.pi / 2)
      one = proto.new_ones(proto.shape)
      u = pyro.sample(
          "{}_uniform".format(name),
          self._wrap(
              dist.Uniform(-half_pi, half_pi).expand(proto.shape),
              event_dim,
          ),
      )
      e = pyro.sample(
          "{}_exponential".format(name),
          self._wrap(dist.Exponential(one), event_dim),
      )
  
      # Differentiably transform to scale drawn from a totally-skewed stable variable.
      a = fn.stability
      z = _unsafe_standard_stable(a / 2, 1, u, e, coords="S")
      assert (z >= 0).all()
      scale = (
          fn.scale
          * (math.pi / 4 * a).cos().pow(a.reciprocal())
          * z.sqrt()
      )
      scale = scale.clamp(min=torch.finfo(scale.dtype).tiny)
  
      # Construct a scaled Gaussian, using Stable(2,0,s,m) == Normal(m,s*sqrt(2)).
      new_fn = self._wrap(
          dist.Normal(fn.loc, scale * (2**0.5)), event_dim
      )
      return {"fn": new_fn, "value": value, "is_observed": is_observed}
  
file_path: pyro/pyro/infer/reparam/stable.py
imports: import math
  import torch
  import pyro
  import pyro.distributions
  from pyro.distributions.stable import _standard_stable, _unsafe_standard_stable
  from pyro.infer.util import is_validation_enabled
  from .reparam import Reparam
label_desc: Use image node_id 1 for calling the SymmetricStableReparam obj's underlying member method code with example usage: obj.apply(msg) and returns: dict