aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/trebin/tuival.x
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/utilities/nttools/trebin/tuival.x')
-rw-r--r--pkg/utilities/nttools/trebin/tuival.x272
1 files changed, 272 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/trebin/tuival.x b/pkg/utilities/nttools/trebin/tuival.x
new file mode 100644
index 00000000..20354a5d
--- /dev/null
+++ b/pkg/utilities/nttools/trebin/tuival.x
@@ -0,0 +1,272 @@
+include "trebin.h"
+
+# tuival -- interpolate
+# Interpolate to get one value.
+# A zero value of iv_step means that the output independent-variable values
+# may not be uniformly spaced, so the interval x1,x2 must be gotten from
+# the xout array. (This is relevant for linear interpolation only.)
+#
+# Phil Hodge, 18-Apr-1988 Subroutine created
+# Phil Hodge, 20-May-1996 Include extrapolate and ext_value for extrapolation.
+# Phil Hodge, 29-Jul-1998 For 1-D, fit a line instead of interpolating,
+# add iv_step to calling sequence, add subroutines
+# tu_range and tu_fit1.
+# Phil Hodge, 22-Apr-1999 The test on whether x is outside the range of
+# the data did not consider that xa could be decreasing.
+# Phil Hodge, 25-Apr-2000 Change calling sequence: x --> xout, j, outrows;
+# this is to support the option of a nonuniformly spaced output
+# independent variable array.
+
+procedure tuival (i_func, xa, ya, y2, n,
+ extrapolate, ext_value, xout, j, outrows, iv_step, y)
+
+int i_func # i: interpolation function code
+double xa[n] # i: input independent-variable values
+double ya[n] # i: input dependent-variable values
+double y2[n] # i: used only by spline interpolation
+int n # i: size of xa, ya, y2 arrays
+bool extrapolate # i: extrapolate rather than use ext_value?
+double ext_value # i: value to assign if x is out of bounds
+double xout[ARB] # i: output independent variable array
+int j # i: current element of xout
+int outrows # i: size of xout array
+double iv_step # i: spacing of x values (can be negative)
+double y # o: the interpolated value
+#--
+double x # independent variable
+double x1, x2 # beginning and end of output pixel
+double dy # an estimate of the error of interpolation
+int klo, khi # indexes within xa that bracket x
+int npts # number of points in interval
+
+begin
+ x = xout[j]
+
+ # Initial guess for klo; we want xa[klo] <= x <= xa[klo+1].
+ klo = (n + 1) / 2
+ khi = klo
+
+ # If x falls outside the range of the data, either extrapolate
+ # (below) or assign a fixed value ext_value.
+ if (!extrapolate && n > 1) {
+ if (xa[1] < xa[2] && (x < xa[1] || x > xa[n])) { # increasing
+ y = ext_value
+ return
+ }
+ if (xa[1] > xa[2] && (x > xa[1] || x < xa[n])) { # decreasing
+ y = ext_value
+ return
+ }
+ }
+
+ switch (i_func) {
+ case I_NEAREST:
+
+ # Find klo such that xa[klo] <= x <= xa[klo+1], starting from
+ # current klo.
+ call tuhunt (xa, n, x, klo)
+ klo = max (klo, 1)
+ klo = min (klo, n)
+ khi = min (klo+1, n)
+ if (abs (x - xa[klo]) < abs (x - xa[khi]))
+ y = ya[klo]
+ else
+ y = ya[khi]
+
+ case I_LINEAR:
+
+ # Get x1 and x2.
+ call tu_x1x2 (xout, j, outrows, iv_step, x1, x2)
+
+ # Get klo, khi, and npts.
+ call tu_range (xa, ya, n, x1, x2, klo, khi, npts)
+ if (npts > 1) {
+ # Fit a line to the data from klo to khi inclusive.
+ call tu_fit1 (xa, ya, x, klo, khi, y)
+ } else {
+ # Interpolate.
+ klo = klo - 1
+ call tuhunt (xa, n, x, klo)
+ klo = max (klo, 1)
+ klo = min (klo, n-1)
+ call tuiep1 (xa[klo], ya[klo], x, y)
+ }
+
+ case I_POLY3:
+
+ call tuhunt (xa, n, x, klo)
+ klo = max (klo, 2)
+ klo = min (klo, n-2)
+ # Pass tuiep3 the four points at klo-1, klo, klo+1, klo+2.
+ call tuiep3 (xa[klo-1], ya[klo-1], x, y, dy)
+
+ case I_SPLINE:
+
+ call tuhunt (xa, n, x, klo)
+ klo = max (klo, 1)
+ klo = min (klo, n-1)
+ call tuispl (xa[klo], ya[klo], y2[klo], x, y)
+ }
+end
+
+# This routine gets the endpoints x1,x2 of the current output pixel.
+# If the output independent variable array is uniformly spaced, x1 and x2
+# will just be the current pixel xout[j] - or + iv_step/2. If the output
+# independent variable array is (or may be) nonuniformly spaced, indicated
+# by iv_step being zero, then x1 and x2 will be the midpoints of intervals
+# adjacent to xout[j] on the left and right.
+#
+# x1 may be less than, equal to, or greater than x2.
+
+procedure tu_x1x2 (xout, j, outrows, iv_step, x1, x2)
+
+double xout[ARB] # i: output independent variable array
+int j # i: current element of xout
+int outrows # i: size of xout array
+double iv_step # i: spacing of x values (can be negative)
+double x1, x2 # o: endpoints of output pixel
+
+begin
+ if (iv_step != 0) {
+ # output is uniformly spaced
+ x1 = xout[j] - iv_step / 2.d0
+ x2 = xout[j] + iv_step / 2.d0
+ } else {
+ if (outrows == 1) {
+ x1 = xout[1]
+ x2 = xout[1]
+ } else if (j == 1) {
+ x2 = (xout[1] + xout[2]) / 2.d0
+ x1 = xout[1] - (x2 - xout[1])
+ } else if (j == outrows) {
+ x1 = (xout[outrows-1] + xout[outrows]) / 2.d0
+ x2 = xout[outrows] + (xout[outrows] - x1)
+ } else {
+ x1 = (xout[j-1] + xout[j]) / 2.d0
+ x2 = (xout[j] + xout[j+1]) / 2.d0
+ }
+ }
+end
+
+# tu_range -- find range of indexes
+# This routine finds the range of indexes in xa and ya corresponding to
+# the interval x1 to x2. The range is klo to khi; klo will be less than
+# or equal to khi, even though xa can be either increasing or decreasing.
+# klo and khi will also be within the range 1 to n inclusive, even if
+# x1 to x2 is outside the range xa[1] to xa[n]. npts will be set to
+# the actual number of elements of xa within the interval x1 to x2;
+# thus, npts can be zero.
+#
+# x1 and x2 will be interchanged, if necessary, so that the array index
+# in xa corresponding to x1 will be smaller than the array index corresponding
+# to x2, i.e. so klo will be smaller than khi.
+#
+# Note that klo is used as an initial value when hunting for a value in xa,
+# so klo must have been initialized to a reasonable value before calling
+# this routine.
+
+procedure tu_range (xa, ya, n, x1, x2, klo, khi, npts)
+
+double xa[n] # i: array of independent-variable values
+double ya[n] # i: array of dependent-variable values
+int n # i: size of xa, ya, y2 arrays
+double x1, x2 # io: endpoints of output pixel
+int klo, khi # io: range of indices in xa within x1,x2
+int npts # o: number of elements in xa within x1,x2
+#--
+double temp # for swapping x1 and x2, if appropriate
+int k1, k2
+
+begin
+ # Swap x1 and x2 if necessary, so that klo will be less than or
+ # equal to khi.
+ if (xa[1] <= xa[2]) { # input X is increasing
+ if (x1 > x2) {
+ temp = x1; x1 = x2; x2 = temp
+ }
+ } else { # input X is decreasing
+ if (x1 < x2) {
+ temp = x1; x1 = x2; x2 = temp
+ }
+ }
+
+ k1 = klo
+ call tuhunt (xa, n, x1, k1)
+ k1 = k1 + 1 # next point
+ klo = k1
+ klo = min (klo, n)
+
+ k2 = k1
+ call tuhunt (xa, n, x2, k2)
+ khi = max (k2, 1)
+ khi = min (khi, n)
+
+ # npts can be different from khi - klo + 1, and it can be zero.
+ npts = k2 - k1 + 1
+end
+
+# tu_fit1 -- fit a line (1-D) to data
+# This routine fits a straight line to (xa[k],ya[k]) for k = klo to khi
+# inclusive. The fit is then evaluated at x, and the result is returned
+# as y. There must be at least two points, i.e. khi > klo.
+
+procedure tu_fit1 (xa, ya, x, klo, khi, y)
+
+double xa[ARB] # i: array of independent-variable values
+double ya[ARB] # i: array of dependent-variable values
+double x # i: independent variable
+int klo, khi # i: range of indices in xa covered by iv_step
+double y # o: value of fit at x
+#--
+double sumx, sumy, sumxy, sumx2
+double xmean, ymean
+double slope, intercept
+int k
+
+begin
+ sumx = 0.d0
+ sumy = 0.d0
+ do k = klo, khi {
+ sumx = sumx + xa[k]
+ sumy = sumy + ya[k]
+ }
+ xmean = sumx / (khi - klo + 1)
+ ymean = sumy / (khi - klo + 1)
+
+ sumxy = 0.d0
+ sumx2 = 0.d0
+ do k = klo, khi {
+ sumxy = sumxy + (xa[k] - xmean) * (ya[k] - ymean)
+ sumx2 = sumx2 + (xa[k] - xmean)**2
+ }
+ slope = sumxy / sumx2
+ intercept = (ymean - slope * xmean)
+
+ y = intercept + slope * x
+end
+
+
+# tuiep1 -- linear interpolation
+# Interpolate to get one value. X is supposed to be between xa[1] and
+# xa[2], but it is not an error if x is outside that interval. Note
+# that xa, ya are subarrays of the arrays with the same names elsewhere.
+
+procedure tuiep1 (xa, ya, x, y)
+
+double xa[2] # i: pair of independent-variable values
+double ya[2] # i: pair of dependent-variable values
+double x # i: independent variable
+double y # o: the interpolated value
+#--
+double p # fraction of distance between indep var val
+
+begin
+ if (x == xa[1]) {
+ y = ya[1]
+ } else if (x == xa[2]) {
+ y = ya[2]
+ } else {
+ p = (x - xa[1]) / (xa[2] - xa[1])
+ y = p * ya[2] + (1.-p) * ya[1]
+ }
+end