1 | module pchsp_95_m |
---|
2 | |
---|
3 | implicit none |
---|
4 | |
---|
5 | contains |
---|
6 | |
---|
7 | function pchsp_95(x, f, ibeg, iend, vc_beg, vc_end) |
---|
8 | |
---|
9 | ! PURPOSE: Set derivatives needed to determine the Hermite |
---|
10 | ! representation of the cubic spline interpolant to given data, |
---|
11 | ! with specified boundary conditions. |
---|
12 | |
---|
13 | ! Part of the "pchip" package. |
---|
14 | |
---|
15 | ! CATEGORY: E1A |
---|
16 | |
---|
17 | ! KEYWORDS: cubic hermite interpolation, piecewise cubic |
---|
18 | ! interpolation, spline interpolation |
---|
19 | |
---|
20 | ! DESCRIPTION: "pchsp" stands for "Piecewise Cubic Hermite Spline" |
---|
21 | ! Computes the Hermite representation of the cubic spline |
---|
22 | ! interpolant to the data given in X and F satisfying the boundary |
---|
23 | ! conditions specified by Ibeg, iend, vc_beg and VC_end. |
---|
24 | |
---|
25 | ! The resulting piecewise cubic Hermite function may be evaluated |
---|
26 | ! by "pchfe" or "pchfd". |
---|
27 | |
---|
28 | ! NOTE: This is a modified version of C. de Boor's cubic spline |
---|
29 | ! routine "cubspl". |
---|
30 | |
---|
31 | ! REFERENCE: Carl de Boor, A Practical Guide to Splines, Springer, |
---|
32 | ! 2001, pages 43-47 |
---|
33 | |
---|
34 | use assert_eq_m, only: assert_eq |
---|
35 | |
---|
36 | real, intent(in):: x(:) |
---|
37 | ! independent variable values |
---|
38 | ! The elements of X must be strictly increasing: |
---|
39 | ! X(I-1) < X(I), I = 2...N. |
---|
40 | ! (Error return if not.) |
---|
41 | ! (error if size(x) < 2) |
---|
42 | |
---|
43 | real, intent(in):: f(:) |
---|
44 | ! dependent variable values to be interpolated |
---|
45 | ! F(I) is value corresponding to X(I). |
---|
46 | |
---|
47 | INTEGER, intent(in):: ibeg |
---|
48 | ! desired boundary condition at beginning of data |
---|
49 | |
---|
50 | ! IBEG = 0 to set pchsp_95(1) so that the third derivative is con- |
---|
51 | ! tinuous at X(2). This is the "not a knot" condition |
---|
52 | ! provided by de Boor's cubic spline routine CUBSPL. |
---|
53 | ! This is the default boundary condition. |
---|
54 | ! IBEG = 1 if first derivative at X(1) is given in VC_BEG. |
---|
55 | ! IBEG = 2 if second derivative at X(1) is given in VC_BEG. |
---|
56 | ! IBEG = 3 to use the 3-point difference formula for pchsp_95(1). |
---|
57 | ! (Reverts to the default boundary condition if size(x) < 3 .) |
---|
58 | ! IBEG = 4 to use the 4-point difference formula for pchsp_95(1). |
---|
59 | ! (Reverts to the default boundary condition if size(x) < 4 .) |
---|
60 | |
---|
61 | ! NOTES: |
---|
62 | ! 1. An error return is taken if IBEG is out of range. |
---|
63 | ! 2. For the "natural" boundary condition, use IBEG=2 and |
---|
64 | ! VC_BEG=0. |
---|
65 | |
---|
66 | INTEGER, intent(in):: iend |
---|
67 | ! IC(2) = IEND, desired condition at end of data. |
---|
68 | ! IEND may take on the same values as IBEG, but applied to |
---|
69 | ! derivative at X(N). In case IEND = 1 or 2, The value is given in VC_END. |
---|
70 | |
---|
71 | ! NOTES: |
---|
72 | ! 1. An error return is taken if IEND is out of range. |
---|
73 | ! 2. For the "natural" boundary condition, use IEND=2 and |
---|
74 | ! VC_END=0. |
---|
75 | |
---|
76 | REAL, intent(in), optional:: vc_beg |
---|
77 | ! desired boundary value, as indicated above. |
---|
78 | ! VC_BEG need be set only if IBEG = 1 or 2 . |
---|
79 | |
---|
80 | REAL, intent(in), optional:: vc_end |
---|
81 | ! desired boundary value, as indicated above. |
---|
82 | ! VC_END need be set only if Iend = 1 or 2 . |
---|
83 | |
---|
84 | real pchsp_95(size(x)) |
---|
85 | ! derivative values at the data points |
---|
86 | ! These values will determine the cubic spline interpolant |
---|
87 | ! with the requested boundary conditions. |
---|
88 | ! The value corresponding to X(I) is stored in |
---|
89 | ! PCHSP_95(I), I=1...N. |
---|
90 | |
---|
91 | ! LOCAL VARIABLES: |
---|
92 | real wk(2, size(x)) ! real array of working storage |
---|
93 | INTEGER n ! number of data points |
---|
94 | integer ierr, ic(2) |
---|
95 | real vc(2) |
---|
96 | |
---|
97 | !------------------------------------------------------------------- |
---|
98 | |
---|
99 | n = assert_eq(size(x), size(f), "pchsp_95 n") |
---|
100 | if ((ibeg == 1 .or. ibeg == 2) .and. .not. present(vc_beg)) then |
---|
101 | print *, "vc_beg required for IBEG = 1 or 2" |
---|
102 | stop 1 |
---|
103 | end if |
---|
104 | if ((iend == 1 .or. iend == 2) .and. .not. present(vc_end)) then |
---|
105 | print *, "vc_end required for IEND = 1 or 2" |
---|
106 | stop 1 |
---|
107 | end if |
---|
108 | ic = (/ibeg, iend/) |
---|
109 | if (present(vc_beg)) vc(1) = vc_beg |
---|
110 | if (present(vc_end)) vc(2) = vc_end |
---|
111 | call PCHSP(IC, VC, N, X, F, pchsp_95, 1, WK, size(WK), IERR) |
---|
112 | if (ierr /= 0) stop 1 |
---|
113 | |
---|
114 | END function pchsp_95 |
---|
115 | |
---|
116 | end module pchsp_95_m |
---|