Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=wp), | intent(in), | dimension(n) | :: | x | vector of length n containing data point abscissa in strictly increasing order. |
|
real(kind=wp), | intent(in), | dimension(n) | :: | y | corresponding vector of length n containing data point ordinates. |
|
real(kind=wp), | intent(in), | dimension(*) | :: | t | knot vector of length n+k since t(1),..,t(k) <= x(1) and t(n+1),..,t(n+k)
|
|
integer, | intent(in) | :: | n | number of data points, n >= k |
||
integer, | intent(in) | :: | k | order of the spline, k >= 1 |
||
real(kind=wp), | intent(out), | dimension(n) | :: | bcoef | a vector of length n containing the b-spline coefficients |
|
real(kind=wp), | intent(out), | dimension(*) | :: | q | a work vector of length (2k-1)n, containing the triangular factorization of the coefficient matrix of the linear system being solved. the coefficients for the interpolant of an additional data set (x(i),yy(i)), i=1,…,n with the same abscissa can be obtained by loading yy into bcoef and then executing call dbnslv(q,2k-1,n,k-1,k-1,bcoef) |
|
real(kind=wp), | intent(out), | dimension(*) | :: | work | work vector of length 2*k |
|
integer, | intent(out) | :: | iflag | corresponding basis function and the system is singular. 104: the system of solver detects a singular system. although the theoretical conditions for a solution were satisfied. |
subroutine dbintk(x,y,t,n,k,bcoef,q,work,iflag)
implicit none
integer,intent(in) :: n !! number of data points, n >= k
real(wp),dimension(n),intent(in) :: x !! vector of length n containing data point abscissa
!! in strictly increasing order.
real(wp),dimension(n),intent(in) :: y !! corresponding vector of length n containing data
!! point ordinates.
real(wp),dimension(*),intent(in) :: t !! knot vector of length n+k
!! since t(1),..,t(k) <= x(1) and t(n+1),..,t(n+k)
!! >= x(n), this leaves only n-k knots (not
!! necessarily x(i) values) interior to (x(1),x(n))
integer,intent(in) :: k !! order of the spline, k >= 1
real(wp),dimension(n),intent(out) :: bcoef !! a vector of length n containing the b-spline coefficients
real(wp),dimension(*),intent(out) :: q !! a work vector of length (2*k-1)*n, containing
!! the triangular factorization of the coefficient
!! matrix of the linear system being solved. the
!! coefficients for the interpolant of an
!! additional data set (x(i),yy(i)), i=1,...,n
!! with the same abscissa can be obtained by loading
!! yy into bcoef and then executing
!! call dbnslv(q,2k-1,n,k-1,k-1,bcoef)
real(wp),dimension(*),intent(out) :: work !! work vector of length 2*k
integer,intent(out) :: iflag !! 0: no errors.
!! 100: k does not satisfy k>=1.
!! 101: n does not satisfy n>=k.
!! 102: x(i) does not satisfy x(i)<x(i+1) for some i.
!! 103: some abscissa was not in the support of the.
!! corresponding basis function and the system is singular.
!! 104: the system of solver detects a singular system.
!! although the theoretical conditions for a solution were satisfied.
integer :: iwork, i, ilp1mx, j, jj, km1, kpkm2, left,lenq, np1
real(wp) :: xi
if (k<1) then
write(error_unit,'(A)') 'dbintk - k does not satisfy k>=1'
iflag = 100
return
endif
if (n<k) then
write(error_unit,'(A)') 'dbintk - n does not satisfy n>=k'
iflag = 101
return
endif
jj = n - 1
if (jj/=0) then
do i=1,jj
if (x(i)>=x(i+1)) then
write(error_unit,'(A)') 'dbintk - x(i) does not satisfy x(i)<x(i+1) for some i'
iflag = 102
return
endif
enddo
endif
np1 = n + 1
km1 = k - 1
kpkm2 = 2*km1
left = k
! zero out all entries of q
lenq = n*(k+km1)
do i=1,lenq
q(i) = 0.0_wp
enddo
! loop over i to construct the n interpolation equations
do i=1,n
xi = x(i)
ilp1mx = min(i+k,np1)
! *** find left in the closed interval (i,i+k-1) such that
! t(left) <= x(i) < t(left+1)
! matrix is singular if this is not possible
left = max(left,i)
if (xi<t(left)) then
write(error_unit,'(A)') 'dbintk - some abscissa was not in the support of the'//&
' corresponding basis function and the system is singular'
iflag = 103
return
endif
do
if (xi<t(left+1)) go to 30
left = left + 1
if (left>=ilp1mx) exit
enddo
left = left - 1
if (xi>t(left+1)) then
write(error_unit,'(A)') 'dbintk - some abscissa was not in the support of the'//&
' corresponding basis function and the system is singular'
iflag = 103
return
endif
! *** the i-th equation enforces interpolation at xi, hence
! a(i,j) = b(j,k,t)(xi), all j. only the k entries with j =
! left-k+1,...,left actually might be nonzero. these k numbers
! are returned, in bcoef (used for temp.storage here), by the
! following
30 call dbspvn(t, k, k, 1, xi, left, bcoef, work, iwork, iflag)
if (iflag/=0) return
! we therefore want bcoef(j) = b(left-k+j)(xi) to go into
! a(i,left-k+j), i.e., into q(i-(left+j)+2*k,(left+j)-k) since
! a(i+j,j) is to go into q(i+k,j), all i,j, if we consider q
! as a two-dim. array , with 2*k-1 rows (see comments in
! dbnfac). in the present program, we treat q as an equivalent
! one-dimensional array (because of fortran restrictions on
! dimension statements) . we therefore want bcoef(j) to go into
! entry
! i -(left+j) + 2*k + ((left+j) - k-1)*(2*k-1)
! = i-left+1 + (left -k)*(2*k-1) + (2*k-2)*j
! of q.
jj = i - left + 1 + (left-k)*(k+km1)
do j=1,k
jj = jj + kpkm2
q(jj) = bcoef(j)
enddo
enddo
! obtain factorization of a, stored again in q.
call dbnfac(q, k+km1, n, km1, km1, iflag)
if (iflag==1) then !success
! *** solve a*bcoef = y by backsubstitution
do i=1,n
bcoef(i) = y(i)
enddo
call dbnslv(q, k+km1, n, km1, km1, bcoef)
iflag = 0
else !failure
write(error_unit,'(A)') 'dbintk - the system of solver detects a singular system'//&
' although the theoretical conditions for a solution were satisfied'
iflag = 104
endif
endsubroutine dbintk