LALSimulation  5.4.0.1-fe68b98
LALSimIMRSpinAlignedEOBGSLOptimizedInterpolation.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2010 Michele Vallisneri, Will Farr, Evan Ochsner, 2014 A. Klein
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 #ifndef _LALSIMIMRSPINALIGNEDEOBGSLOPTIMIZEDINTERPOLATION_C
21 #define _LALSIMIMRSPINALIGNEDEOBGSLOPTIMIZEDINTERPOLATION_C
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include "stddef.h"
26 
27 #include <lal/LALSimInspiral.h>
28 #include <lal/LALSimIMR.h>
29 
30 #include "LALSimIMRSpinEOB.h"
32 
33 /**
34  * This function is largely based on/copied from
35  * XLALAdaptiveRungeKutta4(), which exists inside the
36  * lal/lib/utilities/LALAdaptiveRungeKutta4.c file
37  * subroutine. It reads in an array of timeseries that
38  * contain data *not* evenly spaced in time
39  * and performs cubic spline interpolations to resample
40  * the data to uniform time sampling. Interpolations use
41  * GSL's built-in routines, which recompute interpolation
42  * coefficients each time the itnerpolator is called.
43  * This can be extremely inefficient; in case of SEOBNRv4,
44  * first data points exist at very large dt, and
45  * interp. coefficients might be needlessly recomputed
46  * 10,000+ times or more. We also made the optimization
47  * that assumes the data are sampled at points monotone
48  * in time.
49  * tinit and deltat specify the desired initial time and
50  * time spacing for the output interpolated data,
51  * num_input_times denotes the number of points yin arrays
52  * are sampled in time.
53  * yout is the output array.
54  */
55 UNUSED static int
57  REAL8 deltat, UINT4 num_input_times,
58  REAL8Array ** yout)
59 {
60  int errnum = 0;
61 
62  /* needed for the final interpolation */
63  gsl_spline *interp = NULL;
64  gsl_interp_accel *accel = NULL;
65  int outputlen = 0;
66  REAL8Array *output = NULL;
67  REAL8 *times, *vector; /* aliases */
68 
69  /* needed for the integration */
70  size_t dim = 4;
71 
72  interp = gsl_spline_alloc (gsl_interp_cspline, num_input_times);
73  accel = gsl_interp_accel_alloc ();
74 
75  outputlen = (int) (yin->data[num_input_times - 1] / deltat) + 1;
76  output = XLALCreateREAL8ArrayL (2, dim + 1, outputlen); /* Only dim + 1 rather than dim + 3 since we're not adding amp & phase */
77 
78  if (!interp || !accel || !output)
79  {
80  errnum = XLAL_ENOMEM; /* ouch again, ran out of memory */
81  if (output)
83  outputlen = 0;
84  goto bail_out;
85  }
86 
87  /* make an array of times */
88  times = output->data;
89  for (int j = 0; j < outputlen; j++)
90  times[j] = tinit + deltat * j;
91 
92  /* interpolate! */
93  for (unsigned int i = 1; i <= dim; i++)
94  { /* only up to dim (4) because we are not interpolating amplitude and phase */
95  //gsl_spline_init(interp, &yin->data[0], &yin->data[num_input_times * i], num_input_times + 1);
96  gsl_spline_init (interp, &yin->data[0], &yin->data[num_input_times * i],
97  num_input_times);
98 
99  vector = output->data + outputlen * i;
100  unsigned int index_old = 0;
101  double x_lo_old = 0, y_lo_old = 0, b_i_old = 0, c_i_old = 0, d_i_old =
102  0;
103  for (int j = 0; j < outputlen; j++)
104  {
105  optimized_gsl_spline_eval_e (interp, times[j], accel, &(vector[j]),
106  &index_old, &x_lo_old, &y_lo_old,
107  &b_i_old, &c_i_old, &d_i_old);
108  }
109  }
110 
111  /* deallocate stuff and return */
112 bail_out:
113 
114  if (interp)
115  XLAL_CALLGSL (gsl_spline_free (interp));
116  if (accel)
117  XLAL_CALLGSL (gsl_interp_accel_free (accel));
118 
119  if (errnum)
120  XLAL_ERROR (errnum);
121 
122  *yout = output;
123  return outputlen;
124 }
125 
126 /**
127  * This function applies the same routines as
128  * SEOBNRv2OptimizedInterpolatorNoAmpPhase() above
129  * to interpolate *only the amplitude & phase*; see
130  * documentation for
131  * SEOBNRv2OptimizedInterpolatorNoAmpPhase().
132  */
133 UNUSED static int
135  REAL8 deltat,
136  UINT4 num_input_times,
137  REAL8Array ** yout)
138 {
139  int errnum = 0;
140 
141  /* needed for the integration */
142  size_t dim = 4;
143 
144  /* needed for the final interpolation */
145  gsl_spline *interp = NULL;
146  gsl_interp_accel *accel = NULL;
147  int outputlen = 0;
148  REAL8Array *output = NULL;
149  REAL8 *times, *vector; /* aliases */
150 
151  /* note: for speed, this replaces the single CALLGSL wrapper applied before each GSL call */
152  interp = gsl_spline_alloc (gsl_interp_cspline, num_input_times);
153  accel = gsl_interp_accel_alloc ();
154 
155 
156  outputlen = (int) (yin->data[num_input_times - 1] / deltat) + 1;
157  output = XLALCreateREAL8ArrayL (2, dim + 3, outputlen); /* Original (dim+1), Optimized (dim+3), since we're adding amp & phase */
158 
159  if (!interp || !accel || !output)
160  {
161  errnum = XLAL_ENOMEM; /* ouch again, ran out of memory */
162  if (output)
164  outputlen = 0;
165  goto bail_out;
166  }
167 
168  /* make an array of times */
169  times = output->data;
170  for (int j = 0; j < outputlen; j++)
171  times[j] = tinit + deltat * j;
172 
173  /* interpolate! */
174  for (unsigned int i = dim + 1; i <= dim + 2; i++)
175  { /* Original (dim), Optimized (dim+2), since we're also interpolating amp & phase */
176  //gsl_spline_init(interp, &yin->data[0], &yin->data[num_input_times * i], num_input_times + 1);
177  gsl_spline_init (interp, &yin->data[0], &yin->data[num_input_times * i],
178  num_input_times);
179  vector = output->data + outputlen * i;
180  unsigned int index_old = 0;
181  double x_lo_old = 0, y_lo_old = 0, b_i_old = 0, c_i_old = 0, d_i_old =
182  0;
183  for (int j = 0; j < outputlen; j++)
184  {
185  optimized_gsl_spline_eval_e (interp, times[j], accel, &(vector[j]),
186  &index_old, &x_lo_old, &y_lo_old,
187  &b_i_old, &c_i_old, &d_i_old);
188  }
189  }
190  /* deallocate stuff and return */
191 bail_out:
192 
193  if (interp)
194  XLAL_CALLGSL (gsl_spline_free (interp));
195  if (accel)
196  XLAL_CALLGSL (gsl_interp_accel_free (accel));
197 
198  if (errnum)
199  XLAL_ERROR (errnum);
200 
201  *yout = output;
202  return outputlen;
203 }
204 
205 #endif /* _LALSIMIMRSPINALIGNEDEOBGSLOPTIMIZEDINTERPOLATION_C */
static UNUSED int SEOBNRv2OptimizedInterpolatorOnlyAmpPhase(REAL8Array *yin, REAL8 tinit, REAL8 deltat, UINT4 num_input_times, REAL8Array **yout)
This function applies the same routines as SEOBNRv2OptimizedInterpolatorNoAmpPhase() above to interpo...
static UNUSED int SEOBNRv2OptimizedInterpolatorNoAmpPhase(REAL8Array *yin, REAL8 tinit, REAL8 deltat, UINT4 num_input_times, REAL8Array **yout)
This function is largely based on/copied from XLALAdaptiveRungeKutta4(), which exists inside the lal/...
static int optimized_gsl_spline_eval_e(const gsl_spline *spline, double interptime, gsl_interp_accel *accel, double *output, unsigned int *index_old, double *x_lo_old, double *y_lo_old, double *b_i_old, double *c_i_old, double *d_i_old)
Perform cubic spline interpolation to achieve evenly-sampled data from that input data.
#define XLAL_CALLGSL(statement)
double i
Definition: bh_ringdown.c:118
REAL8Array * XLALCreateREAL8ArrayL(UINT4,...)
void XLALDestroyREAL8Array(REAL8Array *)
double REAL8
uint32_t UINT4
#define XLAL_ERROR(...)
XLAL_ENOMEM
REAL8 * data
char output[FILENAME_MAX]
Definition: unicorn.c:26