#ifdef TEST

	program testit,4
	real grida(9,9),xa(9),ya(9),gridb(5,5),xb(5),yb(5)
        real xa_8(9),ya_8(9),xb_8(5),yb_8(5)
	real*8 cxa(9),cxb(9),cxc(9),cxd(9)
	real*8 cya(9),cyb(9),cyc(9),cyd(9)
	integer indxx(9),indxy(9)
        character*8 hint

        hint = 'LAG2D'
	do j=1,9
	do i=1,9
	  grida(i,j)=0
	  xa(i)=i+2
          xa_8(i)=xa(i)
	  ya(j)=j+2
          ya_8(j)=ya(j)
	  indxx(i)=-1
	  indxy(i)=-1
	enddo
	enddo
	do j=9,1,-1
	  PRINT 101,(GRIDA(I,J),i=1,9)
	ENDDO
	print *,'xa=',xa
	print *,'ya=',ya
	do j=1,5
	do i=1,5
	  gridb(i,j)=i*2+1
	  xb(i)=i*2+1
	  yb(j)=j*2+1
          xb_8(i)=xb(i)
          yb_8(j)=yb(j)
	enddo
	enddo
	do j=5,1,-1
	  PRINT 101,(GRIDB(I,J),i=1,5)
	ENDDO
	print *,'xb=',xb
	print *,'yb=',yb
	call grid_to_grid_coef(xa_8,9,xb_8,5,indxx,cxa,cxb,cxc,cxd,hint)
	print *,'indxx=',indxx
	print 101,cxa
	print 101,cxb
	print 101,cxc
	print 101,cxd
	call grid_to_grid_coef(ya_8,9,yb_8,5,indxy,cya,cyb,cyc,cyd,hint)
	print *,'indxy=',indxy
	print 101,cya
	print 101,cyb
	print 101,cyc
	print 101,cyd
	call grid_to_grid(grida,9,9,gridb,5,5,xa,ya,xb,yb)
	print *,' out of grid_to_grid'
	do j=9,1,-1
	  PRINT 101,(GRIDA(I,J),i=1,9)
	ENDDO
      call grid_to_grid_interp(grida,9,9,gridb,5,5,indxx,indxy,
     %                    cxa,cxb,cxc,cxd,cya,cyb,cyc,cyd,hint)
	print *,' out of grid_to_grid_interp'
	do j=9,1,-1
	  PRINT 101,(GRIDA(I,J),i=1,9)
	ENDDO
101	format(2x,11f6.1)
	stop
	end
#endif
*/* RMNLIB - Library of useful routines for C and FORTRAN programming
* * Copyright (C) 1975-2001  Division de Recherche en Prevision Numerique
* *                          Environnement Canada
* *
* * This library is free software; you can redistribute it and/or
* * modify it under the terms of the GNU Lesser General Public
* * License as published by the Free Software Foundation,
* * version 2.1 of the License.
* *
* * This library is distributed in the hope that it will be useful,
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* * Lesser General Public License for more details.
* *
* * You should have received a copy of the GNU Lesser General Public
* * License along with this library; if not, write to the
* * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* * Boston, MA 02111-1307, USA.
* */
***S/R D1INT2 - ROUTINE USED IN SPLINE INTERPOLATION.
*

      SUBROUTINE grid_to_grid(FI,IFI,JFI,F,IF,JF,XI,YI,X,Y) 1
