GenerateTaylorCW.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Teviet Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /************************** <lalVerbatim file="GenerateTaylorCWCV">
00021 Author: Creighton, T. D.
00022 $Id: GenerateTaylorCW.c,v 1.6 2007/06/08 14:41:47 bema Exp $
00023 **************************************************** </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 
00027 \providecommand{\lessim}{\stackrel{<}{\scriptstyle\sim}}
00028 
00029 \subsection{Module \texttt{GenerateTaylorCW.c}}
00030 \label{ss:GenerateTaylorCW.c}
00031 
00032 Computes a Taylor-parametrized continuous waveform.
00033 
00034 \subsubsection*{Prototypes}
00035 \vspace{0.1in}
00036 \input{GenerateTaylorCWCP}
00037 \idx{LALGenerateTaylorCW()}
00038 
00039 \subsubsection*{Description}
00040 
00041 This function computes a quaiperiodic waveform using the parameters in
00042 \verb@*params@, storing the result in \verb@*output@.
00043 
00044 In the \verb@*params@ structure, the routine uses all the ``input''
00045 fields specified in \verb@GenerateTaylorCW.h@, and sets all of the
00046 ``output'' fields.  If \verb@params->f=NULL@, a precisely periodic
00047 (monochromatic) waveform is generated.
00048 
00049 In the \verb@*output@ structure, the field \verb@output->h@ is
00050 ignored, but all other pointer fields must be set to \verb@NULL@.  The
00051 function will create and allocate space for \verb@output->a@,
00052 \verb@output->f@, and \verb@output->phi@ as necessary.  The
00053 \verb@output->shift@ field will remain set to \verb@NULL@.
00054 
00055 \subsubsection*{Algorithm}
00056 
00057 This function is a fairly straightforward calculation of
00058 Eqs.~\ref{eq:taylorcw-freq} and~\ref{eq:taylorcw-phi} in
00059 \verb@GenerateTaylorCW.h@.  There are no real tricks involved, except
00060 to note that the phase $\phi$ and the time elapsed $t-t_0$ are
00061 computed and stored as \verb@REAL8@s in order to provide waveforms
00062 that are accurate to small fractions of a cycle over many years.
00063 
00064 Since the waveform does not include any effects such as precession,
00065 the amplitudes $A_+$, $A_\times$ and the shift angle $\Phi$, as
00066 defined in \verb@SimulateCoherentGW.h@, are constant.  This is dealt
00067 with by setting \verb@output->a@ to be a
00068 \verb@REAL4TimeVectorSequence@ of two identical vectors
00069 $(A_+,A_\times)$ spanning the requested time of the waveform, under
00070 the assumption that any routine using this output data (such as the
00071 routines in \verb@SimulateCoherentGW.h@) will interpolate these two
00072 endpoints to get the instantaneous values of $A_+$, $A_\times$.  The
00073 field \verb@output->shift@ is left as \verb@NULL@, so the constant
00074 value of $\Phi$ must be subsumed into the polarization angle $\psi$.
00075 
00076 The fields \verb@output->f@ and \verb@output->phi@ are created and
00077 filled at the requested sampling interval \verb@params->deltaT@; it is
00078 up to the calling routine to ensure that this sampling interval is
00079 reasonable.  As a guideline, we want to be able to determine the
00080 instantaneous wave phase accurately to within a fraction of a cycle.
00081 For functions that compute the phase by linear interpolation of
00082 \verb@output->phi@, this means sampling on timescales $\Delta
00083 t\lessim\dot{f}^{-1/2}\sim\max\{\sqrt{kf_0f_kT^{k-1}}\}$, where $T$ is
00084 the duration of the waveform.  More precisely, the largest deviation
00085 from linear phase evolution will typically be on the order of
00086 $\Delta\phi\approx(1/2)\ddot{\phi}(\Delta t/2)^2\approx(\pi/4)\Delta
00087 f\Delta t$, where $\Delta f$ is the frequency shift over the timestep.
00088 So if we want our interpolated phase to agree with the true phase to
00089 within, say, $\pi/2$ radians, then we would like to have
00090 $$
00091 \Delta f \Delta t \lessim 2 \;.
00092 $$
00093 This routine provides a check by setting the output parameter field
00094 \verb@params->dfdt@ equal to the maximum value of $\Delta f\Delta t$
00095 encountered during the integration.
00096 
00097 \subsubsection*{Uses}
00098 \begin{verbatim}
00099 LALMalloc()                   LALFree()
00100 LALSCreateVectorSequence()    LALSDestroyVectorSequence()
00101 LALSCreateVector()            LALSDestroyVector()
00102 LALDCreateVector()            LALDDestroyVector()
00103 LALSnprintf()
00104 \end{verbatim}
00105 
00106 \subsubsection*{Notes}
00107 
00108 \vfill{\footnotesize\input{GenerateTaylorCWCV}}
00109 
00110 ******************************************************* </lalLaTeX> */
00111 
00112 #include <lal/LALStdio.h>
00113 #include <lal/LALStdlib.h>
00114 #include <lal/LALConstants.h>
00115 #include <lal/Units.h>
00116 #include <lal/AVFactories.h>
00117 #include <lal/SeqFactories.h>
00118 #include <lal/SimulateCoherentGW.h>
00119 #include <lal/GenerateTaylorCW.h>
00120 
00121 NRCSID( GENERATETAYLORCWC, "$Id: GenerateTaylorCW.c,v 1.6 2007/06/08 14:41:47 bema Exp $" );
00122 
00123 /* <lalVerbatim file="GenerateTaylorCWCP"> */
00124 void
00125 LALGenerateTaylorCW( LALStatus          *stat,
00126                      CoherentGW         *output,
00127                      TaylorCWParamStruc *params )
00128 { /* </lalVerbatim> */
00129   UINT4 n, i;          /* number of and index over samples */
00130   UINT4 nSpin = 0, j;  /* number of and index over spindown terms */
00131   REAL8 t, tPow, dt;   /* time, interval, and t raised to a power */
00132   REAL8 f0, phi0;      /* initial phase and frequency */
00133   REAL8 twopif0;       /* 2*pi*f0 */
00134   REAL8 f, fPrev;      /* current and previous values of frequency */
00135   REAL4 df = 0.0;      /* maximum difference between f and fPrev */
00136   REAL8 phi;           /* current value of phase */
00137   REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */
00138   REAL4 *fData;        /* pointer to frequency data */
00139   REAL8 *phiData;      /* pointer to phase data */
00140 
00141   INITSTATUS( stat, "LALGenerateTaylorCW", GENERATETAYLORCWC );
00142   ATTATCHSTATUSPTR( stat );
00143 
00144   /* Make sure parameter and output structures exist. */
00145   ASSERT( params, stat, GENERATETAYLORCWH_ENUL,
00146           GENERATETAYLORCWH_MSGENUL );
00147   ASSERT( output, stat, GENERATETAYLORCWH_ENUL,
00148           GENERATETAYLORCWH_MSGENUL );
00149 
00150   /* Make sure output fields don't exist. */
00151   ASSERT( !( output->a ), stat, GENERATETAYLORCWH_EOUT,
00152           GENERATETAYLORCWH_MSGEOUT );
00153   ASSERT( !( output->f ), stat, GENERATETAYLORCWH_EOUT,
00154           GENERATETAYLORCWH_MSGEOUT );
00155   ASSERT( !( output->phi ), stat, GENERATETAYLORCWH_EOUT,
00156           GENERATETAYLORCWH_MSGEOUT );
00157   ASSERT( !( output->shift ), stat, GENERATETAYLORCWH_EOUT,
00158           GENERATETAYLORCWH_MSGEOUT );
00159 
00160   /* If Taylor coeficients are specified, make sure they exist. */
00161   if ( params->f ) {
00162     ASSERT( params->f->data, stat, GENERATETAYLORCWH_ENUL,
00163             GENERATETAYLORCWH_MSGENUL );
00164     nSpin = params->f->length;
00165     fSpin = params->f->data;
00166   }
00167 
00168   /* Set up some other constants, to avoid repeated dereferencing. */
00169   n = params->length;
00170   dt = params->deltaT;
00171   f0 = fPrev = params->f0;
00172   twopif0 = f0*LAL_TWOPI;
00173   phi0 = params->phi0;
00174 
00175   /* Allocate output structures. */
00176   if ( ( output->a = (REAL4TimeVectorSeries *)
00177          LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
00178     ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
00179   }
00180   memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
00181   if ( ( output->f = (REAL4TimeSeries *)
00182          LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
00183     LALFree( output->a ); output->a = NULL;
00184     ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
00185   }
00186   memset( output->f, 0, sizeof(REAL4TimeSeries) );
00187   if ( ( output->phi = (REAL8TimeSeries *)
00188          LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
00189     LALFree( output->a ); output->a = NULL;
00190     LALFree( output->f ); output->f = NULL;
00191     ABORT( stat, GENERATETAYLORCWH_EMEM, GENERATETAYLORCWH_MSGEMEM );
00192   }
00193   memset( output->phi, 0, sizeof(REAL8TimeSeries) );
00194 
00195   /* Set output structure metadata fields. */
00196   output->position = params->position;
00197   output->psi = params->psi;
00198   output->a->epoch = output->f->epoch = output->phi->epoch
00199     = params->epoch;
00200   output->a->deltaT = n*params->deltaT;
00201   output->f->deltaT = output->phi->deltaT = params->deltaT;
00202   output->a->sampleUnits = lalStrainUnit;
00203   output->f->sampleUnits = lalHertzUnit;
00204   output->phi->sampleUnits = lalDimensionlessUnit;
00205   LALSnprintf( output->a->name, LALNameLength, "CW amplitudes" );
00206   LALSnprintf( output->f->name, LALNameLength, "CW frequency" );
00207   LALSnprintf( output->phi->name, LALNameLength, "CW phase" );
00208 
00209   /* Allocate phase and frequency arrays. */
00210   LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
00211   BEGINFAIL( stat ) {
00212     LALFree( output->a );   output->a = NULL;
00213     LALFree( output->f );   output->f = NULL;
00214     LALFree( output->phi ); output->phi = NULL;
00215   } ENDFAIL( stat );
00216   LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
00217   BEGINFAIL( stat ) {
00218     TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00219          stat );
00220     LALFree( output->a );   output->a = NULL;
00221     LALFree( output->f );   output->f = NULL;
00222     LALFree( output->phi ); output->phi = NULL;
00223   } ENDFAIL( stat );
00224 
00225   /* Allocate and fill amplitude array. */
00226   {
00227     CreateVectorSequenceIn in; /* input to create output->a */
00228     in.length = 2;
00229     in.vectorLength = 2;
00230     LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
00231     BEGINFAIL( stat ) {
00232       TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00233            stat );
00234       TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
00235            stat );
00236       LALFree( output->a );   output->a = NULL;
00237       LALFree( output->f );   output->f = NULL;
00238       LALFree( output->phi ); output->phi = NULL;
00239     } ENDFAIL( stat );
00240     output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
00241     output->a->data->data[1] = output->a->data->data[3] = params->aCross;
00242   }
00243 
00244   /* Fill frequency and phase arrays. */
00245   fData = output->f->data->data;
00246   phiData = output->phi->data->data;
00247   for ( i = 0; i < n; i++ ) {
00248     t = tPow = i*dt;
00249     f = 1.0;
00250     phi = t;
00251     j = 0;
00252     while ( j < nSpin ) {
00253       f += fSpin[j]*tPow;
00254       phi += fSpin[j]*( tPow*=t )/( j + 2.0 );
00255       j++;
00256     }
00257     f *= f0;
00258     phi *= twopif0;
00259     if ( fabs( f - fPrev ) > df )
00260       df = fabs( f - fPrev );
00261     *(fData++) = fPrev = f;
00262     *(phiData++) = phi + phi0;
00263   }
00264 
00265   /* Set output field and return. */
00266   params->dfdt = df*dt;
00267   DETATCHSTATUSPTR( stat );
00268   RETURN( stat );
00269 }

Generated on Sun Sep 7 03:06:45 2008 for LAL by  doxygen 1.5.2