dbspvn.f 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. *DECK DBSPVN
  2. SUBROUTINE DBSPVN (T, JHIGH, K, INDEX, X, ILEFT, VNIKX, WORK,
  3. + IWORK)
  4. C***BEGIN PROLOGUE DBSPVN
  5. C***PURPOSE Calculate the value of all (possibly) nonzero basis
  6. C functions at X.
  7. C***LIBRARY SLATEC
  8. C***CATEGORY E3, K6
  9. C***TYPE DOUBLE PRECISION (BSPVN-S, DBSPVN-D)
  10. C***KEYWORDS EVALUATION OF B-SPLINE
  11. C***AUTHOR Amos, D. E., (SNLA)
  12. C***DESCRIPTION
  13. C
  14. C Written by Carl de Boor and modified by D. E. Amos
  15. C
  16. C Abstract **** a double precision routine ****
  17. C DBSPVN is the BSPLVN routine of the reference.
  18. C
  19. C DBSPVN calculates the value of all (possibly) nonzero basis
  20. C functions at X of order MAX(JHIGH,(J+1)*(INDEX-1)), where T(K)
  21. C .LE. X .LE. T(N+1) and J=IWORK is set inside the routine on
  22. C the first call when INDEX=1. ILEFT is such that T(ILEFT) .LE.
  23. C X .LT. T(ILEFT+1). A call to DINTRV(T,N+1,X,ILO,ILEFT,MFLAG)
  24. C produces the proper ILEFT. DBSPVN calculates using the basic
  25. C algorithm needed in DBSPVD. If only basis functions are
  26. C desired, setting JHIGH=K and INDEX=1 can be faster than
  27. C calling DBSPVD, but extra coding is required for derivatives
  28. C (INDEX=2) and DBSPVD is set up for this purpose.
  29. C
  30. C Left limiting values are set up as described in DBSPVD.
  31. C
  32. C Description of Arguments
  33. C
  34. C Input T,X are double precision
  35. C T - knot vector of length N+K, where
  36. C N = number of B-spline basis functions
  37. C N = sum of knot multiplicities-K
  38. C JHIGH - order of B-spline, 1 .LE. JHIGH .LE. K
  39. C K - highest possible order
  40. C INDEX - INDEX = 1 gives basis functions of order JHIGH
  41. C = 2 denotes previous entry with work, IWORK
  42. C values saved for subsequent calls to
  43. C DBSPVN.
  44. C X - argument of basis functions,
  45. C T(K) .LE. X .LE. T(N+1)
  46. C ILEFT - largest integer such that
  47. C T(ILEFT) .LE. X .LT. T(ILEFT+1)
  48. C
  49. C Output VNIKX, WORK are double precision
  50. C VNIKX - vector of length K for spline values.
  51. C WORK - a work vector of length 2*K
  52. C IWORK - a work parameter. Both WORK and IWORK contain
  53. C information necessary to continue for INDEX = 2.
  54. C When INDEX = 1 exclusively, these are scratch
  55. C variables and can be used for other purposes.
  56. C
  57. C Error Conditions
  58. C Improper input is a fatal error.
  59. C
  60. C***REFERENCES Carl de Boor, Package for calculating with B-splines,
  61. C SIAM Journal on Numerical Analysis 14, 3 (June 1977),
  62. C pp. 441-472.
  63. C***ROUTINES CALLED XERMSG
  64. C***REVISION HISTORY (YYMMDD)
  65. C 800901 DATE WRITTEN
  66. C 890831 Modified array declarations. (WRB)
  67. C 890831 REVISION DATE from Version 3.2
  68. C 891214 Prologue converted to Version 4.0 format. (BAB)
  69. C 900315 CALLs to XERROR changed to CALLs to XERMSG. (THJ)
  70. C 920501 Reformatted the REFERENCES section. (WRB)
  71. C***END PROLOGUE DBSPVN
  72. C
  73. INTEGER ILEFT, IMJP1, INDEX, IPJ, IWORK, JHIGH, JP1, JP1ML, K, L
  74. DOUBLE PRECISION T, VM, VMPREV, VNIKX, WORK, X
  75. C DIMENSION T(ILEFT+JHIGH)
  76. DIMENSION T(*), VNIKX(*), WORK(*)
  77. C CONTENT OF J, DELTAM, DELTAP IS EXPECTED UNCHANGED BETWEEN CALLS.
  78. C WORK(I) = DELTAP(I), WORK(K+I) = DELTAM(I), I = 1,K
  79. C***FIRST EXECUTABLE STATEMENT DBSPVN
  80. IF(K.LT.1) GO TO 90
  81. IF(JHIGH.GT.K .OR. JHIGH.LT.1) GO TO 100
  82. IF(INDEX.LT.1 .OR. INDEX.GT.2) GO TO 105
  83. IF(X.LT.T(ILEFT) .OR. X.GT.T(ILEFT+1)) GO TO 110
  84. GO TO (10, 20), INDEX
  85. 10 IWORK = 1
  86. VNIKX(1) = 1.0D0
  87. IF (IWORK.GE.JHIGH) GO TO 40
  88. C
  89. 20 IPJ = ILEFT + IWORK
  90. WORK(IWORK) = T(IPJ) - X
  91. IMJP1 = ILEFT - IWORK + 1
  92. WORK(K+IWORK) = X - T(IMJP1)
  93. VMPREV = 0.0D0
  94. JP1 = IWORK + 1
  95. DO 30 L=1,IWORK
  96. JP1ML = JP1 - L
  97. VM = VNIKX(L)/(WORK(L)+WORK(K+JP1ML))
  98. VNIKX(L) = VM*WORK(L) + VMPREV
  99. VMPREV = VM*WORK(K+JP1ML)
  100. 30 CONTINUE
  101. VNIKX(JP1) = VMPREV
  102. IWORK = JP1
  103. IF (IWORK.LT.JHIGH) GO TO 20
  104. C
  105. 40 RETURN
  106. C
  107. C
  108. 90 CONTINUE
  109. CALL XERMSG ('SLATEC', 'DBSPVN', 'K DOES NOT SATISFY K.GE.1', 2,
  110. + 1)
  111. RETURN
  112. 100 CONTINUE
  113. CALL XERMSG ('SLATEC', 'DBSPVN',
  114. + 'JHIGH DOES NOT SATISFY 1.LE.JHIGH.LE.K', 2, 1)
  115. RETURN
  116. 105 CONTINUE
  117. CALL XERMSG ('SLATEC', 'DBSPVN', 'INDEX IS NOT 1 OR 2', 2, 1)
  118. RETURN
  119. 110 CONTINUE
  120. CALL XERMSG ('SLATEC', 'DBSPVN',
  121. + 'X DOES NOT SATISFY T(ILEFT).LE.X.LE.T(ILEFT+1)', 2, 1)
  122. RETURN
  123. END