!     SUBROUTINE D1INT2 (FI,IFI,JFI,F,IF,JF,FX,FY,FXY,XI,YI,X,Y,HX,HY,
!    1                   ZA,ZB,ZC,ZD)
*
*AUTHOR   - D. ROBERTSON
*
*REVISION 001   C. THIBEAULT - FEB 80 - DOCUMENTATION
*
*LANGUAGE - fortran
*
*OBJECT(D1INT2)
*         - THIS ROUTINE IS PART OF THE SPLINE INTERPOLATION PACKAGE.
*           SEE THE WRITE-UPS ON INTRP AND INT1D1 FOR INFORMATION ABOUT
*           USING THE PACKAGE.
*
*LIBRARIES
*         - SOURCE  RMNSOURCELIB,ID=RMNP     DECK=D1INT2
*         - OBJECT  RMNLIB,ID=RMNP
*
*USAGE    - CALL D1INT2(FI,IFI,JFI,F,IF,JF,FX,FY,FXY,XI,YI,X,Y,
*                       HX,HY,ZA,ZB,ZC,ZD)
*
*ARGUMENTS
*   OUT   - FI   - INTERPOLATED FIELD.
*   IN    - IFI  - X-DIMENSION OF FIELD FI.
*         - JFI  - Y-DIMENSION OF FIELD FI.
*         - F    - ORIGINAL FIELD.
*         - IF   - X-DIMENSION OF FIELD F.
*         - JF   - Y-DIMENSION OF FILED F.
*         - XI   - X LOCATION OF THE VALUES OF THE INTERPOLATED FIELD FI.
*         - YI   - Y LOCATION OF THE VALUES OF THE INTERPOLATED FIELD FI.
*         - X    - X LOCATION OF THE VALUES OF THE ORIGINAL FIELD F.
*         - Y    - Y LOCATION OF THE VALUES OF THE ORIGINAL FIELD F.
*
*NOTES    - A SET OF PROGRAMS IS AVAILABLE TO DO 1 AND 2 DIMENSION
*           SPLINE INTERPOLATION. (A 1-DIMENSIONAL SPLINE IS A CURVE
*           CONSTRAINED TO PASS THROUGH CERTAIN GIVEN POINTS, VARYING
*           CUBICALLY BETWEEN THE GIVEN POINTS. THE DIFFERENT CUBIC
*           SEGMENTS JOIN UP SMOOTHLY, WITH CONTINUOUS 1ST AND 2ND DERIVATIVES.
*           THE 2-DIMENSIONAL SPLINE VARIES BICUBICALLY IN GRID SQUARES,
*           PASSES THROUGH ALL THE ORIGINAL POINTS, AND HAS CONTINUOUS
*           FIRST AND SECOND DERIVATIVES, (AS FAR AS F(XXYY)).)
*         - THE SPACING OF THE POINTS IS ARBITRARY. (THE 2-DIMENSIONAL
*           GRID IS ASSUMED TO HAVE ORTHOGONAL COORDINATE AXES).
*
*---------------------------------------------------------------------------
*
      implicit none
      integer if,jf,ifi,jfi,k,k1,kk
      integer i,j,l,l1,ll
      real we,we1,we2,wn,ww,wm,wz,wz1,wz2,z,ze,zf,zg,zl,zz
      REAL FI     (IFI,JFI)
      REAL F      (IF ,JF )
      REAL FX     (IF ,JF )
      REAL FY     (IF ,JF )
      REAL FXY    (IF ,JF )
      REAL XI     (IFI)
      REAL YI     (JFI)
      REAL X      (IF )
      REAL Y      (JF )
*         - FX   - ARRAY OF SIZE (IF,JF) THAT CONTAINS COMPUTED
*                  PARTIAL DERIVATIVE OF FIELD F WITH RESPECT TO X.
*         - FY   - PARTIAL DERIVATIVE WITH RESPECT TO Y.
*         - FXY  - PARTIAL SECOND DERIVATIVE WITH RESPECT TO X AND Y.
*         - HX   - GRID-LENGTH along X
*         - HY   - GRID-LENGTH along Y
*         - ZA   - WORKING VECTOR OF LENGTH (JFI).
*         - ZB   - WORKING VECTOR OF LENGTH (JFI).
*         - ZC   - WORKING VECTOR OF LENGTH (JFI).
*         - ZD   - WORKING VECTOR OF LENGTH (JFI).
      REAL hx,hx2
      REAL hy,hy2
      REAL ZA     (JFI)
      REAL ZB     (JFI)
      REAL ZC     (JFI)
      REAL ZD     (JFI)
*
*----------------------------------------------------------------------
*
      hx=1.0/(x(2)-x(1))
      hx2=.5*hx
      hy=1.0/(y(2)-y(1))
      hy2=.5*hy
!  compute df/dx
      do j=1,jf
        fx(1,j)=(f(2,j)-f(1,j))*hx
        fx(if,j)=(f(if,j)-f(if-1,j))*hx
        do i=2,if-1
          fx(i,j)=(f(i+1,j)-f(i-1,j))*hx2
        enddo
      enddo
