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
15 This file is part of CoastalME, the Coastal Modelling Environment.
16
17 CoastalME 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
19 This 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
21 You 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
117 else if ( * left == 1 )
118 {
119 * left = 0;
120 return;
121 }
122
123 else if ( t[ * left - 1] <= tval )
124 {
125 * left = * left - 1;
126 return;
127 }
128
129 else if ( tval <= t[1] )
130 {
131 * left = 0;
132 return;
133 }
134
135 //
136 // ...Binary search for TVAL in (T[I],T[I+1]), for I = 1 to *LEFT-2.
137 //
138 low = 1;
139 high = * left - 2;
140
141 for ( ; ; )
142 {
143 if ( low == high )
144 {
145 * left = low;
146 return;
147 }
148
149 mid = ( low + high + 1 ) / 2;
150
151 if ( t[mid] <= tval )
152 {
153 low = mid;
154 }
155
156 else
157 {
158 high = mid - 1;
159 }
160 }
161 }
162
163 //
164 // CASE 2: T[*LEFT+1] < TVAL:
165 // Search for TVAL in (T[I],T[I+1]) for intervals I = *LEFT+1 to N-2.
166 //
167 else if ( t[ * left + 1] < tval )
168 {
169 if ( * left == n - 2 )
170 {
171 return;
172 }
173
174 else if ( * left == n - 3 )
175 {
176 * left = * left + 1;
177 return;
178 }
179
180 else if ( tval <= t[ * left + 2] )
181 {
182 * left = * left + 1;
183 return;
184 }
185
186 else if ( t[n - 2] <= tval )
187 {
188 * left = n - 2;
189 return;
190 }
191
192 // ...Binary search for TVAL in (T[I],T[I+1]) for intervals I = *LEFT+2 to N-3.
193 low = * left + 2;
194 high = n - 3;
195
196 for ( ; ; )
197 {
198 if ( low == high )
199 {
200 * left = low;
201 return;
202 }
203
204 mid = ( low + high + 1 ) / 2;
205
206 if ( t[mid] <= tval )
207 {
208 low = mid;
209 }
210
211 else
212 {
213 high = mid - 1;
214 }
215 }
216 }
217
218 // CASE 3: T[*LEFT] <= TVAL <= T[*LEFT+1]: T is just where the user said it might be.
219 else
220 {
221 }
222
223 return;
224}
225
226//===============================================================================================================================
227//
228// Purpose:
229//
230// HERMITE_CUBIC_VALUE evaluates a Hermite cubic polynomial.
231//
232// Discussion:
233//
234// The input arguments can be vectors.
235//
236// Licensing:
237//
238// This code is distributed under the GNU LGPL license.
239//
240// Modified:
241//
242// 13 February 2011
243//
244// Author:
245//
246// John Burkardt
247//
248// Reference:
249//
250// Fred Fritsch, Ralph Carlson,
251// Monotone Piecewise Cubic Interpolation,
252// SIAM Journal on Numerical Analysis,
253// Volume 17, Number 2, April 1980, pages 238-246.
254//
255// Parameters:
256//
257// Input, double X1, F1, D1, the left endpoint, function value
258// and derivative.
259//
260// Input, double X2, F2, D2, the right endpoint, function value
261// and derivative.
262//
263// Input, int N, the number of evaluation points.
264//
265// Input, double X[N], the points at which the Hermite cubic
266// is to be evaluated.
267//
268// Output, double F[N], D[N], S[N], T[N], the value and first
269// three derivatives of the Hermite cubic at X.
270//
271//===============================================================================================================================
273void 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)
274{
275 double c2;
276 double c3;
277 double df;
278 double h;
279 int i;
280
281 h = x2 - x1;
282 df = (f2 - f1) / h;
283
284 c2 = - ( 2.0 * d1 - 3.0 * df + d2 ) / h;
285 c3 = ( d1 - 2.0 * df + d2 ) / h / h;
286
287 for (i = 0; i < n; i++)
288 {
289 f[i] = f1 + ( x[i] - x1 ) * ( d1
290 + ( x[i] - x1 ) * ( c2
291 + ( x[i] - x1 ) * c3 ) );
292 d[i] = d1 + ( x[i] - x1 ) * ( 2.0 * c2
293 + ( x[i] - x1 ) * 3.0 * c3 );
294 s[i] = 2.0 * c2 + ( x[i] - x1 ) * 6.0 * c3;
295 t[i] = 6.0 * c3;
296 }
297
298 return;
299}
300
301//===============================================================================================================================
302//
303// Purpose:
304//
305// HERMITE_CUBIC_SPLINE_VALUE evaluates a Hermite cubic spline.
306//
307// Licensing:
308//
309// This code is distributed under the GNU LGPL license.
310//
311// Modified:
312//
313// 13 February 2011
314//
315// Author:
316//
317// John Burkardt
318//
319// Reference:
320//
321// Fred Fritsch, Ralph Carlson,
322// Monotone Piecewise Cubic Interpolation,
323// SIAM Journal on Numerical Analysis,
324// Volume 17, Number 2, April 1980, pages 238-246.
325//
326// Parameters:
327//
328// Input, int NN, the number of data points.
329//
330// Input, double XN[NN], the coordinates of the data points.
331// The entries in XN must be in strictly ascending order.
332//
333// Input, double FN[NN], the function values.
334//
335// Input, double DN[NN], the derivative values.
336//
337// Input, int N, the number of sample points.
338//
339// Input, double X[N], the coordinates of the sample points.
340//
341// Output, double F[N], the function value at the sample points.
342//
343// Output, double D[N], the derivative value at the sample points.
344//
345// Output, double S[N], the second derivative value at the
346// sample points.
347//
348// Output, double T[N], the third derivative value at the
349// sample points.
350//
351//===============================================================================================================================
353//===============================================================================================================================
354void 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)
355{
356 int left = n / 2;
357
358 for (int i = 0; i < n; i++)
359 {
360 r8vec_bracket3(nn, xn, x[i], &left);
361
362 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);
363 }
364
365 return;
366}
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.