LAL  7.5.0.1-b72065a
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 
28 void
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 
114 void
116  LALStatus *status,
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)
133  ABORTXLAL (status);
134 
135  RETURN (status);
136 }
137 
138 
139 REAL8
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 
227 int
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 
281 int
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