44 integer,
intent(in) :: n
46 real(dp),
intent(in) :: x(n)
48 real(dp),
intent(in) :: y(n)
50 real(dp),
allocatable :: b(:), c(:), d(:)
51 integer :: i, j, lookup_size
52 real(dp) :: h, x_lookup, min_dx
55 error stop
"spline_set_coeffs requires n >= 2"
56 if (any(x(2:n) <= x(1:n-1))) &
57 error stop
"spline_set_coeffs: x(:) not strictly increasing"
59 allocate(spl%x(n), spl%y(n), spl%bcd(3, n), b(n), c(n), d(n))
66 b(1) = (y(2)-y(1))/(x(2)-x(1))
78 c(2) = (y(2) - y(1))/d(1)
81 b(i) = 2*(d(i-1) + d(i))
82 c(i+1) = (y(i+1) - y(i))/d(i)
93 c(1) = c(3)/(x(4)-x(2)) - c(2)/(x(3)-x(1))
94 c(n) = c(n-1)/(x(n)-x(n-2)) - c(n-2)/(x(n-1)-x(n-3))
95 c(1) = c(1)*d(1)**2/(x(4)-x(1))
96 c(n) = -c(n)*d(n-1)**2/(x(n)-x(n-3))
102 b(i) = b(i) - h*d(i-1)
103 c(i) = c(i) - h*c(i-1)
110 c(i) = (c(i) - d(i)*c(i+1))/b(i)
114 b(n) = (y(n) - y(n-1))/d(n-1) + d(n-1)*(c(n-1) + 2*c(n))
116 b(i) = (y(i+1) - y(i))/d(i) - d(i)*(c(i+1) + 2*c(i))
117 d(i) = (c(i+1) - c(i))/d(i)
129 min_dx = minval(x(2:n) - x(1:n-1))
130 lookup_size = min(4 * n, nint(1 + (x(n) - x(1))/min_dx))
133 h = (x(n) - x(1)) / (lookup_size - 1)
134 spl%lookup_inv_dx = 1/h
135 allocate(spl%lookup_index(lookup_size))
139 spl%lookup_index(1) = 1
140 do i = 2, lookup_size
141 x_lookup = x(1) + (i-1) * h
142 spl%lookup_index(i) = spl%lookup_index(i-1)
143 do while (x_lookup > x(spl%lookup_index(i)+1))
144 spl%lookup_index(i) = spl%lookup_index(i) + 1
155 real(dp),
intent(in) :: u
159 real(dp) :: spline_value, dx
161 associate(n=>spl%n, x=>spl%x, y=>spl%y, bcd=>spl%bcd)
165 else if(u >= x(n))
then
170 j = ceiling(spl%lookup_inv_dx * (u - x(1)))
176 else if (j >
size(spl%lookup_index))
then
177 j =
size(spl%lookup_index)
184 do i = spl%lookup_index(j), n-1
185 if (u <= x(i+1))
exit
190 spline_value = y(i) + dx*(bcd(1, i) + dx*(bcd(2, i) + dx*bcd(3, i)))