/* Fuzzy substraction of two curves. Substracts the Y values of _op_ to the current Function, by making sure that the Y value substracted to a given point corresponds to the closest X_ value of the point in _op_. This function somehow assumes that the data is reasonably organised, and will never go backwards to find a matching X value in _op_. In any case, you really should consider using split_monotonic on it first. */ static VALUE function_fuzzy_substract(VALUE self, VALUE op) { long ss = function_sanity_check(self); const double *xs = Dvector_Data_for_Read(get_x_vector(self),NULL); double *ys = Dvector_Data_for_Write(get_y_vector(self),NULL); long so = function_sanity_check(op); const double *xo = Dvector_Data_for_Read(get_x_vector(op),NULL); const double *yo = Dvector_Data_for_Read(get_y_vector(op),NULL); long i,j = 0; double diff; double fuzz = 0; /* The actual sum of the terms */ for(i = 0; i < ss; i++) { /* We first look for the closest point */ diff = fabs(xs[i] - xo[j]); while((j < (so - 1)) && (fabs(xs[i] - xo[j+1]) < diff)) diff = fabs(xs[i] - xo[++j]); fuzz += diff; ys[i] -= yo[j]; } return rb_float_new(fuzz); }