/*
  :call-seq:
    vector.convolve(kernel, middle)

  convolve applies a simple convolution to the vector using kernel centered
  at the point middle. (0 is the leftmost point of the kernel).
*/

static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
{
  long len;
  const double * values = Dvector_Data_for_Read(self, &len);
  VALUE retval = dvector_new2(len,len);
  double * ret = Dvector_Data_for_Write(retval,NULL);
  long kernel_len;
  const double * ker = Dvector_Data_for_Read(kernel, &kernel_len);
  /* I guess */
  long mid = NUM2LONG(middle);
  if(mid > kernel_len)
    rb_raise(rb_eArgError, "middle should be within kernel's range");
  else
    {
      long i,j,k;
      for(i = 0; i < len; i++) 
        {
          double sum = 0, k_sum = 0;
          for(j = 0; j < kernel_len; j++) 
            {
              /* check that we are within the vector */
              k = i - mid + j;         /* The current index inside the vector */
              /* This code is equivalent to saying that the vector is
                 prolongated until infinity with values at the boundaries
                 -> no, obnoxious, I think. Simply don't take care
                 of these points
                 -> yes, finally ?
              */
              if( k < 0)
/*              continue; */
                k = 0;
              if( k >= len)
/*              continue; */
                k = len - 1;
              sum += ker[j] * values[k];
              k_sum += ker[j];
            }
          sum/= k_sum;
          ret[i] = sum;
        }
    }
  return retval;
}