aboutsummaryrefslogtreecommitdiff
path: root/math/interp/asider.x
diff options
context:
space:
mode:
Diffstat (limited to 'math/interp/asider.x')
-rw-r--r--math/interp/asider.x121
1 files changed, 121 insertions, 0 deletions
diff --git a/math/interp/asider.x b/math/interp/asider.x
new file mode 100644
index 00000000..2c9a2819
--- /dev/null
+++ b/math/interp/asider.x
@@ -0,0 +1,121 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+.help
+ procedure asider
+
+ This procedure finds derivatives assuming that x lands in
+array i.e. 1 <= x <= npts.
+It must be called by a routine that checks for out of bound references
+and takes care of bad points and checks to make sure that the number
+of derivatives requested is reasonable (max. is 5 derivatives or nder
+can be 6 at most and min. nder is 1)
+
+ This version assumes interior polynomial interpolants are stored as
+the data points with corections for bad points, and the spline interpolant
+is stored as a series of b-spline coefficients.
+
+ The storage and evaluation for nearest neighbor and linear interpolation
+are simpler so they are evaluated separately from other piecewise
+polynomials.
+.endhelp
+
+procedure asider(x,der,nder,coeff)
+include "interpdef.h"
+include "asidef.h"
+
+real x
+real coeff[ARB]
+int nder # no. items returned = 1 + no. of deriv.
+
+real der[ARB] # der[1] is value der[2] is f prime etc.
+
+int nx,n0,i,j,k,nt,nd
+real s,ac,pc[6],d[6]
+
+begin
+ do i = 1, nder # return zero for derivatives that are zero
+ der[i] = 0.
+
+ nt = 0 # nt is number of terms in case polynomial type
+
+ switch (ITYPEI) { # switch on interpolator type
+
+ case IT_NEAREST :
+ der[1] = (coeff[COFF + nint(x)])
+ return
+
+ case IT_LINEAR :
+ nx = x
+ der[1] = (x - nx) * coeff[COFF + nx + 1] +
+ (nx + 1 - x) * coeff[COFF + nx]
+ if ( nder > 1 ) # try to return exact number requested
+ der[2] = coeff[COFF + nx + 1] - coeff[COFF + nx]
+ return
+
+ case IT_POLY3 :
+ nt = 4
+
+ case IT_POLY5 :
+ nt = 6
+
+ case IT_SPLINE3 :
+ nt = 4
+
+ }
+
+ # falls through to here if interpolant is one of
+ # the higher order polynomial types or third order spline
+
+ nx = x
+ n0 = COFF + nx
+ s = x - nx
+
+ nd = nder # no. of derivatives needed
+ if ( nder > nt )
+ nd = nt
+
+ # generate polynomial coefficients, first for spline.
+ if (ITYPEI == IT_SPLINE3) {
+ pc[1] = coeff[n0-1] + 4. * coeff[n0] + coeff[n0+1]
+ pc[2] = 3. * (coeff[n0+1] - coeff[n0-1])
+ pc[3] = 3. * (coeff[n0-1] - 2. * coeff[n0] + coeff[n0+1])
+ pc[4] = -coeff[n0-1] + 3. * coeff[n0] - 3. * coeff[n0+1] +
+ coeff[n0+2]
+
+ } else {
+
+ # Newton's form written in line to get polynomial from data
+ # load data
+ do i = 1,nt
+ d[i] = coeff[n0 - nt/2 + i]
+
+ # generate difference table
+ do k = 1, nt-1
+ do i = 1,nt-k
+ d[i] = (d[i+1] - d[i]) / k
+
+ # shift to generate polynomial coefficients of (x - n0)
+ do k = nt,2,-1
+ do i = 2,k
+ d[i] = d[i] + d[i-1] * (k - i - nt/2)
+
+ do i = 1,nt
+ pc[i] = d[nt + 1 - i]
+ }
+
+ do k = 1,nd { # as loop progresses pc contains coefficients of
+ # higher and higher derivatives
+
+ ac = pc[nt - k + 1]
+ do j = nt - k, 1, -1 # evaluate using nested mult.
+ ac = pc[j] + s * ac
+
+ der[k] = ac
+
+ do j = 1,nt - k # differentiate polynomial
+ pc[j] = j * pc[j + 1]
+ }
+
+ return
+
+end