split/Dtable/dtable.c in tioga-1.9 vs split/Dtable/dtable.c in tioga-1.11
- old
+ new
@@ -1743,10 +1743,76 @@
rb_raise(rb_eRuntimeError, "corrupted data given to Dtable._load");
}
return ret;
}
+/* The following function has been written by Benjamin ter Kuile <bterkuile@gmail.com> */
+
+PRIVATE
+/*
+ * call-seq:
+ * dtable.interpolate(Xs, Ys, nx, ny, x_start, x_end, y_start, y_end) -> a_dtable
+ *
+ * Returns a copy of _dtable_ with the values interpolated given the proper X and Y axis to create a uniform spaced result in the X- and Y
+ * direction consisting of nx- and ny values for each direction.
+ */ VALUE dtable_interpolate(VALUE ary, VALUE x_vec, VALUE y_vec, VALUE nx_val, VALUE ny_val, VALUE xstart_val, VALUE xend_val, VALUE ystart_val, VALUE yend_val)
+{
+ Dtable *d = Get_Dtable(ary);
+ int nx = NUM2DBL(rb_Integer(nx_val));
+ int ny = NUM2DBL(rb_Integer(ny_val));
+ int i, j, num_cols = d->num_cols, num_rows = d->num_rows, last_row = num_rows - 1;
+
+ long xsrc_len, ysrc_len;
+ double *xsrc = Dvector_Data_for_Read(x_vec, &xsrc_len);
+ double *ysrc = Dvector_Data_for_Read(y_vec, &ysrc_len);
+ if(xsrc_len != num_cols) rb_raise(rb_eArgError, "Number of x values (%d) do not match the number of columns (%d)", xsrc_len, num_cols);
+ if(ysrc_len != num_rows) rb_raise(rb_eArgError, "Number of y values (%d) do not match the number of rows (%d)", ysrc_len, num_rows);
+ VALUE new = dtable_init(dtable_alloc(cDtable), nx, ny);
+ Dtable *d2 = Get_Dtable(new);
+ double **src, **dest;
+ xstart_val = rb_Float(xstart_val);
+ double xstart = NUM2DBL(rb_Float(xstart_val));
+ if(xstart < xsrc[0]) rb_raise(rb_eArgError, "The start x value %g is smaller than the bound (%g)", xstart, xsrc[0]);
+ double xend = NUM2DBL(rb_Float(xend_val));
+ if(xend > xsrc[xsrc_len-1]) rb_raise(rb_eArgError, "The end x value %g is bigger than the bound (%g)", xend, xsrc[xsrc_len-1]);
+ double ystart = NUM2DBL(rb_Float(ystart_val));
+ if(ystart < ysrc[0]) rb_raise(rb_eArgError, "The start y value %g is smaller than the bound (%g)", ystart, ysrc[0]);
+ double yend = NUM2DBL(rb_Float(yend_val));
+ if(yend > ysrc[ysrc_len-1]) rb_raise(rb_eArgError, "The end y value %g is bigger than the bound (%g)", yend, ysrc[ysrc_len-1]);
+ double dx = (xend-xstart)/(nx-1);
+ double dy = (yend-ystart)/(ny-1);
+ double xcurrent = xstart;
+ double ycurrent = ystart;
+ double intvalue;
+ int isrc = 1;
+ int jsrc = 1;
+ src = d->ptr; dest = d2->ptr;
+ for (i = 1; i < ny+1; i++) {
+ while(ysrc[isrc] < ycurrent && ycurrent < ysrc[ysrc_len-1]){
+ isrc++;
+ }
+ for (j = 1; j < nx+1; j++) {
+ while(xsrc[jsrc] < xcurrent && xcurrent < xsrc[xsrc_len-1]){
+ jsrc++;
+ }
+ intvalue = (
+ ( src[isrc-1][jsrc-1]*(ysrc[isrc]-ycurrent)*(xsrc[jsrc]-xcurrent)) +
+ ( src[isrc][jsrc - 1] * (ycurrent - ysrc[isrc - 1]) * (xsrc[jsrc] - xcurrent) ) +
+ ( src[isrc - 1][jsrc] * (ysrc[isrc] - ycurrent) * (xcurrent - xsrc[jsrc - 1]) ) +
+ ( src[isrc][jsrc] * (ycurrent - ysrc[isrc - 1]) * (xcurrent - xsrc[jsrc - 1]) )
+ );
+ intvalue = intvalue / ( (ysrc[isrc] - ysrc[isrc - 1]) * (xsrc[jsrc] - xsrc[jsrc - 1]) );
+ dest[i-1][j-1] = intvalue;
+ xcurrent += dx;
+ }
+ xcurrent = xstart;
+ jsrc = 1;
+ ycurrent += dy;
+ }
+ return new;
+}
+
/*
* Document-class: Dobjects::Dtable
*
* Dtables are a specialized implementation of two-dimensional arrays of double precision floating point numbers.
* They are intended for use in applications needing efficient processing of large 2D tables of numeric data.
@@ -1898,9 +1964,11 @@
rb_define_method(cDtable, "safe_log10!", dtable_safe_log10_bang, -1);
rb_define_method(cDtable, "safe_inv!", dtable_safe_inv_bang, -1);
rb_define_method(cDtable, "safe_sqrt!", dtable_safe_sqrt_bang, 0);
rb_define_method(cDtable, "safe_asin!", dtable_safe_asin_bang, 0);
rb_define_method(cDtable, "safe_acos!", dtable_safe_acos_bang, 0);
+
+ rb_define_method(cDtable, "interpolate", dtable_interpolate, 8);
/* Marshal : */
rb_define_method(cDtable, "_dump", dtable_dump, 1);
rb_define_singleton_method(cDtable, "_load", dtable_load, 1);
/* modified by Vincent Fourmond, for splitting out the libraries */