Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-8a6b96f
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALInspiralMoments.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 David Churches, Duncan Brown, Jolien Creighton, Benjamin Owen, B.S. Sathyaprakash, Thomas Cokelaer
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/**
21 * \defgroup LALInspiralMoments_c Module LALInspiralMoments.c
22 * \ingroup LALInspiralBank_h
23 * \brief Functions to calculate the moment of the noise power spectral density.
24 * \author Brown, D. A., Cokelaer, T. and Sathyaprakash, B. S.
25 *
26 * The moments of the noise curve are defined as
27 * \f{equation}{
28 * I(q) \equiv S_{h}(f_{0}) \int^{f_{c}/f_{0}}_{f_{s}/f_{0}}
29 * \frac{x^{-q}}{S_{h}(x)} \, dx \,.
30 * \f}
31 * Because in practice we will always divide one of these moments by another, we
32 * do not need to include the \f$S_{h}(f_{0})\f$ term, which always cancels.
33 * This function calculates the integral
34 * \f{equation}{
35 * I = \int^{f_{c}/f_{0}}_{f_{s}/f_{0}} \frac{x^{-q}}{S_{h}(x)} \, dx \,.
36 * \f}
37 * It then divides this quantity by a normalisation constant which has been
38 * passed to the function. In the case of calculating the components of the
39 * metric for the signal manifold for the purpose of generating a template bank,
40 * this constant is given by \f$I(7)\f$, because of the definition of the quantity
41 * \f{equation}{
42 * J(q) \equiv \frac{I(q)}{I(7/3)} \,.
43 * \f}
44 *
45 * ### Algorithm ###
46 *
47 * Given the exponent <tt>pars.ndx</tt> and limits of integration
48 * <tt>pars.xmin</tt> and <tt>pars.xmax</tt> this function returns the moment of
49 * the power spectral density specified by the frequency series
50 * <tt>pars.shf</tt> according to
51 * \f{equation}{
52 * \mathtt{moment} = \int_{\mathtt{xmin}}^{\mathtt{xmax}}
53 * \frac{x^{-\mathtt{ndx}}}{S_h(x)}\, dx \, .
54 * \f}
55 */
56
57/** @{ */
58
59#include <lal/LALInspiralBank.h>
60#include <lal/Integrate.h>
61
62/* Deprecation Warning */
63
64/** \see See \ref LALInspiralMoments_c for documentation */
65void
68 InspiralMomentsEtc *moments,
71 )
72
73{
76 XLAL_PRINT_DEPRECATION_WARNING("XLALGetInspiralMoments");
77
78 if (XLALGetInspiralMoments(moments, params->fLower, params->fCutoff, psd)!= XLAL_SUCCESS){
80 }
82 RETURN( status );
83}
84
85int
87 InspiralMomentsEtc *moments,
88 REAL8 fLower,
89 REAL8 fCutoff,
91 )
92{
93 size_t k;
94 REAL8 xmin;
95 REAL8 xmax;
96 REAL8 ndx;
97 REAL8 norm;
98
99 /* Check inputs */
100 if (!moments){
101 XLALPrintError("Moments is NULL\n");
103 }
104 if (!psd){
105 XLALPrintError("PSD is NULL\n");
107 }
108
109 if (fLower <= 0 || fCutoff <= fLower){
110 XLALPrintError("fLower must be between 0 and fCutoff\n");
112 };
113
114 /* Constants needed in computing the moments */
115 moments->a01 = 3.L/5.L;
116 moments->a21 = 11.L * LAL_PI/12.L;
117 moments->a22 = 743.L/2016.L * cbrt(25.L/(2.L*LAL_PI*LAL_PI));
118 moments->a31 = -3.L/2.L;
119 moments->a41 = 617.L * LAL_PI * LAL_PI / 384.L;
120 moments->a42 = 5429.L/5376.L * cbrt(25.L*LAL_PI/2.L);
121 moments->a43 = 1.5293365L/1.0838016L * cbrt(5.L/(4.L*LAL_PI*LAL_PI*LAL_PI*LAL_PI));
122
123 /* Divide all frequencies by fLower, a scaling that is used in solving */
124 /* the moments integral */
125 psd->f0 /= fLower;
126 psd->deltaF /= fLower;
127 xmin = fLower / fLower;
128 xmax = fCutoff / fLower;
129
130 /* First compute the norm and print if requested */
131 norm = 1.L;
132 ndx = 7.L/3.L;
133 moments->j[7]=XLALInspiralMoments(xmin, xmax, ndx, norm, psd);
134 if (XLAL_IS_REAL8_FAIL_NAN(moments->j[7])){
136 }
137 norm = moments->j[7];
138
139 /* Then compute the normalised moments of the noise PSD from 1/3 to 17/3. */
140 for ( k = 1; k <= 17; ++k )
141 {
142 ndx = (REAL8) k / 3.L;
143 moments->j[k]=XLALInspiralMoments(xmin, xmax, ndx, norm, psd);
144 }
145
146 /* Moments are done: Rescale deltaF and f0 back to their original values */
147 psd->deltaF *= fLower;
148 psd->f0 *= fLower;
149
150 return XLAL_SUCCESS;
151}
152
153/** \see See \ref LALInspiralMoments_c for documentation */
154void
157 InspiralMomentsEtcBCV *moments,
160 )
161{
162 UINT4 k;
164
167
168 /* doesn't seem to be needed. thomas, janvier 2004. I prefer to remove it for the moment.
169 * The factor is not important in the case of SPA approximation but is important in BCV
170 * case. Indeed on one hand we use quantity which are a ratio between two moments and
171 * consequently a factor 1 or 2 is not important. Howver in the case of BCV, we might
172 * use a moment alone. Thus a factor in the computation has an effect. */
173
174 /* for (i=0; i< psd->data->length ; i++)
175 {
176 psd->data->data[i] = psd->data->data[i] * 1e45;
177 }
178 */
179 in.shf = psd;
180 in.xmin = params->fLower;
181 in.xmax = params->fCutoff;
182
183 /* First compute the norm */
184 in.norm = 1.L;
185 for ( k = 0; k <= 22; ++k )
186 {
187 if (k <= 17)
188 {
189 /* positive value*/
190 in.ndx = (REAL8)k / 3.L;
191 }
192 else
193 {
194 /* negative -1,-2 ...-6 */
195 in.ndx = (17.- (REAL8)k) /3.L;
196 }
197
198 LALInspiralMoments( status->statusPtr, &moments->i[k], in );
200 }
201
202 in.norm = moments->i[7] -2.*moments->alpha * moments->i[5] +
203 moments->alpha * moments->alpha*moments->i[3];
204
205
206 /* 17 */
207 moments->M1[0][0] = (moments->i[17] -2.*moments->alpha * moments->i[15] +
208 moments->alpha * moments->alpha*moments->i[13]) / in.norm;
209 /* 14 */
210 moments->M1[0][1] = (moments->i[14] -2.*moments->alpha * moments->i[12] +
211 moments->alpha * moments->alpha*moments->i[10]) / in.norm;
212 /* 11 */
213 moments->M1[1][1] = (moments->i[11] -2.*moments->alpha * moments->i[9] +
214 moments->alpha * moments->alpha*moments->i[7]) / in.norm;
215
216 moments->M1[1][0]=moments->M1[0][1] ;
217
218 /* 12 */
219 moments->M2[0][0] = (moments->i[12] -2.*moments->alpha * moments->i[10] +
220 moments->alpha * moments->alpha*moments->i[8]) / in.norm;
221 /* 9 */
222
223 moments->M2[0][1] = (moments->i[9] -2.*moments->alpha * moments->i[7] +
224 moments->alpha * moments->alpha*moments->i[5]) / in.norm;
225 /* 9 */
226
227 moments->M2[1][0] = (moments->i[9] -2.*moments->alpha * moments->i[7] +
228 moments->alpha * moments->alpha*moments->i[5]) / in.norm;
229 /* 6 */
230 moments->M2[1][1] = (moments->i[6] -2.*moments->alpha * moments->i[4] +
231 moments->alpha * moments->alpha*moments->i[2]) / in.norm;
232
233 /* 7 */
234 moments->M3[0][0] = (moments->i[7] -2.*moments->alpha * moments->i[5] +
235 moments->alpha * moments->alpha*moments->i[3]) / in.norm;
236 /* 4 */
237 moments->M3[0][1] = (moments->i[4] -2.*moments->alpha * moments->i[2] +
238 moments->alpha * moments->alpha*moments->i[0]) / in.norm;
239 /* 1 */
240 moments->M3[1][1] = (moments->i[1] -2.*moments->alpha * moments->i[18] +
241 moments->alpha * moments->alpha * moments->i[20]) / in.norm;
242
243 moments->M3[1][0]=moments->M3[0][1] ;
244
245 if ( lalDebugLevel & LALINFO )
246 {
247 LALPrintError( "#M1=\n");
248 LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
249 moments->M1[0][0],
250 moments->M1[0][1],
251 moments->M1[1][0],
252 moments->M1[1][1] );
253
254 LALPrintError( "#M2=\n" );
255 LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
256 moments->M2[0][0],
257 moments->M2[0][1],
258
259 moments->M2[1][0],
260 moments->M2[1][1] );
261
262 LALPrintError( "#M3=\n" );
263 LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
264 moments->M3[0][0],
265 moments->M3[0][1],
266 moments->M3[1][0],
267 moments->M3[1][1] );
268 }
269
271 RETURN( status );
272}
273
274/** \see See \ref LALInspiralMoments_c for documentation */
275void
277 LALStatus *status, /**< LAL status pointer */
278 REAL8 *moment, /**< [out] the value of the moment */
279 InspiralMomentsIn pars /**< [in] input parameters */
280 )
281
282{
284 XLAL_PRINT_DEPRECATION_WARNING("XLALInspiralMoments");
285
286 *moment = XLALInspiralMoments(pars.xmin, pars.xmax, pars.ndx, pars.norm, pars.shf);
287 if (XLAL_IS_REAL8_FAIL_NAN(*moment)){
288 ABORTXLAL( status );
289 };
290 RETURN (status);
291}
292
293REAL8
295 REAL8 xmin,
296 REAL8 xmax,
297 REAL8 ndx,
298 REAL8 norm,
300 )
301
302{
303 REAL8 moment = 0;
304 REAL8 f0, deltaF;
305 size_t k, kMin, kMax;
306
307 /* Check inputs */
308 if (!shf || !(shf->data) || !(shf->data->data)) {
309 XLALPrintError("PSD or its data are NULL\n");
311 }
312
313 if (xmin <= 0 || xmax <= 0 || xmax <= xmin || norm <= 0) {
314 XLALPrintError("xmin, xmax, and norm must be positive and xmax must be greater than xmin\n");
316 }
317
318 /* set up and check domain of integration */
319 /* NB: Although these are called f0 and deltaF, they are really supposed to
320 be x0 and deltaX (x = f / f0). That is, you either need to have hacked
321 the PSD's f0 and deltaF values before calling this function or be
322 prepared to rescale the outputs. */
323 f0 = shf->f0;
324 deltaF = shf->deltaF;
325 kMax = floor((xmax - f0) / deltaF);
326 if ( (xmin < f0) || (kMax > shf->data->length) ) {
327 XLALPrintError("PSD does not cover domain of integration\n");
329 }
330 kMin = floor((xmin - f0) / deltaF);
331
332 /* do the first point of the integral */
333 if( shf->data->data[kMin] ) {
334 const REAL8 f = f0 + kMin * deltaF;
335 moment += pow( f, -(ndx) ) / ( 2.0 * shf->data->data[kMin] );
336 }
337 /* do the bulk of the integral */
338 for ( k = kMin + 1; k < kMax; ++k ) {
339 const REAL8 psd_val = shf->data->data[k];
340 if ( psd_val ) {
341 const REAL8 f = f0 + k * deltaF;
342 moment += pow( f, -(ndx) ) / psd_val;
343 }
344 }
345 /* Do the last point of the integral, but allow the integration domain
346 to be open on the right if necessary. */
347 if ( kMax < shf->data->length && shf->data->data[kMax] ) {
348 const REAL8 f = f0 + kMax * deltaF;
349 moment += pow( f, -(ndx) ) / ( 2.0 * shf->data->data[kMax] );
350 }
351 moment *= deltaF;
352
353 /* now divide the moment by the user-specified norm */
354 moment /= norm;
355
356 return moment;
357}
358/** @} */
#define CHECKSTATUSPTR(statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define ABORTXLAL(sp)
sigmaKerr data[0]
#define LAL_PI
double REAL8
uint32_t UINT4
#define lalDebugLevel
LALINFO
int LALPrintError(const char *fmt,...)
REAL8 XLALInspiralMoments(REAL8 xmin, REAL8 xmax, REAL8 ndx, REAL8 norm, REAL8FrequencySeries *shf)
void LALInspiralMoments(LALStatus *status, REAL8 *moment, InspiralMomentsIn pars)
int XLALGetInspiralMoments(InspiralMomentsEtc *moments, REAL8 fLower, REAL8 fCutoff, REAL8FrequencySeries *psd)
void LALGetInspiralMoments(LALStatus *status, InspiralMomentsEtc *moments, REAL8FrequencySeries *psd, InspiralTemplate *params)
void LALGetInspiralMomentsBCV(LALStatus *status, InspiralMomentsEtcBCV *moments, REAL8FrequencySeries *psd, InspiralTemplate *params)
#define XLAL_ERROR_REAL8(...)
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
#define XLAL_IS_REAL8_FAIL_NAN(val)
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EDOM
Parameter structure that holds the moments of the PSD and other useful constants required in the comp...
REAL8 j[18]
The required moments are all computed once and stored in this array; The required moments are from J(...
Inputs to the function that computes the moments of the PSD.
REAL8FrequencySeries * shf
the frequency series containing the noise psd
REAL8 norm
norm to be used in computing the moment, the returned value is the above integral divided by the norm
REAL8 ndx
index (without the negative sign) in the moment integral as above
REAL8 xmax
upper limit of the integral
REAL8 xmin
lower limit of the integral
The inspiral waveform parameter structure containing information about the waveform to be generated.
Definition: LALInspiral.h:205
REAL8Sequence * data
REAL8 * data