/*
: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;
}