Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
GenerateTaylorCW.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Teviet Creighton
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#include <lal/LALStdio.h>
21#include <lal/LALStdlib.h>
22#include <lal/LALConstants.h>
23#include <lal/Units.h>
24#include <lal/AVFactories.h>
25#include <lal/SeqFactories.h>
26#include <lal/PulsarSimulateCoherentGW.h>
27#include <lal/GenerateTaylorCW.h>
28
29/**
30 * \author Creighton, T. D.
31 *
32 * \brief Computes a Taylor-parametrized continuous waveform.
33 *
34 * ### Description ###
35 *
36 * This function computes a quaiperiodic waveform using the parameters in
37 * <tt>*params</tt>, storing the result in <tt>*output</tt>.
38 *
39 * In the <tt>*params</tt> structure, the routine uses all the "input"
40 * fields specified in \c TaylorCWParamStruc, and sets all of the
41 * "output" fields. If <tt>params->f=NULL</tt>, a precisely periodic
42 * (monochromatic) waveform is generated.
43 *
44 * In the <tt>*output</tt> structure, the field <tt>output->h</tt> is
45 * ignored, but all other pointer fields must be set to \c NULL. The
46 * function will create and allocate space for <tt>output->a</tt>,
47 * <tt>output->f</tt>, and <tt>output->phi</tt> as necessary. The
48 * <tt>output->shift</tt> field will remain set to \c NULL.
49 *
50 * ### Algorithm ###
51 *
52 * This function is a fairly straightforward calculation of
53 * \eqref{eq_taylorcw-freq} and \eqref{eq_taylorcw-phi} in
54 * \ref GenerateTaylorCW_h. There are no real tricks involved, except
55 * to note that the phase \f$ \phi \f$ and the time elapsed \f$ t-t_0 \f$ are
56 * computed and stored as \c REAL8s in order to provide waveforms
57 * that are accurate to small fractions of a cycle over many years.
58 *
59 * Since the waveform does not include any effects such as precession,
60 * the amplitudes \f$ A_+ \f$ , \f$ A_\times \f$ and the shift angle \f$ \Phi \f$ , as
61 * defined in \ref PulsarSimulateCoherentGW_h, are constant. This is dealt
62 * with by setting <tt>output->a</tt> to be a
63 * \c REAL4TimeVectorSequence of two identical vectors
64 * \f$ (A_+,A_\times) \f$ spanning the requested time of the waveform, under
65 * the assumption that any routine using this output data (such as the
66 * routines in \ref PulsarSimulateCoherentGW_h) will interpolate these two
67 * endpoints to get the instantaneous values of \f$ A_+ \f$ , \f$ A_\times \f$ . The
68 * field <tt>output->shift</tt> is left as \c NULL, so the constant
69 * value of \f$ \Phi \f$ must be subsumed into the polarization angle \f$ \psi \f$ .
70 *
71 * The fields <tt>output->f</tt> and <tt>output->phi</tt> are created and
72 * filled at the requested sampling interval <tt>params->deltaT</tt>; it is
73 * up to the calling routine to ensure that this sampling interval is
74 * reasonable. As a guideline, we want to be able to determine the
75 * instantaneous wave phase accurately to within a fraction of a cycle.
76 * For functions that compute the phase by linear interpolation of
77 * <tt>output->phi</tt>, this means sampling on timescales \f$ \Delta
78 * t\lesssim\dot{f}^{-1/2}\sim\max\{\sqrt{kf_0f_kT^{k-1}}\} \f$ , where \f$ T \f$ is
79 * the duration of the waveform. More precisely, the largest deviation
80 * from linear phase evolution will typically be on the order of
81 * \f$ \Delta\phi\approx(1/2)\ddot{\phi}(\Delta t/2)^2\approx(\pi/4)\Delta
82 * f\Delta t \f$ , where \f$ \Delta f \f$ is the frequency shift over the timestep.
83 * So if we want our interpolated phase to agree with the true phase to
84 * within, say, \f$ \pi/2 \f$ radians, then we would like to have
85 * \f[
86 * \Delta f \Delta t \lesssim 2 \;.
87 * \f]
88 * This routine provides a check by setting the output parameter field
89 * <tt>params->dfdt</tt> equal to the maximum value of \f$ \Delta f\Delta t \f$
90 * encountered during the integration.
91 *
92 */
93void
97{
98 UINT4 n, i; /* number of and index over samples */
99 UINT4 nSpin = 0, j; /* number of and index over spindown terms */
100 REAL8 t, tPow, dt; /* time, interval, and t raised to a power */
101 REAL8 f0, phi0; /* initial phase and frequency */
102 REAL8 twopif0; /* 2*pi*f0 */
103 REAL8 f, fPrev; /* current and previous values of frequency */
104 REAL4 df = 0.0; /* maximum difference between f and fPrev */
105 REAL8 phi; /* current value of phase */
106 REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */
107 REAL4 *fData; /* pointer to frequency data */
108 REAL8 *phiData; /* pointer to phase data */
109
110 INITSTATUS( stat );
112
113 /* Make sure parameter and output structures exist. */
115 GENERATETAYLORCWH_MSGENUL );
117 GENERATETAYLORCWH_MSGENUL );
118
119 /* Make sure output fields don't exist. */
121 GENERATETAYLORCWH_MSGEOUT );
123 GENERATETAYLORCWH_MSGEOUT );
125 GENERATETAYLORCWH_MSGEOUT );
127 GENERATETAYLORCWH_MSGEOUT );
128
129 /* If Taylor coeficients are specified, make sure they exist. */
130 if ( params->f ) {
132 GENERATETAYLORCWH_MSGENUL );
133 nSpin = params->f->length;
134 fSpin = params->f->data;
135 }
136
137 /* Set up some other constants, to avoid repeated dereferencing. */
138 n = params->length;
139 dt = params->deltaT;
140 f0 = fPrev = params->f0;
141 twopif0 = f0 * LAL_TWOPI;
142 phi0 = params->phi0;
143
144 /* Allocate output structures. */
145 if ( ( output->a = ( REAL4TimeVectorSeries * )
146 LALMalloc( sizeof( REAL4TimeVectorSeries ) ) ) == NULL ) {
147 ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
148 }
149 memset( output->a, 0, sizeof( REAL4TimeVectorSeries ) );
150 if ( ( output->f = ( REAL4TimeSeries * )
151 LALMalloc( sizeof( REAL4TimeSeries ) ) ) == NULL ) {
152 LALFree( output->a );
153 output->a = NULL;
154 ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
155 }
156 memset( output->f, 0, sizeof( REAL4TimeSeries ) );
157 if ( ( output->phi = ( REAL8TimeSeries * )
158 LALMalloc( sizeof( REAL8TimeSeries ) ) ) == NULL ) {
159 LALFree( output->a );
160 output->a = NULL;
161 LALFree( output->f );
162 output->f = NULL;
163 ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
164 }
165 memset( output->phi, 0, sizeof( REAL8TimeSeries ) );
166
167 /* Set output structure metadata fields. */
168 output->position = params->position;
169 output->psi = params->psi;
170 output->a->epoch = output->f->epoch = output->phi->epoch
171 = params->epoch;
172 output->a->deltaT = n * params->deltaT;
173 output->f->deltaT = output->phi->deltaT = params->deltaT;
174 output->a->sampleUnits = lalStrainUnit;
175 output->f->sampleUnits = lalHertzUnit;
176 output->phi->sampleUnits = lalDimensionlessUnit;
177 snprintf( output->a->name, LALNameLength, "CW amplitudes" );
178 snprintf( output->f->name, LALNameLength, "CW frequency" );
179 snprintf( output->phi->name, LALNameLength, "CW phase" );
180
181 /* Allocate phase and frequency arrays. */
182 LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
183 BEGINFAIL( stat ) {
184 LALFree( output->a );
185 output->a = NULL;
186 LALFree( output->f );
187 output->f = NULL;
188 LALFree( output->phi );
189 output->phi = NULL;
190 }
191 ENDFAIL( stat );
192 LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
193 BEGINFAIL( stat ) {
194 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
195 stat );
196 LALFree( output->a );
197 output->a = NULL;
198 LALFree( output->f );
199 output->f = NULL;
200 LALFree( output->phi );
201 output->phi = NULL;
202 }
203 ENDFAIL( stat );
204
205 /* Allocate and fill amplitude array. */
206 {
207 CreateVectorSequenceIn in; /* input to create output->a */
208 in.length = 2;
209 in.vectorLength = 2;
210 LALSCreateVectorSequence( stat->statusPtr, &( output->a->data ), &in );
211 BEGINFAIL( stat ) {
212 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
213 stat );
214 TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
215 stat );
216 LALFree( output->a );
217 output->a = NULL;
218 LALFree( output->f );
219 output->f = NULL;
220 LALFree( output->phi );
221 output->phi = NULL;
222 }
223 ENDFAIL( stat );
224 output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
225 output->a->data->data[1] = output->a->data->data[3] = params->aCross;
226 }
227
228 /* Fill frequency and phase arrays. */
229 fData = output->f->data->data;
230 phiData = output->phi->data->data;
231
232 for ( i = 0; i < n; i++ ) {
233 t = tPow = i * dt;
234 f = 1.0;
235 phi = t;
236 j = 0;
237 while ( j < nSpin ) {
238 f += fSpin[j] * tPow;
239 phi += fSpin[j] * ( tPow *= t ) / ( j + 2.0 );
240 j++;
241 }
242 f *= f0;
243 phi *= twopif0;
244 if ( fabs( f - fPrev ) > df ) {
245 df = fabs( f - fPrev );
246 }
247 *( fData++ ) = fPrev = f;
248 *( phiData++ ) = phi + phi0;
249 }
250
251 /* Set output field and return. */
252 params->dfdt = df * dt;
254 RETURN( stat );
255}
int j
#define LALMalloc(n)
#define LALFree(p)
#define ABORT(statusptr, code, mesg)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define BEGINFAIL(statusptr)
void LALSCreateVectorSequence(LALStatus *status, REAL4VectorSequence **vectorSequence, CreateVectorSequenceIn *vSeqParams)
#define GENERATETAYLORCWH_EOUT
Output field a, f, phi, or shift already exists.
#define GENERATETAYLORCWH_ENUL
Unexpected null pointer in arguments.
#define GENERATETAYLORCWH_EMEM
Out of memory.
void LALGenerateTaylorCW(LALStatus *stat, PulsarCoherentGW *output, TaylorCWParamStruc *params)
Computes a Taylor-parametrized continuous waveform.
#define LAL_TWOPI
double REAL8
uint32_t UINT4
float REAL4
LALNameLength
const LALUnit lalStrainUnit
const LALUnit lalHertzUnit
const LALUnit lalDimensionlessUnit
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALSDestroyVector(LALStatus *, REAL4Vector **)
void LALSCreateVector(LALStatus *, REAL4Vector **, UINT4)
n
This structure stores a representation of a plane gravitational wave propagating from a particular po...
This structure stores the parameters for constructing a gravitational waveform with a Taylor-polynomi...
LIGOTimeGPS epoch
double psi
double df