-
1
- #1
starlite79
Technical User
I'd like to use IMPLICIT NONE for a subroutine called spline.f attached below. However, trying to declare all variables correctly is giving me erroneous results. The arrays are being passed by another routine that is calling spline.f. If I try to use IMPLICIT NONE as the only change, I get the obvious NO IMPLICIT type errors as well as a type/rank mismatch for argument U1.
Here is the code:
I thought U1, U2, X1, and X2 are real and the array Q should be declared like this: Q(*,*,*,*), but this doesn't work (output from main program yields NaN). Could someone offer a hint about how to use IMPLICIT NONE correctly?
Here is the code:
Code:
subroutine spline(nn,x,u,s,a)
c
c$$$$ calls no other routines
c finds array s for spline interpolator eval.
c nn number of data points supplied (may be negative, see below)
c x array containing x-coordinates where function is sampled. xx(1),xx(2),...
c must be a strictly increasing sequence.
c u array containing sample values that are to be interpolated.
c s output array of 2nd derivative at sample points.
c a working space array of dimension at least nn.
c if the user wishes to force the derivatives at the ends of the series to
c assume specified values, he should put du(1)/dx and du(n)/dx in s1,s2
c and call the routine with nn=-number of terms in series. normally a parabola
c is fitted through the 1st and last 3 points to find the slopes.
c if less than 4 points are supplied, straight lines are fitted.
c
integer i,j,n,n1,nn
real a,c,q,q1,qn,s,u,x
dimension x(*),u(*),s(*),a(*)
c
q(u1,x1,u2,x2)=(u1/x1**2-u2/x2**2)/(1.0/x1-1.0/x2)
c
n=iabs(nn)
if (n.le.3) then
c series too short for cubic spline - use straight lines.
do i=1,n
s(i)=0.0
enddo
return
endif
q1=q(u(2)-u(1),x(2)-x(1),u(3)-u(1),x(3)-x(1))
qn=q(u(n-1)-u(n),x(n-1)-x(n),u(n-2)-u(n),x(n-2)-x(n))
if (nn.le.0) then
q1=s(1)
qn=s(2)
endif
s(1)=6.0*((u(2)-u(1))/(x(2)-x(1)) - q1)
n1= n - 1
do i=2,n1
s(i)= (u(i-1)/(x(i)-x(i-1)) - u(i)*(1.0/(x(i)-x(i-1))+
+ 1.0/(x(i+1)-x(i))) + u(i+1)/(x(i+1)-x(i)))*6.0
enddo
s(n)=6.0*(qn + (u(n1)-u(n))/(x(n)-x(n1)))
a(1)=2.0*(x(2)-x(1))
a(2)=1.5*(x(2)-x(1)) + 2.0*(x(3)-x(2))
s(2)=s(2) - 0.5*s(1)
do i=3,n1
c=(x(i)-x(i-1))/a(i-1)
a(i)=2.0*(x(i+1)-x(i-1)) - c*(x(i)-x(i-1))
s(i)=s(i) - c*s(i-1)
enddo
c=(x(n)-x(n1))/a(n1)
a(n)=(2.0-c)*(x(n)-x(n1))
s(n)=s(n) - c*s(n1)
c back substitiute
s(n)= s(n)/a(n)
do j=1,n1
i=n-j
s(i) =(s(i) - (x(i+1)-x(i))*s(i+1))/a(i)
enddo
return
end
I thought U1, U2, X1, and X2 are real and the array Q should be declared like this: Q(*,*,*,*), but this doesn't work (output from main program yields NaN). Could someone offer a hint about how to use IMPLICIT NONE correctly?