Caffe2 - Python API
A deep learning, cross platform ML framework
cauchy.py
1 import math
2 from torch._six import inf, nan
3 from numbers import Number
4 
5 import torch
6 from torch.distributions import constraints
7 from torch.distributions.distribution import Distribution
8 from torch.distributions.utils import broadcast_all
9 
10 
12  r"""
13  Samples from a Cauchy (Lorentz) distribution. The distribution of the ratio of
14  independent normally distributed random variables with means `0` follows a
15  Cauchy distribution.
16 
17  Example::
18 
19  >>> m = Cauchy(torch.tensor([0.0]), torch.tensor([1.0]))
20  >>> m.sample() # sample from a Cauchy distribution with loc=0 and scale=1
21  tensor([ 2.3214])
22 
23  Args:
24  loc (float or Tensor): mode or median of the distribution.
25  scale (float or Tensor): half width at half maximum.
26  """
27  arg_constraints = {'loc': constraints.real, 'scale': constraints.positive}
28  support = constraints.real
29  has_rsample = True
30 
31  def __init__(self, loc, scale, validate_args=None):
32  self.loc, self.scale = broadcast_all(loc, scale)
33  if isinstance(loc, Number) and isinstance(scale, Number):
34  batch_shape = torch.Size()
35  else:
36  batch_shape = self.loc.size()
37  super(Cauchy, self).__init__(batch_shape, validate_args=validate_args)
38 
39  def expand(self, batch_shape, _instance=None):
40  new = self._get_checked_instance(Cauchy, _instance)
41  batch_shape = torch.Size(batch_shape)
42  new.loc = self.loc.expand(batch_shape)
43  new.scale = self.scale.expand(batch_shape)
44  super(Cauchy, new).__init__(batch_shape, validate_args=False)
45  new._validate_args = self._validate_args
46  return new
47 
48  @property
49  def mean(self):
50  return self.loc.new_tensor(nan).expand(self._extended_shape())
51 
52  @property
53  def variance(self):
54  return self.loc.new_tensor(inf).expand(self._extended_shape())
55 
56  def rsample(self, sample_shape=torch.Size()):
57  shape = self._extended_shape(sample_shape)
58  eps = self.loc.new(shape).cauchy_()
59  return self.loc + eps * self.scale
60 
61  def log_prob(self, value):
62  if self._validate_args:
63  self._validate_sample(value)
64  return -math.log(math.pi) - self.scale.log() - (1 + ((value - self.loc) / self.scale)**2).log()
65 
66  def cdf(self, value):
67  if self._validate_args:
68  self._validate_sample(value)
69  return torch.atan((value - self.loc) / self.scale) / math.pi + 0.5
70 
71  def icdf(self, value):
72  if self._validate_args:
73  self._validate_sample(value)
74  return torch.tan(math.pi * (value - 0.5)) * self.scale + self.loc
75 
76  def entropy(self):
77  return math.log(4 * math.pi) + self.scale.log()
def _get_checked_instance(self, cls, _instance=None)
def _extended_shape(self, sample_shape=torch.Size())