LALInspiralStationaryPhaseApprox1.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 B.S. Sathyaprakash, Thomas Cokelaer
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="LALInspiralStationaryPhaseApprox1CV">
00021  * Author: B.S. Sathyaprakash
00022  **** </lalVerbatim> */
00023 
00024 /**** <lalLaTeX>
00025  *
00026  * %% A one-line description of the function(s) defined in this module.
00027  * \subsection{Module \texttt{LALInspiralStationaryPhaseApprox1.c}}
00028  * This module computes the stationary phase approximation to the
00029  * Fourier transform of a chirp waveform by integrating Eq.~\ref{eq:InspiralFourierPhase}. 
00030  *
00031  * \subsubsection*{Prototypes}
00032  * \input{LALInspiralStationaryPhaseApprox1CP}
00033  * \idx{LALInspiralStationaryPhaseApprox1()}
00034  * \begin{itemize}
00035  * \item {\tt signal:} Output containing the inspiral waveform.
00036  * \item {\tt params:} Input containing binary chirp parameters.
00037  * \end{itemize}
00038  *
00039  * \subsubsection*{Description}
00040  *
00041  * %% A description of the data analysis task performed by this function;
00042  * %% this is the main place to document the module.
00043  * This module generates the Fourier domain waveform that is analogous of
00044  * the time-domain approximant {\tt TaylorT1.} Instead of re-expanding the
00045  * the energy and flux functions they are kept in tact and the integral
00046  * in Eq.~(\ref{eq:InspiralFourierPhase}) is solved numerically.
00047  * The code returns the Fourier transform packed in the same way as fftw
00048  * would for the Fourier transform of a real vector.  For a signal vector 
00049  * of length {\tt n=signal->length} ({\tt n} even):
00050  * \begin{itemize}
00051  * \item {\tt signal->data[0]} is the {\it real} 0th frequency component of the Fourier transform.
00052  * \item {\tt signal->data[n/2]} is the {\it real} Nyquist frequency component of the Fourier transform.
00053  * \item {\tt signal->data[k]} and {\tt signal->data[n-k],} for {\tt k=1,\ldots, n/2-1,} are
00054  * the real and imaginary parts of the Fourier transform at a frequency $k\Delta f=k/T,$ $T$ being
00055  * the duration of the signal and $\Delta f=1/T$ is the frequency resolution.
00056  * \end{itemize}
00057  *
00058  * \subsubsection*{Algorithm}
00059  *
00060  * %% A description of the method used to perform the calculation.
00061  * The lal code {\tt LALDRomberIntegrate} is used to solve the 
00062  * integral in Eq.~(\ref{eq:InspiralFourierPhase}).
00063  * The reference points are chosen so that on inverse Fourier transforming
00064  * the time-domain waveform will 
00065  * \begin{itemize}
00066  * \item be padded with zeroes in the first {\tt params->nStartPad} bins,
00067  * \item begin with a phase shift of {\tt params->nStartPhase} radians,
00068  * \item have an amplitude of ${\tt n} v^2.$ 
00069  * \end{itemize}
00070  *
00071  * \subsubsection*{Uses}
00072  *
00073  * %% List of any external functions called by this function.
00074  * \begin{verbatim}
00075    LALInspiralSetup 
00076    LALInspiralChooseModel
00077    LALDRombergIntegrate 
00078  * \end{verbatim}
00079  * \subsubsection*{Notes}
00080  *
00081  * %% Any relevant notes.
00082  * If it is required to compare the output of this module with a time domain
00083  * signal one should use an inverse Fourier transform routine that packs data
00084  * in the same way as fftw. Moreover, one should divide the resulting inverse
00085  * Fourier transform by a factor ${\tt n}/2$ to be consistent with the 
00086  * amplitude used in time-domain signal models.
00087  *
00088  *
00089  *
00090  * \vfill{\footnotesize\input{LALInspiralStationaryPhaseApprox1CV}}
00091  *
00092  **** </lalLaTeX> */
00093 
00094 #include <lal/LALInspiral.h>
00095 #include <lal/Integrate.h>
00096 
00097 /* a local function to compute the phase of the Fourier transform */
00098 void 
00099 LALPsiOfT (
00100    LALStatus *stauts, 
00101    REAL8     *psioft, 
00102    REAL8      v, 
00103    void      *param
00104    );
00105 
00106 NRCSID (LALINSPIRALSTATIONARYPHASEAPPROX1C, "$Id: LALInspiralStationaryPhaseApprox1.c,v 1.6 2007/06/08 14:41:49 bema Exp $");
00107 
00108 /* This is the main function to compute the stationary phase approximation */
00109 
00110 /*  <lalVerbatim file="LALInspiralStationaryPhaseApprox1CP"> */
00111 void 
00112 LALInspiralStationaryPhaseApprox1 (
00113    LALStatus        *status, 
00114    REAL4Vector      *signal,
00115    InspiralTemplate *params
00116    ) 
00117 { /* </lalVerbatim>  */
00118    REAL8 t, pimmc, f0, fn, f, v, df, shft, phi, amp0, amp, psif, psi, sign;
00119    INT4 n, i, nby2;
00120    void *funcParams;
00121    DIntegrateIn intinp;
00122    TofVIntegrandIn psiIn;
00123    TofVIn tofvin;
00124    expnCoeffs ak;
00125    expnFunc func;
00126 
00127    INITSTATUS (status, "LALInspiralStationaryPhaseApprox1", LALINSPIRALSTATIONARYPHASEAPPROX1C);
00128    ATTATCHSTATUSPTR(status);
00129    ASSERT (signal,  status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00130    ASSERT (signal->data,  status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00131    ASSERT (params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00132 
00133 /* Set up the coefficients in post-Newtonian expansion, vlso, etc. */
00134    LALInspiralSetup (status->statusPtr, &ak, params);
00135    CHECKSTATUSPTR(status);
00136 /* Set up the functions required for the chosen signal approximation sheme */
00137    LALInspiralChooseModel(status->statusPtr, &func, &ak, params);
00138    CHECKSTATUSPTR(status);
00139 
00140 /* Cast the struct required for the phase function */
00141    psiIn.dEnergy = func.dEnergy;
00142    psiIn.flux = func.flux;
00143    psiIn.coeffs = &ak;
00144 
00145 /* Cast the struct required for computing initial conditions */
00146    n = signal->length;
00147    nby2 = n/2;
00148    df = params->tSampling/signal->length;
00149    pimmc = LAL_PI * ak.totalmass;
00150    t = 0.0;
00151    tofvin.t = t;
00152    tofvin.v0 = ak.v0;
00153    tofvin.t0 = ak.t0;
00154    tofvin.vlso = ak.vlsoT2;
00155    tofvin.totalmass = ak.totalmass;
00156    tofvin.dEnergy = func.dEnergy;
00157    tofvin.flux = func.flux;
00158    tofvin.coeffs = &ak;
00159 
00160 /* Compute the initial velocity frequency  */
00161    LALInspiralVelocity(status->statusPtr, &v, &tofvin);
00162    f0 = pow(v,3.L)/pimmc;
00163    fn = (params->fCutoff < ak.fn) ? params->fCutoff : ak.fn; 
00164 
00165    /* If we want to pad with zeroes in the beginning then the instant of
00166     * coalescence will be the chirp time + the duration for which padding
00167     * is needed. Thus, in the equation below nStartPad occurs with a +ve sign.
00168     */
00169    shft = LAL_PI*2.L * (ak.tn + params->nStartPad/params->tSampling + params->startTime);
00170    phi =  params->startPhase + LAL_PI/4.L;
00171    amp0 = params->signalAmplitude * ak.totalmass * pow(LAL_PI/12.L, 0.5L) * df;
00172 
00173    signal->data[0] = 0.;
00174    signal->data[nby2] = 0.;
00175 /* 
00176    Compute the standard stationary phase approximation. 
00177 */
00178    funcParams = (void *) &psiIn;
00179    intinp.function = LALPsiOfT;
00180    intinp.type = ClosedInterval;
00181    for (i=1; i<nby2; i++) 
00182    {
00183       f = i * df;
00184       if (f<f0 || f>fn)
00185       {
00186 /* 
00187    All frequency components below f0 and above fn are set to zero  
00188 */
00189          signal->data[i] = 0.;
00190          signal->data[n-i] = 0.;
00191       }
00192       else
00193       {
00194          ak.vf = v = pow(pimmc * f, oneby3);
00195          if (v==ak.v0) 
00196          {
00197             psif = 0.;
00198 
00199          } 
00200          else 
00201          {
00202             if (ak.v0 > ak.vf) 
00203             {
00204                intinp.xmin = ak.vf;
00205                intinp.xmax = ak.v0;
00206                sign = -1.0;
00207             } 
00208             else 
00209             {
00210                intinp.xmin = ak.v0;
00211                intinp.xmax = ak.vf;
00212                sign = 1.0;
00213             }
00214             LALDRombergIntegrate (status->statusPtr, &psif, &intinp, funcParams);
00215             CHECKSTATUSPTR(status);
00216             psif *= sign;
00217          }
00218          psi = shft * f + phi + psif;
00219 /* 
00220       dEnergybyFlux computes 1/(dv/dt) while what we need is 1/(dF/dt):
00221       dF/dt=(dF/dv)(dv/dt)=-dEnergybyFlux/(dF/dv)=-dEnergybyFlux 3v^2/(LAL_PI m^2)
00222 */
00223          amp = amp0 * pow(-func.dEnergy(v,&ak)/func.flux(v,&ak),0.5) * v;
00224          signal->data[i] = (REAL4) (amp * cos(psi));
00225          signal->data[n-i] = -(REAL4) (amp * sin(psi));
00226       }
00227    }
00228    params->fFinal = fn;
00229    DETATCHSTATUSPTR(status);
00230    RETURN(status);
00231 }
00232 
00233 void 
00234 LALPsiOfT(
00235    LALStatus *status, 
00236    REAL8     *psioft, 
00237    REAL8      v, 
00238    void      *param
00239    ) 
00240 {
00241    REAL8 vf, dE, F;
00242    TofVIntegrandIn *par;
00243 
00244    status = NULL;
00245    par = (TofVIntegrandIn *) param;
00246 
00247    /* The integrand below has an overall -ve sign as compared to
00248     * Eq. (3.5) of DIS3; this is because as oppsed to Eq. (3.5) of
00249     * DIS3 here we integrate from v0 to vf instead of from vf to v0.
00250     */
00251    dE = par->dEnergy(v, par->coeffs);
00252    F = par->flux(v, par->coeffs);
00253    vf = par->coeffs->vf;
00254    *psioft = 2. * (v*v*v - vf*vf*vf) * dE/F;
00255 }

Generated on Thu Aug 21 03:12:45 2008 for LAL by  doxygen 1.5.2