CoastalME (Coastal Modelling Environment)
Simulates the long-term behaviour of complex coastlines
Loading...
Searching...
No Matches
hermite_cubic.cpp
Go to the documentation of this file.
1
12
13/*===============================================================================================================================
14
15This file is part of CoastalME, the Coastal Modelling Environment.
16
17CoastalME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
18
19This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23===============================================================================================================================*/
24#include <iostream>
25using std::cout;
26using std::cerr;
27using std::endl;
28using std::ios;
29
30#include "cme.h"
31#include "hermite_cubic.h"
32
33//===============================================================================================================================
34//
35// Purpose:
36//
37// R8VEC_BRACKET3 finds the interval containing or nearest a given value.
38//
39// Discussion:
40//
41// An R8VEC is a vector of R8's.
42//
43// The routine always returns the index LEFT of the sorted array
44// T with the property that either
45// * T is contained in the interval [ T[LEFT], T[LEFT+1] ], or
46// * T < T[LEFT] = T[0], or
47// * T > T[LEFT+1] = T[N-1].
48//
49// The routine is useful for interpolation problems, where
50// the abscissa must be located within an interval of data
51// abscissas for interpolation, or the "nearest" interval
52// to the (extreme) abscissa must be found so that extrapolation
53// can be carried out.
54//
55// This version of the function has been revised so that the value of
56// LEFT that is returned uses the 0-based indexing natural to C++.
57//
58// Licensing:
59//
60// This code is distributed under the GNU LGPL license.
61//
62// Modified:
63//
64// 30 April 2009
65//
66// Author:
67//
68// John Burkardt
69//
70// Parameters:
71//
72// Input, int N, length of the input array.
73//
74// Input, double T[N], an array that has been sorted into ascending order.
75//
76// Input, double TVAL, a value to be bracketed by entries of T.
77//
78// Input/output, int *LEFT.
79// On input, if 0 <= LEFT <= N-2, LEFT is taken as a suggestion for the
80// interval [ T[LEFT-1] T[LEFT] ] in which TVAL lies. This interval
81// is searched first, followed by the appropriate interval to the left
82// or right. After that, a binary search is used.
83// On output, LEFT is set so that the interval [ T[LEFT], T[LEFT+1] ]
84// is the closest to TVAL; it either contains TVAL, or else TVAL
85// lies outside the interval [ T[0], T[N-1] ].
86//
87//===============================================================================================================================
89//===============================================================================================================================
90void r8vec_bracket3(int const n, double const* t, double const tval, int* left)
91{
92 int high;
93 int low;
94 int mid;
95
96 // Check the input data
97 if (n < 2)
98 {
99 cerr << endl << "R8VEC_BRACKET3 - Fatal error! N must be at least 2." << endl;
100 return;
101 }
102
103 // If *left is not between 0 and n-2, set it to the middle value
104 if ((*left < 0) || (n - 2 < *left))
105 {
106 *left = (n - 1) / 2;
107 }
108
109 // CASE 1: TVAL < T[*LEFT]: search for TVAL in (T[I],T[I+1]), for I = 0 to *LEFT-1.
110 if ( tval < t[*left] )
111 {
112 if ( *left == 0 )
113 {
114 return;
115 }
116 else if ( *left == 1 )
117 {
118 *left = 0;
119 return;
120 }
121 else if ( t[*left-1] <= tval )
122 {
123 *left = *left - 1;
124 return;
125 }
126 else if ( tval <= t[1] )
127 {
128 *left = 0;
129 return;
130 }
131 //
132 // ...Binary search for TVAL in (T[I],T[I+1]), for I = 1 to *LEFT-2.
133 //
134 low = 1;
135 high = *left - 2;
136
137 for ( ; ; )
138 {
139 if ( low == high )
140 {
141 *left = low;
142 return;
143 }
144
145 mid = ( low + high + 1 ) / 2;
146
147 if ( t[mid] <= tval )
148 {
149 low = mid;
150 }
151 else
152 {
153 high = mid - 1;
154 }
155 }
156 }
157 //
158 // CASE 2: T[*LEFT+1] < TVAL:
159 // Search for TVAL in (T[I],T[I+1]) for intervals I = *LEFT+1 to N-2.
160 //
161 else if ( t[*left+1] < tval )
162 {
163 if ( *left == n - 2 )
164 {
165 return;
166 }
167 else if ( *left == n - 3 )
168 {
169 *left = *left + 1;
170 return;
171 }
172 else if ( tval <= t[*left+2] )
173 {
174 *left = *left + 1;
175 return;
176 }
177 else if ( t[n-2] <= tval )
178 {
179 *left = n - 2;
180 return;
181 }
182
183 // ...Binary search for TVAL in (T[I],T[I+1]) for intervals I = *LEFT+2 to N-3.
184 low = *left + 2;
185 high = n - 3;
186
187 for ( ; ; )
188 {
189 if ( low == high )
190 {
191 *left = low;
192 return;
193 }
194
195 mid = ( low + high + 1 ) / 2;
196
197 if ( t[mid] <= tval )
198 {
199 low = mid;
200 }
201 else
202 {
203 high = mid - 1;
204 }
205 }
206 }
207
208 // CASE 3: T[*LEFT] <= TVAL <= T[*LEFT+1]: T is just where the user said it might be.
209 else
210 {
211 }
212
213 return;
214}
215
216//===============================================================================================================================
217//
218// Purpose:
219//
220// HERMITE_CUBIC_VALUE evaluates a Hermite cubic polynomial.
221//
222// Discussion:
223//
224// The input arguments can be vectors.
225//
226// Licensing:
227//
228// This code is distributed under the GNU LGPL license.
229//
230// Modified:
231//
232// 13 February 2011
233//
234// Author:
235//
236// John Burkardt
237//
238// Reference:
239//
240// Fred Fritsch, Ralph Carlson,
241// Monotone Piecewise Cubic Interpolation,
242// SIAM Journal on Numerical Analysis,
243// Volume 17, Number 2, April 1980, pages 238-246.
244//
245// Parameters:
246//
247// Input, double X1, F1, D1, the left endpoint, function value
248// and derivative.
249//
250// Input, double X2, F2, D2, the right endpoint, function value
251// and derivative.
252//
253// Input, int N, the number of evaluation points.
254//
255// Input, double X[N], the points at which the Hermite cubic
256// is to be evaluated.
257//
258// Output, double F[N], D[N], S[N], T[N], the value and first
259// three derivatives of the Hermite cubic at X.
260//
261//===============================================================================================================================
263void hermite_cubic_value(double const x1, double const f1, double const d1, double const x2, double const f2, double const d2, int const n, double const* x, double* f, double* d, double* s, double* t)
264{
265 double c2;
266 double c3;
267 double df;
268 double h;
269 int i;
270
271 h = x2 - x1;
272 df = (f2 - f1) / h;
273
274 c2 = - ( 2.0 * d1 - 3.0 * df + d2 ) / h;
275 c3 = ( d1 - 2.0 * df + d2 ) / h / h;
276
277 for (i = 0; i < n; i++)
278 {
279 f[i] = f1 + ( x[i] - x1 ) * ( d1
280 + ( x[i] - x1 ) * ( c2
281 + ( x[i] - x1 ) * c3 ) );
282 d[i] = d1 + ( x[i] - x1 ) * ( 2.0 * c2
283 + ( x[i] - x1 ) * 3.0 * c3 );
284 s[i] = 2.0 * c2 + ( x[i] - x1 ) * 6.0 * c3;
285 t[i] = 6.0 * c3;
286 }
287 return;
288}
289
290//===============================================================================================================================
291//
292// Purpose:
293//
294// HERMITE_CUBIC_SPLINE_VALUE evaluates a Hermite cubic spline.
295//
296// Licensing:
297//
298// This code is distributed under the GNU LGPL license.
299//
300// Modified:
301//
302// 13 February 2011
303//
304// Author:
305//
306// John Burkardt
307//
308// Reference:
309//
310// Fred Fritsch, Ralph Carlson,
311// Monotone Piecewise Cubic Interpolation,
312// SIAM Journal on Numerical Analysis,
313// Volume 17, Number 2, April 1980, pages 238-246.
314//
315// Parameters:
316//
317// Input, int NN, the number of data points.
318//
319// Input, double XN[NN], the coordinates of the data points.
320// The entries in XN must be in strictly ascending order.
321//
322// Input, double FN[NN], the function values.
323//
324// Input, double DN[NN], the derivative values.
325//
326// Input, int N, the number of sample points.
327//
328// Input, double X[N], the coordinates of the sample points.
329//
330// Output, double F[N], the function value at the sample points.
331//
332// Output, double D[N], the derivative value at the sample points.
333//
334// Output, double S[N], the second derivative value at the
335// sample points.
336//
337// Output, double T[N], the third derivative value at the
338// sample points.
339//
340//===============================================================================================================================
342//===============================================================================================================================
343void hermite_cubic_spline_value(int const nn, double* const xn, double* const fn, double* const dn, int const n, double* const x, double* f, double* d, double* s, double* t)
344{
345 int left = n / 2;
346
347 for (int i = 0; i < n; i++)
348 {
349 r8vec_bracket3(nn, xn, x[i], &left);
350
351 hermite_cubic_value(xn[left], fn[left], dn[left], xn[left+1], fn[left+1], dn[left+1], 1, x+i, f+i, d+i, s+i, t+i);
352 }
353 return;
354}
355
This file contains global definitions for CoastalME.
void hermite_cubic_value(double const x1, double const f1, double const d1, double const x2, double const f2, double const d2, int const n, double const *x, double *f, double *d, double *s, double *t)
This is part of a C++ library from http://people.sc.fsu.edu/~jburkardt/cpp_src/hermite_cubic/hermite_...
void r8vec_bracket3(int const n, double const *t, double const tval, int *left)
This is part of a C++ library from http://people.sc.fsu.edu/~jburkardt/cpp_src/hermite_cubic/hermite_...
void hermite_cubic_spline_value(int const nn, double *const xn, double *const fn, double *const dn, int const n, double *const x, double *f, double *d, double *s, double *t)
This is part of a C++ library from http://people.sc.fsu.edu/~jburkardt/cpp_src/hermite_cubic/hermite_...
Definitions of some routines from the hermite_cubic library.