The Elk Code
spline.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2011 J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3 ! This file is distributed under the terms of the GNU Lesser General Public
4 ! License. See the file COPYING for license details.
5 
6 !BOP
7 ! !ROUTINE: spline
8 ! !INTERFACE:
9 subroutine spline(n,x,f,cf)
10 ! !INPUT/OUTPUT PARAMETERS:
11 ! n : number of points (in,integer)
12 ! x : abscissa array (in,real(n))
13 ! f : input data array (in,real(n))
14 ! cf : cubic spline coefficients (out,real(3,n))
15 ! !DESCRIPTION:
16 ! Calculates the coefficients of a cubic spline fitted to input data. In other
17 ! words, given a set of data points $f_i$ defined at $x_i$, where
18 ! $i=1\ldots n$, the coefficients $c_j^i$ are determined such that
19 ! $$ y_i(x)=f_i+c_1^i(x-x_i)+c_2^i(x-x_i)^2+c_3^i(x-x_i)^3, $$
20 ! is the interpolating function for $x\in[x_i,x_{i+1})$. The coefficients are
21 ! determined piecewise by fitting a cubic polynomial to adjacent points.
22 !
23 ! !REVISION HISTORY:
24 ! Created November 2011 (JKD)
25 !EOP
26 !BOC
27 implicit none
28 ! arguments
29 integer, intent(in) :: n
30 real(8), intent(in) :: x(n),f(n)
31 real(8), intent(out) :: cf(3,n)
32 ! local variables
33 integer i
34 real(8) x0,x1,x2,x3,y0,y1,y2,y3
35 real(8) t0,t1,t2,t3,t4,t5,t6,t7
36 if (n < 1) then
37  write(*,*)
38  write(*,'("Error(spline): n < 1 : ",I8)') n
39  write(*,*)
40  stop
41 end if
42 if (n == 1) then
43  cf(1:3,1)=0.d0
44  return
45 end if
46 if (n == 2) then
47  cf(1,1)=(f(2)-f(1))/(x(2)-x(1))
48  cf(2:3,1)=0.d0
49  cf(1,2)=cf(1,1)
50  cf(2:3,2)=0.d0
51  return
52 end if
53 if (n == 3) then
54  x0=x(1)
55  x1=x(2)-x0; x2=x(3)-x0
56  y0=f(1)
57  y1=f(2)-y0; y2=f(3)-y0
58  t0=1.d0/(x1*x2*(x2-x1))
59  t3=x1*y2; t4=x2*y1
60  t1=t0*(x2*t4-x1*t3)
61  t2=t0*(t3-t4)
62  cf(1,1)=t1
63  cf(2,1)=t2
64  cf(3,1)=0.d0
65  t3=2.d0*t2
66  cf(1,2)=t1+t3*x1
67  cf(2,2)=t2
68  cf(3,2)=0.d0
69  cf(1,3)=t1+t3*x2
70  cf(2,3)=t2
71  cf(3,3)=0.d0
72  return
73 end if
74 x0=x(1)
75 x1=x(2)-x0; x2=x(3)-x0; x3=x(4)-x0
76 t4=x1-x2; t5=x1-x3; t6=x2-x3
77 y0=f(1)
78 y1=f(2)-y0; y2=f(3)-y0; y3=f(4)-y0
79 t1=x1*x2*y3; t2=x2*x3*y1; t3=x1*x3
80 t0=1.d0/(x2*t3*t4*t5*t6)
81 t3=t3*y2
82 t7=t0*(t1*t4+t2*t6-t3*t5)
83 t4=x1**2; t5=x2**2; t6=x3**2
84 y1=t3*t6-t1*t5; y3=t2*t5-t3*t4; y2=t1*t4-t2*t6
85 t1=t0*(x1*y1+x2*y2+x3*y3)
86 t2=-t0*(y1+y2+y3)
87 cf(1,1)=t1; cf(2,1)=t2; cf(3,1)=t7
88 cf(1,2)=t1+2.d0*t2*x1+3.d0*t7*t4
89 cf(2,2)=t2+3.d0*t7*x1
90 cf(3,2)=t7
91 if (n == 4) then
92  cf(1,3)=t1+2.d0*t2*x2+3.d0*t7*t5
93  cf(2,3)=t2+3.d0*t7*x2
94  cf(3,3)=t7
95  cf(1,4)=t1+2.d0*t2*x3+3.d0*t7*t6
96  cf(2,4)=t2+3.d0*t7*x3
97  cf(3,4)=t7
98  return
99 end if
100 do i=3,n-2
101  x0=x(i)
102  x1=x(i-1)-x0; x2=x(i+1)-x0; x3=x(i+2)-x0
103  t4=x1-x2; t5=x1-x3; t6=x2-x3
104  y0=f(i)
105  y1=f(i-1)-y0; y2=f(i+1)-y0; y3=f(i+2)-y0
106  t1=x1*x2*y3; t2=x2*x3*y1; t3=x1*x3
107  t0=1.d0/(x2*t3*t4*t5*t6)
108  t3=t3*y2
109  t7=t0*(t1*t4+t2*t6-t3*t5)
110  t4=x1**2; t5=x2**2; t6=x3**2
111  y1=t3*t6-t1*t5; y2=t1*t4-t2*t6; y3=t2*t5-t3*t4
112  t1=t0*(x1*y1+x2*y2+x3*y3)
113  t2=-t0*(y1+y2+y3)
114  cf(1,i)=t1; cf(2,i)=t2; cf(3,i)=t7
115 end do
116 cf(1,n-1)=t1+2.d0*t2*x2+3.d0*t7*t5
117 cf(2,n-1)=t2+3.d0*t7*x2
118 cf(3,n-1)=t7
119 cf(1,n)=t1+2.d0*t2*x3+3.d0*t7*t6
120 cf(2,n)=t2+3.d0*t7*x3
121 cf(3,n)=t7
122 end subroutine
123 !EOC
124 
subroutine spline(n, x, f, cf)
Definition: spline.f90:10