Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Interpolate.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Drew Keppel
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/* ---------- see Interpolate.h for doxygen documentation ---------- */
21
22#include <math.h>
23#include <string.h>
24#include <lal/LALStdlib.h>
25#include <lal/Interpolate.h>
26
27
28void
32 REAL4 target,
33 SInterpolatePar *params
34 )
35{
36 REAL4 *dn; /* difference in a step down */
37 REAL4 *up; /* difference in a step up */
38 REAL4 diff;
39 UINT4 near;
40 UINT4 order;
41 UINT4 n;
42 UINT4 i;
43
45
46 ASSERT (output, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
47 ASSERT (params, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
48 ASSERT (params->x, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
49 ASSERT (params->y, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
50
51 n = params->n;
52 ASSERT (n > 1, status, INTERPOLATEH_ESIZE, INTERPOLATEH_MSGESIZE);
53
54 dn = (REAL4 *) LALMalloc (n*sizeof(REAL4));
55 ASSERT (dn, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
56
57 up = (REAL4 *) LALMalloc (n*sizeof(REAL4));
58 ASSERT (up, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
59
60
61 /*
62 *
63 * Initialize dn[] and up[] and find element of domain nearest the target.
64 *
65 */
66
67
68 memcpy (dn, params->y, n*sizeof(REAL4));
69 memcpy (up, params->y, n*sizeof(REAL4));
70 diff = target - params->x[near = 0];
71 for (i = 1; diff > 0 && i < n; ++i)
72 {
73 REAL4 tmp = target - params->x[i];
74 diff = (fabs(tmp) < fabs(diff) ? near = i, tmp : diff);
75 }
76 output->y = params->y[near];
77
78
79 /*
80 *
81 * Recompute dn[] and up[] for each polynomial order.
82 *
83 */
84
85
86 for (order = 1; order < n; ++order)
87 {
88 UINT4 imax = n - order;
89 for (i = 0; i < imax; ++i)
90 {
91 REAL4 xdn = params->x[i];
92 REAL4 xup = params->x[i + order];
93 REAL4 den = xdn - xup;
94 REAL4 fac;
95 ASSERT (den != 0, status, INTERPOLATEH_EZERO, INTERPOLATEH_MSGEZERO);
96 fac = (dn[i + 1] - up[i])/den;
97 dn[i] = fac*(xdn - target);
98 up[i] = fac*(xup - target);
99 }
100
101 /* go down unless impossible */
102 output->y += (near < imax ? dn[near] : up[--near]);
103 }
104
105 output->dy = fabs(dn[0]) < fabs(up[0]) ? fabs(dn[0]) : fabs(up[0]);
106
107 LALFree (dn);
108 LALFree (up);
109 RETURN (status);
110}
111
112
113
114void
118 REAL8 target,
119 DInterpolatePar *params
120 )
121{
123
124 XLAL_PRINT_DEPRECATION_WARNING("XLALDPolynomialInterpolation");
125
126 ASSERT (output, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
127 ASSERT (params, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
128 ASSERT (params->x, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
129 ASSERT (params->y, status, INTERPOLATEH_ENULL, INTERPOLATEH_MSGENULL);
130
131 output->dy = XLALREAL8PolynomialInterpolation(&(output->y), target, params->y, params->x, params->n);
132 if (xlalErrno)
134
135 RETURN (status);
136}
137
138
139REAL8
141 REAL8 *yout,
142 REAL8 xtarget,
143 REAL8 *y,
144 REAL8 *x,
145 UINT4 n
146 )
147{
148 REAL8 dy;
149 REAL8 *dn; /* difference in a step down */
150 REAL8 *up; /* difference in a step up */
151 REAL8 diff;
152 UINT4 near = 0;
153 UINT4 order;
154 UINT4 i;
155
156 if ( yout == NULL || y == NULL || x == NULL )
158
159 if ( n <= 1 )
161
162 dn = (REAL8 *) LALMalloc (n*sizeof(*dn));
163 if ( !dn )
165
166 up = (REAL8 *) LALMalloc (n*sizeof(*up));
167 if ( !up )
169
170
171 /*
172 *
173 * Initialize dn[] and up[] and find element of domain nearest xtarget.
174 *
175 */
176
177
178 memcpy (dn, y, n*sizeof(*dn));
179 memcpy (up, y, n*sizeof(*up));
180 diff = xtarget - x[near];
181 for (i = 1; diff > 0 && i < n; ++i)
182 {
183 REAL8 tmp = xtarget - x[i];
184 diff = (fabs(tmp) < fabs(diff) ? near = i, tmp : diff);
185 }
186 *yout = y[near];
187
188
189 /*
190 *
191 * Recompute dn[] and up[] for each polynomial order.
192 *
193 */
194
195
196 for (order = 1; order < n; ++order)
197 {
198 UINT4 imax = n - order;
199 for (i = 0; i < imax; ++i)
200 {
201 REAL8 xdn = x[i];
202 REAL8 xup = x[i + order];
203 REAL8 den = xdn - xup;
204 REAL8 fac;
205 if ( !den )
206 {
207 LALFree (dn);
208 LALFree (up);
210 }
211 fac = (dn[i + 1] - up[i])/den;
212 dn[i] = fac*(xdn - xtarget);
213 up[i] = fac*(xup - xtarget);
214 }
215
216 /* go down unless impossible */
217 *yout += (near < imax ? dn[near] : up[--near]);
218 }
219
220 dy = fabs(dn[0]) < fabs(up[0]) ? fabs(dn[0]) : fabs(up[0]);
221
222 LALFree (dn);
223 LALFree (up);
224 return dy;
225}
226
227int
229 REAL8Sequence *x_in, // Assumed to be in ascending order
230 REAL8Sequence *y_in,
231 REAL8Sequence *x_out,
232 REAL8Sequence *y_out, // Modified in place
233 UINT4 n_data_points,
234 const gsl_interp_type *itrp_type // Can be NULL -- default it to cubic spline
235 )
236{
237 size_t i=0;
238 REAL8 x_min, x_max;
239
240 gsl_interp_accel *i_acc = gsl_interp_accel_alloc();
241
242 /*
243 * What type of interpolation do want? Default is cubic spline
244 * Other types can be found at
245 * http://www.gnu.org/software/gsl/manual/html_node/Interpolation-Types.html
246 */
247 gsl_spline *spline;
248 if (!itrp_type) {
249 spline = gsl_spline_alloc(gsl_interp_cspline, n_data_points);
250 } else {
251 spline = gsl_spline_alloc(itrp_type, n_data_points);
252 }
253 gsl_spline_init(spline, x_in->data, y_in->data, n_data_points);
254
255 /*
256 * Do the interpolation.
257 */
258 x_min = x_in->data[0];
259 x_max = x_in->data[x_in->length-1];
260 for(; i<x_out->length; i++) {
261 /*
262 * The gsl interpolator is known to do funny and sometimes
263 * inconsistent things outside the boundaries of the input,
264 * so we check for and bail if we don't meet that criteria
265 */
266 if (x_out->data[i] < x_min || x_out->data[i] > x_max ) {
267 XLALPrintError("XLAL Error - %s: %g is outside the bounds of the interpolant.\n", __func__, x_out->data[i]);
269 }
270 y_out->data[i] = gsl_spline_eval(spline, x_out->data[i], i_acc);
271 }
272
273 /*
274 * Clean up.
275 */
276 gsl_spline_free(spline);
277 gsl_interp_accel_free(i_acc);
278 return 0;
279}
280
281int
283 REAL8TimeSeries *ts_in,
284 REAL8Sequence *y_in,
285 REAL8Sequence *t_in,
286 REAL8Sequence *t_out, // If NULL, interpolate from dt and epoch of ts_in
287 UINT4 n_data_points,
288 const gsl_interp_type *itrp_type
289 )
290{
291 /*
292 * If the user doesn't provide a sampling series to interpolate to,
293 * we'll infer it from the epoch and sample rate.
294 */
295 int length = ts_in->data->length;
296 int destroy_t_out = 0;
297 if (!t_out) {
298 if (ts_in->deltaT < 0.0) {
299 XLALPrintError("XLAL Error - %s: Not enough information in the time series to infer sampling values. Supply proper epoch and deltaT.", __func__);
301 }
302 REAL8 start = XLALGPSGetREAL8(&ts_in->epoch);
303 destroy_t_out = 1;
304 t_out = XLALCreateREAL8Sequence(length);
305 length--;
306 for (; length>=0; length--){
307 t_out->data[length] = length*ts_in->deltaT + start;
308 }
309 }
310 XLALREAL8Interpolation(t_in, y_in, t_out, ts_in->data, n_data_points, itrp_type);
311 /*
312 * We created it, so we'll clean it up too.
313 */
314 if (destroy_t_out) {
316 }
317 return 0;
318}
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
#define ASSERT(assertion, statusptr, code, mesg)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define ABORTXLAL(sp)
int XLALPrintError(const char *fmt,...)
Definition: XLALError.c:68
#define INTERPOLATEH_ENULL
Null pointer.
Definition: Interpolate.h:91
#define INTERPOLATEH_ESIZE
Invalid size.
Definition: Interpolate.h:92
void LALDPolynomialInterpolation(LALStatus *status, DInterpolateOut *output, REAL8 target, DInterpolatePar *params)
Definition: Interpolate.c:115
int XLALREAL8TimeSeriesInterpolation(REAL8TimeSeries *ts_in, REAL8Sequence *y_in, REAL8Sequence *t_in, REAL8Sequence *t_out, UINT4 n_data_points, const gsl_interp_type *itrp_type)
Definition: Interpolate.c:282
void LALSPolynomialInterpolation(LALStatus *status, SInterpolateOut *output, REAL4 target, SInterpolatePar *params)
Definition: Interpolate.c:29
#define INTERPOLATEH_EZERO
Zero divide.
Definition: Interpolate.h:93
REAL8 XLALREAL8PolynomialInterpolation(REAL8 *yout, REAL8 xtarget, REAL8 *y, REAL8 *x, UINT4 n)
Definition: Interpolate.c:140
int XLALREAL8Interpolation(REAL8Sequence *x_in, REAL8Sequence *y_in, REAL8Sequence *x_out, REAL8Sequence *y_out, UINT4 n_data_points, const gsl_interp_type *itrp_type)
Definition: Interpolate.c:228
double REAL8
Double precision real floating-point number (8 bytes).
uint32_t UINT4
Four-byte unsigned integer.
float REAL4
Single precision real floating-point number (4 bytes).
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
#define XLAL_ERROR_REAL8(...)
Macro to invoke a failure from a XLAL routine returning a REAL8.
Definition: XLALError.h:752
#define XLAL_ERROR_VAL(val,...)
Macro to invoke the XLALError() function and return with code val (it should not really be used itsel...
Definition: XLALError.h:687
#define xlalErrno
Modifiable lvalue containing the XLAL error number.
Definition: XLALError.h:571
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
Prints a deprecation warning at the "warning" verbosity level.
Definition: XLALError.h:228
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_ESIZE
Wrong size.
Definition: XLALError.h:420
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409
@ XLAL_EFPDIV0
IEEE Division by zero floating point error.
Definition: XLALError.h:449
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
Returns the GPS time as a REAL8.
Definition: XLALTime.c:91
These structures contain the output of the interpolation.
Definition: Interpolate.h:114
These structures contain the interpolation parameters; These are the arrays of n domain values and t...
Definition: Interpolate.h:141
REAL8 * y
The array of values to interpolate.
Definition: Interpolate.h:144
REAL8 * x
The array of domain values.
Definition: Interpolate.h:143
UINT4 n
The number of points in the arrays to use in the interpolation.
Definition: Interpolate.h:142
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Time series of REAL8 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:580
REAL8Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:586
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:583
LIGOTimeGPS epoch
The start time of the time series.
Definition: LALDatatypes.h:582
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
These structures contain the output of the interpolation.
Definition: Interpolate.h:105
These structures contain the interpolation parameters; These are the arrays of n domain values and t...
Definition: Interpolate.h:127
REAL4 * x
The array of domain values.
Definition: Interpolate.h:129
UINT4 n
The number of points in the arrays to use in the interpolation.
Definition: Interpolate.h:128
REAL4 * y
The array of values to interpolate.
Definition: Interpolate.h:130
void output(int gps_sec, int output_type)
Definition: tconvert.c:440