!  compute df/dy
      do j=2,jf-1
        do i=1,if
          fy(i,1)=(f(i,2)-f(i,1))*hy
          fy(i,jf)=(f(i,jf)-f(i,jf-1))*hy
        enddo
        do i=1,if
          fy(i,j)=(f(i,j+1)-f(i,j-1))*hy2
        enddo
      enddo
!  compute df/dxdy
      do j=1,jf
        fxy(1,j)=(fy(2,j)-fy(1,j))*hx
        fxy(if,j)=(fy(if,j)-fy(if-1,j))*hx
        do i=2,if-1
          fxy(i,j)=(fy(i+1,j)-fy(i-1,j))*hx2
        enddo
      enddo
      LL=2
      DO 15 J=1,JFI
      DO 22 L=LL,JF
        L1=L-1
        IF(YI(J).LE.Y(L)) GO TO 23
   22 CONTINUE
*
   23 continue
      LL=L1+1
      WN=YI(J)-Y(L1)
      WE=WN*hy
      WE1=1.-WE
      WE2=WE1*WE1
      WW=2.*WE
      ZA(J)=WE2*WN
      ZB(J)=WE1*WN*WE
      ZC(J)=WE2*(1.+WW)
      ZD(J)=WE*WE*(3.-WW)
   15 CONTINUE
*
      KK=2
      DO 11 I=1,IFI
      DO 12 K=KK,IF
        K1=K-1
        IF(XI(I).LE.X(K)) then
          GO TO 13
        endif
   12 CONTINUE
*
   13 continue
      KK=K1+1
      WM=XI(I)-X(K1)
      WZ=WM*hx
      WZ1=1.-WZ
      WZ2=WZ1*WZ1
      ZZ=2.*WZ
      ZE=WZ2*WM
      ZF=WZ1*WM*WZ
      ZG=WZ2*(1.+ZZ)
      ZL=WZ*WZ*(3.-ZZ)
      LL=2
      DO 115 J=1,JFI
      DO 122 L=LL,JF
        L1=L-1
        IF(YI(J).LE.Y(L)) then
          GO TO 123
        endif
  122 CONTINUE
*
  123 continue
      LL=L1+1
      Z=ZA(J)*(ZE*FXY(K1,L1)-ZF*FXY(K,L1)+ZG*FY(K1,L1)+ZL*FY(K,L1))
      Z=Z-ZB(J)*(ZE*FXY(K1,L)-ZF*FXY(K,L)+ZG*FY(K1,L)+ZL*FY(K,L))
      Z=Z+ZC(J)*(ZE*FX(K1,L1)-ZF*FX(K,L1)+ZG*F(K1,L1)+ZL*F(K,L1))
      Z=Z+ZD(J)*(ZE*FX(K1,L)-ZF*FX(K,L)+ZG*F(K1,L)+ZL*F(K,L))
      FI(I,J)=Z
  115 CONTINUE
*
   11 CONTINUE
*
*--------------------------------------------------------------------
*
      RETURN
      END

      subroutine grid_to_grid_interp(FI,IFI,JFI,F,IF,JF,indxx,indxy, 2
     %           cxa,cxb,cxc,cxd,cya,cyb,cyc,cyd,interp)
      implicit none
      character* (*) interp
      integer if,jf,ifi,jfi
      integer i,j
      REAL FI     (IFI,JFI)
      REAL F      (IF ,JF )
      real*8 cxa(ifi),cxb(ifi),cxc(ifi),cxd(ifi)
      real*8 cya(jfi),cyb(jfi),cyc(jfi),cyd(jfi)
      integer indxx(ifi),indxy(ifi)

      real *8 ta,tb,tc,td
      integer ix,jy

      if (interp.eq.'CUB_LAG') then
      do j=1,jfi
        jy=indxy(j)
        do i=1,ifi
          ix=indxx(i)
          ta=f(ix,jy  )*cxa(i)+f(ix+1,jy  )*cxb(i)+f(ix+2,jy  )*cxc(i)+f(ix+3,jy  )*cxd(i)

          tb=f(ix,jy+1)*cxa(i)+f(ix+1,jy+1)*cxb(i)+f(ix+2,jy+1)*cxc(i)+f(ix+3,jy+1)*cxd(i)
          tc=f(ix,jy+2)*cxa(i) + f(ix+1,jy+2)*cxb(i) + f(ix+2,jy+2)*cxc(i) + f(ix+3,jy+2)*cxd(i)
          td=f(ix,jy+3)*cxa(i)+f(ix+1,jy+3)*cxb(i)+f(ix+2,jy+3)*cxc(i)+f(ix+3,jy+3)*cxd(i)
