Repository: cornellius-gp/gpytorch

Issue:
[Bug] Interpolation gives wrong interp_values next to the left boundary
# 🐛 Bug

Interpolation utility returns asymetric interp_values for symmetric grid & inputs.
The problem arises next to the left boundary, where all points between gridpoint-0 and gridpoint-2 are interpolated with the same value (this should not happen)!

## To reproduce

```python
import numpy
import torch

grid_size = 8
grid_bounds=[(0, 1)]
grid = torch.zeros(grid_size, len(grid_bounds))
for i in range(len(grid_bounds)):
    grid_diff = float(grid_bounds[i][1] - grid_bounds[i][0]) / (grid_size - 2)
    grid[:, i] = torch.linspace(grid_bounds[i][0] - grid_diff, grid_bounds[i][1] + grid_diff, grid_size)

from gpytorch.utils.interpolation import Interpolation

inputs = torch.tensor([0.0,0.1,0.2,0.3,0.5,0.7,0.8,0.9,1.0]).unsqueeze(1)
interp_indices, interp_values = Interpolation().interpolate(grid, inputs)

interp_values

```

For symmetric input (see above), this code returns the following (asymetric!) interp_values, where 2nd and 3rd rows are incorrect:
```
tensor([[ 0.0000,  1.0000,  0.0000,  0.0000],
        [ 0.0000,  1.0000,  0.0000,  0.0000],
        [ 0.0000,  0.0000,  1.0000,  0.0000],
        [-0.0681,  0.6304,  0.4933, -0.0557],
        [-0.0625,  0.5625,  0.5625, -0.0625],
        [-0.0557,  0.4933,  0.6304, -0.0681],
        [-0.0321,  0.9866,  0.0481, -0.0026],
        [-0.0480,  0.4240,  0.6960, -0.0720],
        [ 0.0000,  0.0000,  1.0000,  0.0000]])
```

and correct interp_indices:
```
tensor([[0, 1, 2, 3],
        [0, 1, 2, 3],
        [0, 1, 2, 3],
        [1, 2, 3, 4],
        [2, 3, 4, 5],
        [3, 4, 5, 6],
        [4, 5, 6, 7],
        [4, 5, 6, 7],
        [4, 5, 6, 7]])
```

## Expected Behavior

Should return symmetric interp_values for symmetric grid & inputs:
```
tensor([[ 0.0000e+00,  1.0000e+00,  0.0000e+00,  0.0000e+00],
        [-7.2000e-02,  6.9600e-01,  4.2400e-01, -4.8000e-02],
        [-2.6014e-03,  4.8117e-02,  9.8657e-01, -3.2086e-02],
        [-6.8063e-02,  6.3044e-01,  4.9331e-01, -5.5688e-02],
        [-3.0470e-04,  1.3726e-02,  9.9846e-01, -1.1883e-02],
        [-6.2500e-02,  5.6250e-01,  5.6250e-01, -6.2500e-02],
        [-1.1883e-02,  9.9846e-01,  1.3727e-02, -3.0470e-04],
        [-3.2086e-02,  9.8657e-01,  4.8117e-02, -2.6019e-03],
        [-4.8000e-02,  4.2400e-01,  6.9600e-01, -7.2000e-02],
        [ 0.0000e+00,  0.0000e+00,  1.0000e+00,  0.0000e+00]])
```

## Additional context

The solution will follow shortly (#896).
It basically replaces 1->0 in one line.



Discussion:

Resolving patch:
diff --git a/gpytorch/utils/interpolation.py b/gpytorch/utils/interpolation.py
--- a/gpytorch/utils/interpolation.py
+++ b/gpytorch/utils/interpolation.py
@@ -104,7 +104,7 @@ def interpolate(self, x_grid, x_target, interp_points=range(-2, 2)):
 
             # Find points who's closest lower grid point is the first grid point
             # This corresponds to a boundary condition that we must fix manually.
-            left_boundary_pts = torch.nonzero(lower_grid_pt_idxs < 1)
+            left_boundary_pts = torch.nonzero(lower_grid_pt_idxs < 0)
             num_left = len(left_boundary_pts)
 
             if num_left > 0:


Test patch: