prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Linear kernel's variance prior is broken
  Repro: 
  [linear_kernel_prior_issue.ipynb.txt](https://github.com/cornellius-gp/gpytorch/files/2979717/linear_kernel_prior_issue.ipynb.txt)
  
  
  </issue>
  <code>
  [start of gpytorch/kernels/linear_kernel.py]
  1 #!/usr/bin/env python3
  2 
  3 import torch
  4 from .kernel import Kernel
  5 from ..lazy import MatmulLazyTensor, RootLazyTensor
  6 
  7 
  8 class LinearKernel(Kernel):
  9     r"""
  10     Computes a covariance matrix based on the Linear kernel
  11     between inputs :math:`\mathbf{x_1}` and :math:`\mathbf{x_2}`:
  12 
  13     .. math::
  14         \begin{equation*}
  15             k_\text{Linear}(\mathbf{x_1}, \mathbf{x_2}) = (\mathbf{x_1} - \mathbf{o})^\top
  16             (\mathbf{x_2} - \mathbf{o}) + v.
  17         \end{equation*}
  18 
  19     where
  20 
  21     * :math:`\mathbf o` is an :attr:`offset` parameter.
  22     * :math:`v` is a :attr:`variance` parameter.
  23 
  24 
  25     .. note::
  26 
  27         To implement this efficiently, we use a :obj:`gpytorch.lazy.RootLazyTensor` during training and a
  28         :class:`gpytorch.lazy.MatmulLazyTensor` during test. These lazy tensors represent matrices of the form
  29         :math:`K = XX^{\top}` and :math:`K = XZ^{\top}`. This makes inference
  30         efficient because a matrix-vector product :math:`Kv` can be computed as
  31         :math:`Kv=X(X^{\top}v)`, where the base multiply :math:`Xv` takes only
  32         :math:`O(nd)` time and space.
  33 
  34     Args:
  35         :attr:`num_dimensions` (int):
  36             Number of data dimensions to expect. This
  37             is necessary to create the offset parameter.
  38         :attr:`variance_prior` (:class:`gpytorch.priors.Prior`):
  39             Prior over the variance parameter (default `None`).
  40         :attr:`offset_prior` (:class:`gpytorch.priors.Prior`):
  41             Prior over the offset parameter (default `None`).
  42         :attr:`active_dims` (list):
  43             List of data dimensions to operate on.
  44             `len(active_dims)` should equal `num_dimensions`.
  45     """
  46 
  47     def __init__(self, num_dimensions, variance_prior=None, active_dims=None):
  48         super(LinearKernel, self).__init__(active_dims=active_dims)
  49         self.register_parameter(name="raw_variance", parameter=torch.nn.Parameter(torch.zeros(1)))
  50         self.register_parameter(name="offset", parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions)))
  51         if variance_prior is not None:
  52             self.register_prior("variance_prior", variance_prior, "variance")
  53 
  54     @property
  55     def variance(self):
  56         return self._param_transform(self.raw_variance)
  57 
  58     @variance.setter
  59     def variance(self, value):
  60         self._set_variance(value)
  61 
  62     def _set_variance(self, value):
  63         if not torch.is_tensor(value):
  64             value = torch.tensor(value)
  65         self.initialize(raw_variance=self._inv_param_transform(value))
  66 
  67     def forward(self, x1, x2, diag=False, batch_dims=None, **params):
  68         x1_ = x1 * self.variance.sqrt()
  69         if batch_dims == (0, 2):
  70             x1_ = x1_.view(x1_.size(0), x1_.size(1), -1, 1)
  71             x1_ = x1_.permute(0, 2, 1, 3).contiguous()
  72             x1_ = x1_.view(-1, x1_.size(-2), x1_.size(-1))
  73 
  74         if x1.size() == x2.size() and torch.equal(x1, x2):
  75             # Use RootLazyTensor when x1 == x2 for efficiency when composing
  76             # with other kernels
  77             prod = RootLazyTensor(x1_)
  78 
  79         else:
  80             x2_ = x2 * self.variance.sqrt()
  81             if batch_dims == (0, 2):
  82                 x2_ = x2_.view(x2_.size(0), x2_.size(1), -1, 1)
  83                 x2_ = x2_.permute(0, 2, 1, 3).contiguous()
  84                 x2_ = x2_.view(-1, x2_.size(-2), x2_.size(-1))
  85 
  86             prod = MatmulLazyTensor(x1_, x2_.transpose(2, 1))
  87 
  88         return prod
  89
  [end of gpytorch/kernels/linear_kernel.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/gpytorch/kernels/linear_kernel.py b/gpytorch/kernels/linear_kernel.py
  --- a/gpytorch/kernels/linear_kernel.py
  +++ b/gpytorch/kernels/linear_kernel.py
  @@ -1,6 +1,7 @@
   #!/usr/bin/env python3
   
   import torch
  +import warnings
   from .kernel import Kernel
   from ..lazy import MatmulLazyTensor, RootLazyTensor
   
  @@ -12,13 +13,12 @@
   
       .. math::
           \begin{equation*}
  -            k_\text{Linear}(\mathbf{x_1}, \mathbf{x_2}) = (\mathbf{x_1} - \mathbf{o})^\top
  -            (\mathbf{x_2} - \mathbf{o}) + v.
  +            k_\text{Linear}(\mathbf{x_1}, \mathbf{x_2}) = v\mathbf{x_1}^\top
  +            \mathbf{x_2}.
           \end{equation*}
   
       where
   
  -    * :math:`\mathbf o` is an :attr:`offset` parameter.
       * :math:`v` is a :attr:`variance` parameter.
   
   
  @@ -32,24 +32,37 @@
           :math:`O(nd)` time and space.
   
       Args:
  -        :attr:`num_dimensions` (int):
  -            Number of data dimensions to expect. This
  -            is necessary to create the offset parameter.
           :attr:`variance_prior` (:class:`gpytorch.priors.Prior`):
               Prior over the variance parameter (default `None`).
  -        :attr:`offset_prior` (:class:`gpytorch.priors.Prior`):
  -            Prior over the offset parameter (default `None`).
           :attr:`active_dims` (list):
               List of data dimensions to operate on.
               `len(active_dims)` should equal `num_dimensions`.
       """
   
  -    def __init__(self, num_dimensions, variance_prior=None, active_dims=None):
  +    def __init__(self, num_dimensions=None, offset_prior=None, variance_prior=None, active_dims=None):
           super(LinearKernel, self).__init__(active_dims=active_dims)
  +        if num_dimensions is not None:
  +            warnings.warn(
  +                "The `num_dimensions` argument is deprecated and no longer used.",
  +                DeprecationWarning
  +            )
  +            self.register_parameter(
  +                name="offset",
  +                parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions))
  +            )
  +        if offset_prior is not None:
  +            warnings.warn(
  +                "The `offset_prior` argument is deprecated and no longer used.",
  +                DeprecationWarning
  +            )
           self.register_parameter(name="raw_variance", parameter=torch.nn.Parameter(torch.zeros(1)))
  -        self.register_parameter(name="offset", parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions)))
           if variance_prior is not None:
  -            self.register_prior("variance_prior", variance_prior, "variance")
  +            self.register_prior(
  +                "variance_prior",
  +                variance_prior,
  +                lambda: self.variance,
  +                lambda v: self._set_variance(v)
  +            )
   
       @property
       def variance(self):
  
verification_info: {"golden_diff": "diff --git a/gpytorch/kernels/linear_kernel.py b/gpytorch/kernels/linear_kernel.py\n--- a/gpytorch/kernels/linear_kernel.py\n+++ b/gpytorch/kernels/linear_kernel.py\n@@ -1,6 +1,7 @@\n #!/usr/bin/env python3\n \n import torch\n+import warnings\n from .kernel import Kernel\n from ..lazy import MatmulLazyTensor, RootLazyTensor\n \n@@ -12,13 +13,12 @@\n \n     .. math::\n         \\begin{equation*}\n-            k_\\text{Linear}(\\mathbf{x_1}, \\mathbf{x_2}) = (\\mathbf{x_1} - \\mathbf{o})^\\top\n-            (\\mathbf{x_2} - \\mathbf{o}) + v.\n+            k_\\text{Linear}(\\mathbf{x_1}, \\mathbf{x_2}) = v\\mathbf{x_1}^\\top\n+            \\mathbf{x_2}.\n         \\end{equation*}\n \n     where\n \n-    * :math:`\\mathbf o` is an :attr:`offset` parameter.\n     * :math:`v` is a :attr:`variance` parameter.\n \n \n@@ -32,24 +32,37 @@\n         :math:`O(nd)` time and space.\n \n     Args:\n-        :attr:`num_dimensions` (int):\n-            Number of data dimensions to expect. This\n-            is necessary to create the offset parameter.\n         :attr:`variance_prior` (:class:`gpytorch.priors.Prior`):\n             Prior over the variance parameter (default `None`).\n-        :attr:`offset_prior` (:class:`gpytorch.priors.Prior`):\n-            Prior over the offset parameter (default `None`).\n         :attr:`active_dims` (list):\n             List of data dimensions to operate on.\n             `len(active_dims)` should equal `num_dimensions`.\n     \"\"\"\n \n-    def __init__(self, num_dimensions, variance_prior=None, active_dims=None):\n+    def __init__(self, num_dimensions=None, offset_prior=None, variance_prior=None, active_dims=None):\n         super(LinearKernel, self).__init__(active_dims=active_dims)\n+        if num_dimensions is not None:\n+            warnings.warn(\n+                \"The `num_dimensions` argument is deprecated and no longer used.\",\n+                DeprecationWarning\n+            )\n+            self.register_parameter(\n+                name=\"offset\",\n+                parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions))\n+            )\n+        if offset_prior is not None:\n+            warnings.warn(\n+                \"The `offset_prior` argument is deprecated and no longer used.\",\n+                DeprecationWarning\n+            )\n         self.register_parameter(name=\"raw_variance\", parameter=torch.nn.Parameter(torch.zeros(1)))\n-        self.register_parameter(name=\"offset\", parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions)))\n         if variance_prior is not None:\n-            self.register_prior(\"variance_prior\", variance_prior, \"variance\")\n+            self.register_prior(\n+                \"variance_prior\",\n+                variance_prior,\n+                lambda: self.variance,\n+                lambda v: self._set_variance(v)\n+            )\n \n     @property\n     def variance(self):\n", "issue": "Linear kernel's variance prior is broken\nRepro: \r\n[linear_kernel_prior_issue.ipynb.txt](https://github.com/cornellius-gp/gpytorch/files/2979717/linear_kernel_prior_issue.ipynb.txt)\r\n\n", "before_files": [{"content": "#!/usr/bin/env python3\n\nimport torch\nfrom .kernel import Kernel\nfrom ..lazy import MatmulLazyTensor, RootLazyTensor\n\n\nclass LinearKernel(Kernel):\n    r\"\"\"\n    Computes a covariance matrix based on the Linear kernel\n    between inputs :math:`\\mathbf{x_1}` and :math:`\\mathbf{x_2}`:\n\n    .. math::\n        \\begin{equation*}\n            k_\\text{Linear}(\\mathbf{x_1}, \\mathbf{x_2}) = (\\mathbf{x_1} - \\mathbf{o})^\\top\n            (\\mathbf{x_2} - \\mathbf{o}) + v.\n        \\end{equation*}\n\n    where\n\n    * :math:`\\mathbf o` is an :attr:`offset` parameter.\n    * :math:`v` is a :attr:`variance` parameter.\n\n\n    .. note::\n\n        To implement this efficiently, we use a :obj:`gpytorch.lazy.RootLazyTensor` during training and a\n        :class:`gpytorch.lazy.MatmulLazyTensor` during test. These lazy tensors represent matrices of the form\n        :math:`K = XX^{\\top}` and :math:`K = XZ^{\\top}`. This makes inference\n        efficient because a matrix-vector product :math:`Kv` can be computed as\n        :math:`Kv=X(X^{\\top}v)`, where the base multiply :math:`Xv` takes only\n        :math:`O(nd)` time and space.\n\n    Args:\n        :attr:`num_dimensions` (int):\n            Number of data dimensions to expect. This\n            is necessary to create the offset parameter.\n        :attr:`variance_prior` (:class:`gpytorch.priors.Prior`):\n            Prior over the variance parameter (default `None`).\n        :attr:`offset_prior` (:class:`gpytorch.priors.Prior`):\n            Prior over the offset parameter (default `None`).\n        :attr:`active_dims` (list):\n            List of data dimensions to operate on.\n            `len(active_dims)` should equal `num_dimensions`.\n    \"\"\"\n\n    def __init__(self, num_dimensions, variance_prior=None, active_dims=None):\n        super(LinearKernel, self).__init__(active_dims=active_dims)\n        self.register_parameter(name=\"raw_variance\", parameter=torch.nn.Parameter(torch.zeros(1)))\n        self.register_parameter(name=\"offset\", parameter=torch.nn.Parameter(torch.zeros(1, 1, num_dimensions)))\n        if variance_prior is not None:\n            self.register_prior(\"variance_prior\", variance_prior, \"variance\")\n\n    @property\n    def variance(self):\n        return self._param_transform(self.raw_variance)\n\n    @variance.setter\n    def variance(self, value):\n        self._set_variance(value)\n\n    def _set_variance(self, value):\n        if not torch.is_tensor(value):\n            value = torch.tensor(value)\n        self.initialize(raw_variance=self._inv_param_transform(value))\n\n    def forward(self, x1, x2, diag=False, batch_dims=None, **params):\n        x1_ = x1 * self.variance.sqrt()\n        if batch_dims == (0, 2):\n            x1_ = x1_.view(x1_.size(0), x1_.size(1), -1, 1)\n            x1_ = x1_.permute(0, 2, 1, 3).contiguous()\n            x1_ = x1_.view(-1, x1_.size(-2), x1_.size(-1))\n\n        if x1.size() == x2.size() and torch.equal(x1, x2):\n            # Use RootLazyTensor when x1 == x2 for efficiency when composing\n            # with other kernels\n            prod = RootLazyTensor(x1_)\n\n        else:\n            x2_ = x2 * self.variance.sqrt()\n            if batch_dims == (0, 2):\n                x2_ = x2_.view(x2_.size(0), x2_.size(1), -1, 1)\n                x2_ = x2_.permute(0, 2, 1, 3).contiguous()\n                x2_ = x2_.view(-1, x2_.size(-2), x2_.size(-1))\n\n            prod = MatmulLazyTensor(x1_, x2_.transpose(2, 1))\n\n        return prod\n", "path": "gpytorch/kernels/linear_kernel.py"}]}