C+ C NAME: C SplineX C PURPOSE: C Interpolation of 2D arrays in first (horizontal) dimension. C CATEGORY: C Interpolation using natural spline C CALLING SEQUENCE: subroutine SplineX(iFlag,NX,XN,MX,XM,NY,ZN,ZM) C INPUTS: C iFlag integer 1st bit set: flag bad point in output ZZ if C nearest grid point in Z is bad. C C 2nd bit set: if the range of XM extends C outside the range of XN then x-coordinates outside C the range of XN are mapped back inside C by a mod ( max(XN)-min(XN)) operation. C C NX integer first (horizontal) dimension of input ZN C XN(NX) real horizontal coordinates for input ZN C MX integer first (horizontal) dimension of output ZM C XM(MX) real horizontal coordinates for output ZM C ZN(NX,NY) real fnc-values C OUTPUTS: C ZM(MX,NY) real interpolated fnc-values C CALLS: C ArrR4GetMinMax, IndexR4, BadR4, nrSplInt, nrSpline, Say C SEE ALSO: C SplineY, SplineGridX, SplineGridY C RESTRICTIONS: C The in- and output horizontal coordinate ranges must be non-zero C PROCEDURE: C > 1st bit of iFlag is set: for each grid point of the output grid the C nearest grid point of the output grid is determined. If this nearest C point was flagged (contained value BadR4()) then the value of the C output grid is also flagged. C !! `Nearest' means the nearest grid point in the C horizontal direction only (along a single row); C > For each row in Z a spline is calculated, using all valid fnc-values C in that row. XN provides the ordinates for the spline C > If the row dimension is not changed (NX=MX), SplineX and has the effect of C filling in the invalid function values (if 1st bit of iFlag is set). C In this case the same array can be used for both ZN and ZM. C MODIFICATION HISTORY: C JUL-1993, Paul Hick (UCSD/CASS) C APR-1994, Paul Hick (UCSD/CASS) C added argument bFlag to control flagging of function values in the output array C MAY-2002, Paul Hick (UCSD/CASS; pphick@ucsd.edu) C Generalized version of old SplineGridX. Instead of working with evenly spaced C ordinate values, now arbitrary ordinate values for in- and output arrays C are allowed. C Changed logical argument bFlag to integer argument iFlag. The original bFlag C functionality is now controlled by the first bit in iFlag. The second bit C is now used to contol the mod(Xmax-Xmin) behavior. C- integer iFlag integer NX real XN(NX) integer MX real XM(MX) integer NY real ZN(NX,NY) ! Input data array real ZM(MX,NY) ! Output data array character cSay*7 /'SplineX'/ logical bFlag logical bMod logical bSpline parameter (NMAX = 1000) real XS (NMAX) ! Scratch arrays for splines real ZS (NMAX) real Y2 (NMAX) real Ztmp(NMAX) integer INDX(NMAX) if (max(NX,MX) .gt. NMAX) call Say(cSay,'E','Not enough','scratch space. Increase parameter NMAX') call ArrR4GetMinMax(NX,XN,XNmin,XNmax) call ArrR4GetMinMax(MX,XM,XMmin,XMmax) if (XNmin .eq. XNmax .or. XMmin .eq. XMmax) & call Say(cSay,'E','zero range','in- and output range must be non-zero') call IndexR4(1,NX,1,NX,XN,INDX) ! Sort into monotonic increasing order Bad = BadR4() bFlag = iand(iFlag,1) .ne. 0 ! Test 1st bit bMod = iand(iFlag,2) .ne. 0 ! Test 2nd bit XNrange = XNmax-XNmin bSpline = .TRUE. do J=1,NY ! Spline each row separately KX = 0 do I=1,NX ! Pick up all valid grid points IS = INDX(I) ! Process in sorted order if (ZN(IS,J) .ne. Bad) then KX = KX+1 XS(KX) = XN(IS) ! XS monotonic increasing ZS(KX) = ZN(IS,J) end if end do ! Calculate natural spline if (KX .gt. 1) call nrSpline(KX,XS,ZS,1.0e30,1.0e30,Y2) do I=1,MX ! Calculate new grid fnc-values XX = XM(I) if (bMod) XX = XNmin+mod( mod(XX-XNmin,XNrange)+XNrange, XNrange ) if (bFlag) then ! iNear = nearest input grid point iNear = 1 dNear = abs(XX-XN(1)) do N=2,NX dX = abs(XX-XN(N)) if (dX .lt. dNear) then dNear = dX iNear = N end if end do bSpline = ZN(iNear,J) .ne. Bad ! Nearest grid point flagged? end if if (KX .gt. 1 .and. bSpline) then call nrSplInt(KX,XS,ZS,Y2, XX,Ztmp(I)) else Ztmp(I) = Bad end if end do do I=1,MX ! Copy result into ZM array ZM(I,J) = Ztmp(I) end do end do return end