subroutine init_cubic_spline(n,x,y,y2)
  implicit none
  integer,intent(in) :: n
  real(kind=8), dimension(n), intent(in) :: x,y
  real(kind=8), dimension(n), intent(out) :: y2
  integer i,j
  real(kind=8) a,b
  real(kind=8), allocatable, dimension(:) :: tmp

  allocate(tmp(n));tmp=0.d0
  y2 = 0.0d0

  do i=2,n-1
    a=(x(i)-x(i-1))/(x(i+1)-x(i-1))
    b=a*y2(i-1)+2
    y2(i)=(a-1)/b
    tmp(i)=(6.d0*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1)) &
    & /(x(i)-x(i-1)))/(x(i+1)-x(i-1))-a*tmp(i-1))/b
  enddo

  do j=n-1,1,-1
    y2(j) = y2(j)*y2(j+1)+tmp(j)
  enddo
  deallocate(tmp)

end subroutine init_cubic_spline

subroutine cubic_spline(n,x,y,y2,xin,yout,y1out)
  integer, intent(in) :: n
  real(kind=8), dimension(n), intent(in) :: x,y,y2
  real(kind=8), intent(in) :: xin
  real(kind=8), intent(out) :: yout,y1out
  real(kind=8) :: a,b,h
  integer :: i,i0,i1

  i0=1
  i1=n

  do while ( (i1-i0).gt.1 ) 
    i=(i1+i0)/2
    if (x(i).gt.xin) then
        i1=i
    else
        i0=i
    endif
  enddo

  h=x(i1)-x(i0)
  a=(x(i1)-xin)/h
  b=(xin-x(i0))/h
  yout  = a*y(i0)+b*y(i1)+((a*a*a-a)*y2(i0)+(b*b*b-b)*y2(i1))*(h**2)/6.0d0
  y1out = (y(i1)-y(i0))/h-(3.0d0*a*a-1)/6.0d0*h*y2(i0)+(3.0d0*b*b-1)/6.0d0*h*y2(i1)
end subroutine cubic_spline