!	print *,'i,j,ix,jy,ta,tb,tc,td=',i,j,ix,jy,ta,tb,tc,td
          fi(i,j)=cya(j)*ta+cyb(j)*tb+cyc(j)*tc+cyd(j)*td
!        print *,cya(j),cyb(j),cyc(j),cyd(j),fi(i,j)
        enddo
      enddo
      endif
*
      if (interp.eq.'LINEAR') then
      do j=1,jfi
        jy=indxy(j)
        do i=1,ifi
          ix=indxx(i)
          ta=f(ix,jy  )*cxa(i) + f(ix+1,jy  )*(1.0d0-cxa(i))
          tb=f(ix,jy+1)*cxa(i) + f(ix+1,jy+1)*(1.0d0-cxa(i))
          fi(i,j)=cya(j)*ta + (1.0d0-cya(j))*tb
        enddo
      enddo
      endif
*
      if (interp.eq.'NEAREST') then
      do j=1,jfi
        jy=indxy(j)
        do i=1,ifi
          ix=indxx(i)
          fi(i,j)=f(ix,jy  )
        enddo
      enddo
      endif
*
      return
      end


      subroutine grid_to_grid_coef(xi,ifi,x,if,index,cxa,cxb,cxc,cxd,interp) 18
      implicit none
      character* (*) interp
      integer if,ifi,index(ifi)
      real*8 xi(ifi),x(if)
      real*8 cxa(ifi),cxb(ifi),cxc(ifi),cxd(ifi),mid
      parameter (mid = 0.5d0)

      integer ii,i
      real *8 da,db,dc,dd,xa,xb,xc,xd

      real *8 triprd,za,zb,zc,zd,xxi
      triprd(za,zb,zc,zd)=(za-zb)*(za-zc)*(za-zd)
      if (interp.eq.'CUB_LAG') then
      ii=4
      xa=x(1)
      xb=x(2)
      xc=x(3)
      xd=x(4)
      da=1.0/triprd(xa,xb,xc,xd)
      db=1.0/triprd(xb,xa,xc,xd)
      dc=1.0/triprd(xc,xa,xb,xd)
      dd=1.0/triprd(xd,xa,xb,xc)

      do i=1,ifi
        do while( xi(i).gt.xc .and. ii.lt.if)
          ii=ii+1
          xa=xb
          xb=xc
          xc=xd
          xd=x(ii)
          da=1.0/triprd(xa,xb,xc,xd)
          db=1.0/triprd(xb,xa,xc,xd)
          dc=1.0/triprd(xc,xa,xb,xd)
          dd=1.0/triprd(xd,xa,xb,xc)
        end do
        xxi=xi(i)
        index(i)=ii-3
        cxa(i)=da*triprd(xxi,xb,xc,xd)
        cxb(i)=db*triprd(xxi,xa,xc,xd)
        cxc(i)=dc*triprd(xxi,xa,xb,xd)
        cxd(i)=dd*triprd(xxi,xa,xb,xc)
      enddo
      endif
*
      if (interp.eq.'LINEAR') then
      ii=2
      xa=x(1)
      xb=x(2)
      da=xb-xa
      do i=1,ifi
        do while( xi(i).gt.xb .and. ii.lt.if)
          ii=ii+1
          xa=xb
          xb=x(ii)
          da=xb-xa
        end do
        xxi= xi(i)
        index(i)=ii-1
        cxa(i) = (xb-xxi) / da
      enddo
      endif
*
      if (interp.eq.'NEAREST') then
      ii=2
      xa=x(1)
      xb=x(2)
      da=xb-xa
      do i=1,ifi
        do while( xi(i).gt.xb .and. ii.lt.if)
          ii=ii+1
          xa=xb
          xb=x(ii)
          da=xb-xa
        end do
        xxi=xi(i)
        index(i)=ii-1
        db = 1.0d0 - (xb-xxi) / da
        if ( db .gt. mid ) index(i) = ii
      enddo
      endif
*
      return
      end
*