    float xcoord = (x + 1) * (width - 1) / 2;
    point = floor(xcoord);
    weight = 1 - (xcoord - point);
+}
+
+__device__ void getBottomRight(float x, int width, int& point, float& weight)
+{
+   /* for interpolation :
+      stores in point and weight :
+      - the x-coordinate of the pixel on the left (or y-coordinate of the upper pixel)
+      - the weight for interpolating
+   */
+
+   float xcoord = (x + 1) * (width - 1) / 2;
+   point = ceil(xcoord);
+   weight = 1 - (point - xcoord);
 }
 
 __device__ bool between(int value, int lowerBound, int upperBound)

                                                      THCudaTensor_size(state, inputImages, 3),
                                                      THCudaTensor_size(state, inputImages, 1),
                                                      THCudaTensor_size(state, inputImages, 2),
                                                      THCudaTensor_size(state, output, 2));



   const bool withinImageBounds = xOut < output_width; // check whether x exceed the boundary
   const bool withinGridBounds = blockIdx.x*blockDim.y + threadIdx.x / 2 < output_width; // check whether

   if(!withinImageBounds || !withinGridBounds) return;

   const int width = inputImages_width;
   const int height = inputImages_height;

   int xOut_l = xOut > 0 ? (xOut - 1) : xOut;
   int yOut_t = yOut > 0 ? (yOut - 1) : yOut;
   int xOut_r = xOut < (output_width - 1) ? (xOut + 1) : xOut;
   int yOut_b = yOut < (output_height - 1) ? (yOut + 1) : yOut;

   float yf = grids_data[b*grids_strideBatch + yOuy*grids_strideHeight + xOut*grids_strideWidth];
   float xf = grids_data[b*grids_strideBatch + yOut*grids_strideHeight + xOut*grids_strideWidth + 1];

   // get coordinates for four corners of target response map in the source response map
   float yf_tl = grids_data[b*grids_strideBatch + yOut_t*grids_strideHeight + xOut_l*grids_strideWidth];
   float xf_tl = grids_data[b*grids_strideBatch + yOut_t*grids_strideHeight + xOut_l*grids_strideWidth + 1];

   float yf_tr = grids_data[b*grids_strideBatch + yOut_t*grids_strideHeight + xOut_r*grids_strideWidth];
   float xf_tr = grids_data[b*grids_strideBatch + yOut_t*grids_strideHeight + xOut_r*grids_strideWidth + 1];

   float yf_bl = grids_data[b*grids_strideBatch + yOut_b*grids_strideHeight + xOut_l*grids_strideWidth];
   float xf_bl = grids_data[b*grids_strideBatch + yOut_b*grids_strideHeight + xOut_l*grids_strideWidth + 1];

   float yf_br = grids_data[b*grids_strideBatch + yOut_b*grids_strideHeight + xOut_r*grids_strideWidth];
   float xf_br = grids_data[b*grids_strideBatch + yOut_b*grids_strideHeight + xOut_r*grids_strideWidth + 1];

   // compute the bottom left coordinates of source response map
   float xs_tl = min(min(min(xf_tl, xf_tr), xf_bl), xf_br);
   float ys_tl = min(min(min(yf_tl, yf_tr), yf_bl), yf_br);

   float xs_br = max(max(max(xf_tl, xf_tr), xf_bl), xf_br);
   float ys_br = max(max(max(yf_tl, yf_tr), yf_bl), yf_br);

   int yi_t, xi_l;
   float yWeight_t, xWeight_l;

   int yi_b, xi_r;
   float yWeight_b, xWeight_r;

   // compute the top left, top right, bottom left, bottom right corner for current grid
   // compute the nearest bottom right coordiate in source map of top left grid coordiate
   getBottomRight(xs_tl, inputImages_width, xi_l, xWeight_l);
   getBottomRight(ys_tl, inputImages_height, yi_t, yWeight_t);
   // compute the nearest top left coordiate in source map of bottom right grid coordiate
   getTopLeft(xs_br, inputImages_width, xi_r, xWeight_r);
   getTopLeft(ys_br, inputImages_height, yi_b, yWeight_b);

   // compute average mask value in region [topleft, bottom right]
   float weights[32];
   float m = 0;
   float weight_sum = 0;
   int id_point = 0;
   for (int y = yi_t; y <= yi_b; ++y) {
     if (!between(y, 0, height-1)) continue;
     for (int x = xi_l; x <= xi_r; +=x) {
       if (!between(x, 0, width-1)) continue;
       float weight = __expf((x - xf) * (x - xf) + (y - yf) * (y - yf));
       weight_sum += weight;
       weights[id_point] = weight;
       int address = masks_strideBatch * b + masks_strideHeight * y + masks_strideWidth * x;
       m += weight * masks_data[address];
       ++id_point;
     }
   }
   m /= weight_sum;

   float v=0;
   float inTopLeft=0;
