prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Incorrect result from Delta's batch_log_pdf
  It looks like there may be a bug in Delta's `batch_log_pdf` method. When the value we're computing the log prob of doesn't match the parameter I expect `batch_log_pdf` to return `-inf` but it doesn't. For example:
  
  ```
  x = Variable(torch.Tensor([[1.0]]))
  y = Variable(torch.Tensor([[2.0]]))
  
  # This is OK, it returns zero as expected:
  print(Delta(x).batch_log_pdf(x))
  
  # Here I expect -inf, but get 2.5500e+08
  print(Delta(x).batch_log_pdf(y))
  ```
  
  `log_pdf` works as expected.
  
  (This isn't high priority for me.)
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pyro/distributions/__init__.py`
  Content:
  ```
  1 # abstract base class
  2 from pyro.distributions.bernoulli import Bernoulli
  3 from pyro.distributions.beta import Beta
  4 from pyro.distributions.categorical import Categorical
  5 from pyro.distributions.cauchy import Cauchy
  6 from pyro.distributions.half_cauchy import HalfCauchy
  7 from pyro.distributions.delta import Delta
  8 from pyro.distributions.distribution import Distribution  # noqa: F401
  9 # specific distributions
  10 from pyro.distributions.diag_normal import DiagNormal
  11 from pyro.distributions.dirichlet import Dirichlet
  12 from pyro.distributions.exponential import Exponential
  13 from pyro.distributions.gamma import Gamma
  14 from pyro.distributions.log_normal import LogNormal
  15 from pyro.distributions.multinomial import Multinomial
  16 from pyro.distributions.poisson import Poisson
  17 from pyro.distributions.random_primitive import RandomPrimitive
  18 from pyro.distributions.uniform import Uniform
  19 
  20 # function aliases
  21 diagnormal = DiagNormal()
  22 lognormal = RandomPrimitive(LogNormal)
  23 categorical = Categorical()
  24 bernoulli = RandomPrimitive(Bernoulli)
  25 beta = RandomPrimitive(Beta)
  26 delta = Delta()
  27 exponential = RandomPrimitive(Exponential)
  28 gamma = RandomPrimitive(Gamma)
  29 multinomial = RandomPrimitive(Multinomial)
  30 poisson = RandomPrimitive(Poisson)
  31 uniform = RandomPrimitive(Uniform)
  32 dirichlet = RandomPrimitive(Dirichlet)
  33 cauchy = RandomPrimitive(Cauchy)
  34 halfcauchy = RandomPrimitive(HalfCauchy)
  35
  ```
  
  Path: `pyro/distributions/delta.py`
  Content:
  ```
  1 import torch
  2 from torch.autograd import Variable
  3 
  4 from pyro.distributions.distribution import Distribution
  5 
  6 
  7 class Delta(Distribution):
  8     """
  9     :param v: support element *(any)*
  10 
  11     Discrete distribution that assigns probability one to the single element in
  12     its support. Delta distribution parameterized by a random choice should not
  13     be used with MCMC based inference, as doing so produces incorrect results.
  14     """
  15     enumerable = True
  16 
  17     def _sanitize_input(self, v):
  18         if v is not None:
  19             # stateless distribution
  20             return v
  21         elif self.v is not None:
  22             # stateful distribution
  23             return self.v
  24         else:
  25             raise ValueError("Parameter(s) were None")
  26 
  27     def __init__(self, v=None, batch_size=1, *args, **kwargs):
  28         """
  29         Params:
  30           `v` - value
  31         """
  32         self.v = v
  33         if v is not None:
  34             if v.dim() == 1 and batch_size > 1:
  35                 self.v = v.expand(v, v.size(0))
  36         super(Delta, self).__init__(*args, **kwargs)
  37 
  38     def sample(self, v=None):
  39         v = self._sanitize_input(v)
  40         if isinstance(v, Variable):
  41             return v
  42         return Variable(v)
  43 
  44     def batch_log_pdf(self, x, v=None, batch_size=1):
  45         v = self._sanitize_input(v)
  46         if x.dim == 1:
  47             x = x.expand(batch_size, x.size(0))
  48         return (torch.eq(x, v.expand_as(x)) - 1).float() * 999999
  49 
  50     def log_pdf(self, x, v=None, *args, **kwargs):
  51         v = self._sanitize_input(v)
  52         if torch.equal(x.data, v.data.expand_as(x.data)):
  53             return Variable(torch.zeros(1).type_as(v.data))
  54         return Variable(torch.Tensor([-float("inf")]).type_as(v.data))
  55 
  56     def support(self, v=None):
  57         """
  58         Returns the delta distribution's support, as a tensor along the first dimension.
  59 
  60         :param v: torch variable where each element of the tensor represents the point at
  61             which the delta distribution is concentrated.
  62         :return: torch variable enumerating the support of the delta distribution.
  63         :rtype: torch.autograd.Variable.
  64         """
  65         v = self._sanitize_input(v)
  66         # univariate case
  67         return Variable(v.data)
  68
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pyro/distributions/__init__.py b/pyro/distributions/__init__.py
  --- a/pyro/distributions/__init__.py
  +++ b/pyro/distributions/__init__.py
  @@ -23,7 +23,7 @@
   categorical = Categorical()
   bernoulli = RandomPrimitive(Bernoulli)
   beta = RandomPrimitive(Beta)
  -delta = Delta()
  +delta = RandomPrimitive(Delta)
   exponential = RandomPrimitive(Exponential)
   gamma = RandomPrimitive(Gamma)
   multinomial = RandomPrimitive(Multinomial)
  diff --git a/pyro/distributions/delta.py b/pyro/distributions/delta.py
  --- a/pyro/distributions/delta.py
  +++ b/pyro/distributions/delta.py
  @@ -14,44 +14,40 @@
       """
       enumerable = True
   
  -    def _sanitize_input(self, v):
  -        if v is not None:
  -            # stateless distribution
  -            return v
  -        elif self.v is not None:
  -            # stateful distribution
  -            return self.v
  -        else:
  -            raise ValueError("Parameter(s) were None")
  -
  -    def __init__(self, v=None, batch_size=1, *args, **kwargs):
  +    def __init__(self, v, batch_size=None, *args, **kwargs):
           """
           Params:
             `v` - value
           """
           self.v = v
  -        if v is not None:
  -            if v.dim() == 1 and batch_size > 1:
  -                self.v = v.expand(v, v.size(0))
  +        if not isinstance(self.v, Variable):
  +            self.v = Variable(self.v)
  +        if v.dim() == 1 and batch_size is not None:
  +            self.v = v.expand(v, v.size(0))
           super(Delta, self).__init__(*args, **kwargs)
   
  -    def sample(self, v=None):
  -        v = self._sanitize_input(v)
  -        if isinstance(v, Variable):
  -            return v
  -        return Variable(v)
  +    def batch_shape(self, x=None):
  +        event_dim = 1
  +        v = self.v
  +        if x is not None and x.size() != v.size():
  +            v = self.v.expand_as(x)
  +        return v.size()[:-event_dim]
  +
  +    def event_shape(self):
  +        event_dim = 1
  +        return self.v.size()[-event_dim:]
  +
  +    def shape(self, x=None):
  +        return self.batch_shape(x) + self.event_shape()
   
  -    def batch_log_pdf(self, x, v=None, batch_size=1):
  -        v = self._sanitize_input(v)
  -        if x.dim == 1:
  -            x = x.expand(batch_size, x.size(0))
  -        return (torch.eq(x, v.expand_as(x)) - 1).float() * 999999
  +    def sample(self):
  +        return self.v
   
  -    def log_pdf(self, x, v=None, *args, **kwargs):
  -        v = self._sanitize_input(v)
  -        if torch.equal(x.data, v.data.expand_as(x.data)):
  -            return Variable(torch.zeros(1).type_as(v.data))
  -        return Variable(torch.Tensor([-float("inf")]).type_as(v.data))
  +    def batch_log_pdf(self, x):
  +        v = self.v
  +        if x.size() != v.size():
  +            v = v.expand_as(x)
  +        return torch.sum(torch.eq(x, v).float().log(), -1)
   
       def support(self, v=None):
           """
  @@ -62,6 +58,4 @@
           :return: torch variable enumerating the support of the delta distribution.
           :rtype: torch.autograd.Variable.
           """
  -        v = self._sanitize_input(v)
  -        # univariate case
  -        return Variable(v.data)
  +        return Variable(self.v.data)
  
verification_info: {"golden_diff": "diff --git a/pyro/distributions/__init__.py b/pyro/distributions/__init__.py\n--- a/pyro/distributions/__init__.py\n+++ b/pyro/distributions/__init__.py\n@@ -23,7 +23,7 @@\n categorical = Categorical()\n bernoulli = RandomPrimitive(Bernoulli)\n beta = RandomPrimitive(Beta)\n-delta = Delta()\n+delta = RandomPrimitive(Delta)\n exponential = RandomPrimitive(Exponential)\n gamma = RandomPrimitive(Gamma)\n multinomial = RandomPrimitive(Multinomial)\ndiff --git a/pyro/distributions/delta.py b/pyro/distributions/delta.py\n--- a/pyro/distributions/delta.py\n+++ b/pyro/distributions/delta.py\n@@ -14,44 +14,40 @@\n     \"\"\"\n     enumerable = True\n \n-    def _sanitize_input(self, v):\n-        if v is not None:\n-            # stateless distribution\n-            return v\n-        elif self.v is not None:\n-            # stateful distribution\n-            return self.v\n-        else:\n-            raise ValueError(\"Parameter(s) were None\")\n-\n-    def __init__(self, v=None, batch_size=1, *args, **kwargs):\n+    def __init__(self, v, batch_size=None, *args, **kwargs):\n         \"\"\"\n         Params:\n           `v` - value\n         \"\"\"\n         self.v = v\n-        if v is not None:\n-            if v.dim() == 1 and batch_size > 1:\n-                self.v = v.expand(v, v.size(0))\n+        if not isinstance(self.v, Variable):\n+            self.v = Variable(self.v)\n+        if v.dim() == 1 and batch_size is not None:\n+            self.v = v.expand(v, v.size(0))\n         super(Delta, self).__init__(*args, **kwargs)\n \n-    def sample(self, v=None):\n-        v = self._sanitize_input(v)\n-        if isinstance(v, Variable):\n-            return v\n-        return Variable(v)\n+    def batch_shape(self, x=None):\n+        event_dim = 1\n+        v = self.v\n+        if x is not None and x.size() != v.size():\n+            v = self.v.expand_as(x)\n+        return v.size()[:-event_dim]\n+\n+    def event_shape(self):\n+        event_dim = 1\n+        return self.v.size()[-event_dim:]\n+\n+    def shape(self, x=None):\n+        return self.batch_shape(x) + self.event_shape()\n \n-    def batch_log_pdf(self, x, v=None, batch_size=1):\n-        v = self._sanitize_input(v)\n-        if x.dim == 1:\n-            x = x.expand(batch_size, x.size(0))\n-        return (torch.eq(x, v.expand_as(x)) - 1).float() * 999999\n+    def sample(self):\n+        return self.v\n \n-    def log_pdf(self, x, v=None, *args, **kwargs):\n-        v = self._sanitize_input(v)\n-        if torch.equal(x.data, v.data.expand_as(x.data)):\n-            return Variable(torch.zeros(1).type_as(v.data))\n-        return Variable(torch.Tensor([-float(\"inf\")]).type_as(v.data))\n+    def batch_log_pdf(self, x):\n+        v = self.v\n+        if x.size() != v.size():\n+            v = v.expand_as(x)\n+        return torch.sum(torch.eq(x, v).float().log(), -1)\n \n     def support(self, v=None):\n         \"\"\"\n@@ -62,6 +58,4 @@\n         :return: torch variable enumerating the support of the delta distribution.\n         :rtype: torch.autograd.Variable.\n         \"\"\"\n-        v = self._sanitize_input(v)\n-        # univariate case\n-        return Variable(v.data)\n+        return Variable(self.v.data)\n", "issue": "Incorrect result from Delta's batch_log_pdf\nIt looks like there may be a bug in Delta's `batch_log_pdf` method. When the value we're computing the log prob of doesn't match the parameter I expect `batch_log_pdf` to return `-inf` but it doesn't. For example:\r\n\r\n```\r\nx = Variable(torch.Tensor([[1.0]]))\r\ny = Variable(torch.Tensor([[2.0]]))\r\n\r\n# This is OK, it returns zero as expected:\r\nprint(Delta(x).batch_log_pdf(x))\r\n\r\n# Here I expect -inf, but get 2.5500e+08\r\nprint(Delta(x).batch_log_pdf(y))\r\n```\r\n\r\n`log_pdf` works as expected.\r\n\r\n(This isn't high priority for me.)\n", "before_files": [{"content": "# abstract base class\nfrom pyro.distributions.bernoulli import Bernoulli\nfrom pyro.distributions.beta import Beta\nfrom pyro.distributions.categorical import Categorical\nfrom pyro.distributions.cauchy import Cauchy\nfrom pyro.distributions.half_cauchy import HalfCauchy\nfrom pyro.distributions.delta import Delta\nfrom pyro.distributions.distribution import Distribution  # noqa: F401\n# specific distributions\nfrom pyro.distributions.diag_normal import DiagNormal\nfrom pyro.distributions.dirichlet import Dirichlet\nfrom pyro.distributions.exponential import Exponential\nfrom pyro.distributions.gamma import Gamma\nfrom pyro.distributions.log_normal import LogNormal\nfrom pyro.distributions.multinomial import Multinomial\nfrom pyro.distributions.poisson import Poisson\nfrom pyro.distributions.random_primitive import RandomPrimitive\nfrom pyro.distributions.uniform import Uniform\n\n# function aliases\ndiagnormal = DiagNormal()\nlognormal = RandomPrimitive(LogNormal)\ncategorical = Categorical()\nbernoulli = RandomPrimitive(Bernoulli)\nbeta = RandomPrimitive(Beta)\ndelta = Delta()\nexponential = RandomPrimitive(Exponential)\ngamma = RandomPrimitive(Gamma)\nmultinomial = RandomPrimitive(Multinomial)\npoisson = RandomPrimitive(Poisson)\nuniform = RandomPrimitive(Uniform)\ndirichlet = RandomPrimitive(Dirichlet)\ncauchy = RandomPrimitive(Cauchy)\nhalfcauchy = RandomPrimitive(HalfCauchy)\n", "path": "pyro/distributions/__init__.py"}, {"content": "import torch\nfrom torch.autograd import Variable\n\nfrom pyro.distributions.distribution import Distribution\n\n\nclass Delta(Distribution):\n    \"\"\"\n    :param v: support element *(any)*\n\n    Discrete distribution that assigns probability one to the single element in\n    its support. Delta distribution parameterized by a random choice should not\n    be used with MCMC based inference, as doing so produces incorrect results.\n    \"\"\"\n    enumerable = True\n\n    def _sanitize_input(self, v):\n        if v is not None:\n            # stateless distribution\n            return v\n        elif self.v is not None:\n            # stateful distribution\n            return self.v\n        else:\n            raise ValueError(\"Parameter(s) were None\")\n\n    def __init__(self, v=None, batch_size=1, *args, **kwargs):\n        \"\"\"\n        Params:\n          `v` - value\n        \"\"\"\n        self.v = v\n        if v is not None:\n            if v.dim() == 1 and batch_size > 1:\n                self.v = v.expand(v, v.size(0))\n        super(Delta, self).__init__(*args, **kwargs)\n\n    def sample(self, v=None):\n        v = self._sanitize_input(v)\n        if isinstance(v, Variable):\n            return v\n        return Variable(v)\n\n    def batch_log_pdf(self, x, v=None, batch_size=1):\n        v = self._sanitize_input(v)\n        if x.dim == 1:\n            x = x.expand(batch_size, x.size(0))\n        return (torch.eq(x, v.expand_as(x)) - 1).float() * 999999\n\n    def log_pdf(self, x, v=None, *args, **kwargs):\n        v = self._sanitize_input(v)\n        if torch.equal(x.data, v.data.expand_as(x.data)):\n            return Variable(torch.zeros(1).type_as(v.data))\n        return Variable(torch.Tensor([-float(\"inf\")]).type_as(v.data))\n\n    def support(self, v=None):\n        \"\"\"\n        Returns the delta distribution's support, as a tensor along the first dimension.\n\n        :param v: torch variable where each element of the tensor represents the point at\n            which the delta distribution is concentrated.\n        :return: torch variable enumerating the support of the delta distribution.\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        v = self._sanitize_input(v)\n        # univariate case\n        return Variable(v.data)\n", "path": "pyro/distributions/delta.py"}], "after_files": [{"content": "# abstract base class\nfrom pyro.distributions.bernoulli import Bernoulli\nfrom pyro.distributions.beta import Beta\nfrom pyro.distributions.categorical import Categorical\nfrom pyro.distributions.cauchy import Cauchy\nfrom pyro.distributions.half_cauchy import HalfCauchy\nfrom pyro.distributions.delta import Delta\nfrom pyro.distributions.distribution import Distribution  # noqa: F401\n# specific distributions\nfrom pyro.distributions.diag_normal import DiagNormal\nfrom pyro.distributions.dirichlet import Dirichlet\nfrom pyro.distributions.exponential import Exponential\nfrom pyro.distributions.gamma import Gamma\nfrom pyro.distributions.log_normal import LogNormal\nfrom pyro.distributions.multinomial import Multinomial\nfrom pyro.distributions.poisson import Poisson\nfrom pyro.distributions.random_primitive import RandomPrimitive\nfrom pyro.distributions.uniform import Uniform\n\n# function aliases\ndiagnormal = DiagNormal()\nlognormal = RandomPrimitive(LogNormal)\ncategorical = Categorical()\nbernoulli = RandomPrimitive(Bernoulli)\nbeta = RandomPrimitive(Beta)\ndelta = RandomPrimitive(Delta)\nexponential = RandomPrimitive(Exponential)\ngamma = RandomPrimitive(Gamma)\nmultinomial = RandomPrimitive(Multinomial)\npoisson = RandomPrimitive(Poisson)\nuniform = RandomPrimitive(Uniform)\ndirichlet = RandomPrimitive(Dirichlet)\ncauchy = RandomPrimitive(Cauchy)\nhalfcauchy = RandomPrimitive(HalfCauchy)\n", "path": "pyro/distributions/__init__.py"}, {"content": "import torch\nfrom torch.autograd import Variable\n\nfrom pyro.distributions.distribution import Distribution\n\n\nclass Delta(Distribution):\n    \"\"\"\n    :param v: support element *(any)*\n\n    Discrete distribution that assigns probability one to the single element in\n    its support. Delta distribution parameterized by a random choice should not\n    be used with MCMC based inference, as doing so produces incorrect results.\n    \"\"\"\n    enumerable = True\n\n    def __init__(self, v, batch_size=None, *args, **kwargs):\n        \"\"\"\n        Params:\n          `v` - value\n        \"\"\"\n        self.v = v\n        if not isinstance(self.v, Variable):\n            self.v = Variable(self.v)\n        if v.dim() == 1 and batch_size is not None:\n            self.v = v.expand(v, v.size(0))\n        super(Delta, self).__init__(*args, **kwargs)\n\n    def batch_shape(self, x=None):\n        event_dim = 1\n        v = self.v\n        if x is not None and x.size() != v.size():\n            v = self.v.expand_as(x)\n        return v.size()[:-event_dim]\n\n    def event_shape(self):\n        event_dim = 1\n        return self.v.size()[-event_dim:]\n\n    def shape(self, x=None):\n        return self.batch_shape(x) + self.event_shape()\n\n    def sample(self):\n        return self.v\n\n    def batch_log_pdf(self, x):\n        v = self.v\n        if x.size() != v.size():\n            v = v.expand_as(x)\n        return torch.sum(torch.eq(x, v).float().log(), -1)\n\n    def support(self, v=None):\n        \"\"\"\n        Returns the delta distribution's support, as a tensor along the first dimension.\n\n        :param v: torch variable where each element of the tensor represents the point at\n            which the delta distribution is concentrated.\n        :return: torch variable enumerating the support of the delta distribution.\n        :rtype: torch.autograd.Variable.\n        \"\"\"\n        return Variable(self.v.data)\n", "path": "pyro/distributions/delta.py"}]}