LALInspiralMoments.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 David Churches, Duncan Brown, Jolien Creighton, Benjamin Owen, 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="LALInspiralMomentsCV">
00021 Authors: Brown, D. A., Cokelaer, T. and  Sathyaprakash, B. S.
00022 $Id: LALInspiralMoments.c,v 1.19 2007/06/08 14:41:42 bema Exp $
00023 </lalVerbatim>  */
00024 
00025 #if 0
00026 <lalLaTeX>
00027 
00028 \subsection{Module \texttt{LALInspiralMoments.c}}
00029 
00030 Module to calculate the moment of the noise power spectral density. 
00031 
00032 \subsubsection*{Prototypes}
00033 \vspace{0.1in}
00034 \input{LALInspiralMomentsCP}
00035 \idx{LALInspiralMoments()}
00036 \begin{itemize}
00037    \item \texttt{moment,} Output, the value of the moment
00038    \item \texttt{pars,} Input 
00039 \end{itemize}
00040 
00041 \subsubsection*{Description}
00042 
00043 The moments of the noise curve are defined as
00044 \begin{equation}
00045 I(q)  \equiv S_{h}(f_{0}) \int^{f_{c}/f_{0}}_{f_{s}/f_{0}}
00046 \frac{x^{-q}}{S_{h}(x)} \, dx \,.  
00047 \end{equation}
00048 Because in practice we will always divide one of these moments by another, we
00049 do not need to include the $S_{h}(f_{0})$ term, which always cancels.
00050 This function calculates the integral
00051 \begin{equation}
00052 I = \int^{f_{c}/f_{0}}_{f_{s}/f_{0}} \frac{x^{-q}}{S_{h}(x)} \, dx \,.
00053 \end{equation} 
00054 It then divides this quantity by a normalisation constant which has been
00055 passed to the function. In the case of calculating the components of the
00056 metric for the signal manifold for the purpose of generating a template bank,
00057 this constant is given by $I(7)$, because of the definition of the quantity
00058 \begin{equation}
00059 J(q) \equiv \frac{I(q)}{I(7/3)} \,.
00060 \end{equation}
00061 
00062 \subsubsection*{Algorithm}
00063 Given the exponent \texttt{pars.ndx} and limits of integration
00064 \texttt{pars.xmin} and \texttt{pars.xmax} this function returns the moment of
00065 the power spectral density specified by the frequency series
00066 \texttt{pars.shf} according to
00067 \begin{equation}
00068 \mathtt{moment} = \int_{\mathtt{xmin}}^{\mathtt{xmax}} 
00069 \frac{x^{-\mathtt{ndx}}}{S_h(x)}\, dx \, .
00070 \end{equation}
00071 
00072 \subsubsection*{Uses}
00073 \begin{verbatim}
00074 LALDRombergIntegrate
00075 \end{verbatim}
00076 
00077 \subsubsection*{Notes}
00078 
00079 \vfill{\footnotesize\input{LALInspiralMomentsCV}}
00080 
00081 </lalLaTeX>
00082 #endif
00083 
00084 #include <lal/LALInspiralBank.h>
00085 #include <lal/Integrate.h>
00086 
00087 NRCSID( LALINSPIRALMOMENTSC, "$Id: LALInspiralMoments.c,v 1.19 2007/06/08 14:41:42 bema Exp $" );
00088 
00089 /* <lalVerbatim file="LALInspiralMomentsCP"> */
00090 void
00091 LALGetInspiralMoments (
00092     LALStatus            *status,
00093     InspiralMomentsEtc   *moments,
00094     REAL8FrequencySeries *psd,
00095     InspiralTemplate     *params 
00096     )
00097 /* </lalVerbatim> */
00098 {
00099   UINT4 k;
00100   InspiralMomentsIn in;
00101 
00102   INITSTATUS( status, "LALGetInspiralMoments", LALINSPIRALMOMENTSC );
00103   ATTATCHSTATUSPTR( status );
00104 
00105   ASSERT( params, status, 
00106       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00107   ASSERT( params->fLower>0, status, 
00108       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00109   ASSERT( moments, status, 
00110       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00111   ASSERT( psd, status,
00112       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00113 
00114   /* Constants needed in computing the moments */
00115   moments->a01 = 3.L/5.L;
00116   moments->a21 = 11.L * LAL_PI/12.L;
00117   moments->a22 = 743.L/2016.L * pow(25.L/(2.L*LAL_PI*LAL_PI),1.L/3.L);
00118   moments->a31 = -3.L/2.L;
00119   moments->a41 = 617.L * LAL_PI * LAL_PI / 384.L;
00120   moments->a42 = 5429.L/5376.L * pow(25.L*LAL_PI/2.L,1.L/3.L);
00121   moments->a43 = 1.5293365L/1.0838016L * pow(5.L/(4.L*pow(LAL_PI,4.L)),1.L/3.L);
00122 
00123   /* setup the input structure needed in the computation of the moments */
00124   in.shf = psd;
00125 
00126   /* Divide all frequencies by fLower, a scaling that is used in solving */
00127   /* the moments integral                                                */
00128   in.shf->f0 /= params->fLower;
00129   in.shf->deltaF /= params->fLower;
00130   in.xmin = params->fLower / params->fLower;
00131   in.xmax = params->fCutoff / params->fLower;
00132 
00133   /* First compute the norm and print if requested */
00134   in.norm = 1.L;
00135   in.ndx = 7.L/3.L; 
00136   LALInspiralMoments( status->statusPtr, &moments->j[7], in ); 
00137   CHECKSTATUSPTR( status );
00138   in.norm = moments->j[7];
00139 
00140   if ( lalDebugLevel & LALINFO )
00141   {
00142     LALPrintError( 
00143         "a01=%e a21=%e a22=%e a31=%e a41=%e a42=%e a43=%e j7=%e\n", 
00144         moments->a01, moments->a21, moments->a22, moments->a31, 
00145         moments->a41, moments->a42, moments->a43, moments->j[7] );
00146   }
00147 
00148   /* Then compute the normalised moments of the noise PSD from 1/3 to 17/3. */
00149   for ( k = 1; k <= 17; ++k )
00150   {
00151     in.ndx = (REAL8) k / 3.L; 
00152     LALInspiralMoments( status->statusPtr, &moments->j[k], in );  
00153     CHECKSTATUSPTR( status );
00154 
00155     if ( lalDebugLevel & LALINFO ) 
00156     {
00157       LALPrintError( "j%1i=%e\n", k, moments->j[k] );
00158     }
00159   }
00160 
00161   /* Moments are done: Rescale deltaF and f0 back to their original values */
00162   in.shf->deltaF *= params->fLower;
00163   in.shf->f0 *= params->fLower;
00164 
00165   DETATCHSTATUSPTR( status );
00166   RETURN( status );
00167 }
00168 
00169 
00170 void
00171 LALGetInspiralMomentsBCV (
00172     LALStatus               *status,
00173     InspiralMomentsEtcBCV   *moments,
00174     REAL8FrequencySeries    *psd,
00175     InspiralTemplate        *params 
00176     )
00177 {
00178   UINT4 k;
00179   InspiralMomentsIn in;
00180   double q;
00181 
00182   INITSTATUS( status, "LALGetInspiralMomentsBCV", LALINSPIRALMOMENTSC );
00183   ATTATCHSTATUSPTR( status );
00184 
00185   /* doesn't seem to be needed. thomas, janvier 2004. I prefer to remove it for the moment.
00186    *  The factor is not important in the case of SPA approximation but is important in BCV
00187    *  case. Indeed on one hand we use quantity which are a ratio between two moments and
00188    *  consequently a factor 1 or 2 is not important. Howver in the case of BCV, we might
00189    *  use a moment alone. Thus a factor in the computation has an effect. */
00190   
00191   /*  for (i=0; i< psd->data->length ; i++)
00192   {
00193     psd->data->data[i] = psd->data->data[i] * 1e45;
00194   }
00195    */
00196   in.shf = psd;  
00197   in.xmin = params->fLower;
00198   in.xmax = params->fCutoff;
00199 
00200   /* First compute the norm */
00201   in.norm = 1.L;
00202   for ( k = 0; k <= 22; ++k )
00203   {
00204     if (k <= 17)
00205     {
00206       /* positive value*/
00207       in.ndx = (REAL8)k / 3.L;
00208     }
00209     else
00210     {
00211       /* negative -1,-2 ...-6 */
00212       in.ndx = (17.- (REAL8)k) /3.L;
00213     }
00214 
00215     LALInspiralMoments( status->statusPtr, &moments->i[k], in ); 
00216     CHECKSTATUSPTR(status);
00217   }
00218 
00219   in.norm = moments->i[7] -2.*moments->alpha * moments->i[5] +    
00220     moments->alpha * moments->alpha*moments->i[3];
00221 
00222 
00223   /* 17 */
00224   q = 2* moments->n0; /*=10/3 */
00225   moments->M1[0][0] = (moments->i[17] -2.*moments->alpha * moments->i[15] +    
00226       moments->alpha * moments->alpha*moments->i[13]) / in.norm;
00227   /* 14 */
00228   q = moments->n0 +moments->n15; 
00229   moments->M1[0][1] = (moments->i[14] -2.*moments->alpha * moments->i[12] +    
00230       moments->alpha * moments->alpha*moments->i[10]) / in.norm;
00231   /* 11 */
00232   q = 2 * moments->n15; 
00233   moments->M1[1][1] = (moments->i[11] -2.*moments->alpha * moments->i[9] +    
00234       moments->alpha * moments->alpha*moments->i[7]) / in.norm;
00235 
00236   moments->M1[1][0]=moments->M1[0][1] ;
00237 
00238   /*  12 */
00239   q = moments->n0; 
00240   moments->M2[0][0] = (moments->i[12] -2.*moments->alpha * moments->i[10] +    
00241       moments->alpha * moments->alpha*moments->i[8]) / in.norm;   
00242   /* 9 */
00243   q = moments->n15; 
00244 
00245   moments->M2[0][1] = (moments->i[9] -2.*moments->alpha * moments->i[7] +    
00246       moments->alpha * moments->alpha*moments->i[5]) / in.norm;   
00247   /*  9 */
00248   q = moments->n0-1;   
00249 
00250   moments->M2[1][0] = (moments->i[9] -2.*moments->alpha * moments->i[7] +    
00251       moments->alpha * moments->alpha*moments->i[5]) / in.norm;
00252   /*  6 */
00253   q = moments->n15-1; 
00254   moments->M2[1][1] = (moments->i[6] -2.*moments->alpha * moments->i[4] +    
00255       moments->alpha * moments->alpha*moments->i[2]) / in.norm;
00256 
00257   /* 7 */
00258   q = 0; 
00259   moments->M3[0][0] = (moments->i[7] -2.*moments->alpha * moments->i[5] +    
00260       moments->alpha * moments->alpha*moments->i[3]) / in.norm;   
00261   /* 4 */
00262   q = -1; 
00263   moments->M3[0][1] = (moments->i[4] -2.*moments->alpha * moments->i[2] +    
00264       moments->alpha * moments->alpha*moments->i[0]) / in.norm;   
00265   /* 1 */
00266   q = -2; 
00267   moments->M3[1][1] = (moments->i[1] -2.*moments->alpha * moments->i[18] +    
00268       moments->alpha * moments->alpha * moments->i[20]) / in.norm;
00269 
00270   moments->M3[1][0]=moments->M3[0][1] ;
00271 
00272   if ( lalDebugLevel & LALINFO )
00273   {
00274     LALPrintError( "#M1=\n");
00275     LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
00276         moments->M1[0][0],
00277         moments->M1[0][1],
00278         moments->M1[1][0],
00279         moments->M1[1][1] );
00280 
00281     LALPrintError( "#M2=\n" );
00282     LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
00283         moments->M2[0][0],
00284         moments->M2[0][1],
00285 
00286         moments->M2[1][0],
00287         moments->M2[1][1] );
00288 
00289     LALPrintError( "#M3=\n" );     
00290     LALPrintError( "#%15.12lf %15.12lf \n# %15.12lf %15.12lf\n",
00291         moments->M3[0][0],
00292         moments->M3[0][1],
00293         moments->M3[1][0],
00294         moments->M3[1][1] );
00295   }
00296 
00297   DETATCHSTATUSPTR( status );
00298   RETURN( status );
00299 }
00300 
00301 
00302 /* <lalVerbatim file="LALInspiralMomentsCP"> */
00303 void
00304 LALInspiralMoments(
00305     LALStatus         *status,
00306     REAL8             *moment,
00307     InspiralMomentsIn  pars
00308     )
00309 /* </lalVerbatim> */
00310 {
00311   REAL8 f;
00312   REAL8 momentTmp;
00313   REAL8 fMin;
00314   REAL8 fMax;
00315   REAL8 deltaF;
00316   UINT4 k;
00317   UINT4 kMin;
00318   UINT4 kMax;
00319 
00320   INITSTATUS( status, "LALInspiralMoments", LALINSPIRALMOMENTSC );
00321 
00322   ASSERT( pars.shf, status, 
00323       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00324   ASSERT( pars.shf->data, status, 
00325       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00326   ASSERT( pars.shf->data->data, status, 
00327       LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL );
00328 
00329   /* make sure that the minimum and maximum of the integral are within */
00330   /* the frequency series                                              */
00331   fMax = pars.shf->f0 + (REAL8) pars.shf->data->length * pars.shf->deltaF;
00332   if ( pars.xmin < pars.shf->f0 || pars.xmax > fMax+LAL_REAL4_EPS )
00333   {
00334     ABORT( status, LALINSPIRALBANKH_EFRANGE, LALINSPIRALBANKH_MSGEFRANGE );
00335   }
00336 
00337   /* the minimum and maximum frequency where we have four points */
00338   deltaF = pars.shf->deltaF;
00339   fMin = pars.shf->f0 + deltaF;
00340   fMax = pars.shf->f0 + ((REAL8) pars.shf->data->length - 2 ) * deltaF;
00341 
00342   if ( pars.xmin <= fMin )
00343   {
00344     kMin = 1;
00345   }
00346   else
00347   {
00348     kMin = (UINT8) floor( (pars.xmin - pars.shf->f0) / deltaF );
00349   }
00350 
00351   if ( pars.xmax >= fMax )
00352   {
00353     kMax = pars.shf->data->length - 1;
00354   }
00355   else
00356   {
00357     kMax = (UINT8) floor( (pars.xmax - pars.shf->f0) / deltaF );
00358   }
00359 
00360   /* the first and last points of the integral */
00361   momentTmp = 0.;
00362   f = pars.shf->f0 + (REAL8) kMin * deltaF;
00363   if( pars.shf->data->data[kMin] )
00364   {
00365     momentTmp = pow( f, -(pars.ndx) ) / ( 2.0 * pars.shf->data->data[kMin] );
00366   }
00367   *moment = momentTmp;
00368 
00369   momentTmp = 0.;
00370   f = pars.shf->f0 + (REAL8) kMax * deltaF;
00371   if( pars.shf->data->data[kMin] )
00372   {
00373     momentTmp = pow( f, -(pars.ndx) ) / ( 2.0 * pars.shf->data->data[kMin] );
00374   }
00375   *moment += momentTmp;
00376 #if 0
00377   In the following line we should have kMax
00378   Changed by Sathya on June 30, 2002
00379   *moment += pow( f, -(pars.ndx) ) / ( 2.0 * pars.shf->data->data[kMin] );
00380 #endif
00381   momentTmp = 0.;
00382   if ( pars.shf->data->data[kMax] )
00383   {
00384     momentTmp = pow( f, -(pars.ndx) ) / ( 2.0 * pars.shf->data->data[kMax] );
00385   }
00386   *moment += momentTmp;
00387   kMin++;
00388   kMax--;
00389 
00390   for ( k = kMin; k < kMax; ++k )
00391   {
00392     momentTmp = 0.;
00393     f = pars.shf->f0 + (REAL8) k * deltaF;
00394     if ( pars.shf->data->data[k] )
00395     {
00396       momentTmp = pow( f, -(pars.ndx) ) / pars.shf->data->data[k];
00397     }
00398     *moment += momentTmp;
00399   }
00400 
00401   *moment *= deltaF;
00402 
00403   /* now divide the moment by the specified norm */
00404   *moment /= pars.norm;
00405 
00406   RETURN (status);
00407 }

Generated on Mon Sep 8 03:06:59 2008 for LAL by  doxygen 1.5.2