LALInspiralHybridHexagonalBank.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 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="LALInspiralHybridHexagonalBankCV">
00021 Author: Cokelaer Thomas
00022 $Id: LALInspiralHybridHexagonalBank.c,v 1.7 2007/06/08 14:41:42 bema Exp $
00023 </lalVerbatim>  */
00024 
00025 /*  <lalLaTeX>
00026 
00027 \subsection{Module \texttt{LALInspiralHybridHexagonalBank.c}}
00028 
00029 \subsubsection*{Prototypes}
00030 \vspace{0.1in}
00031 \input{LALInspiralHybridHexagonalBankCP}
00032 \idx{LALInspiralHybridHexagonalBank()}
00033 
00034 \subsubsection*{Description}
00035 This code does almost the same as the standard Hexagonal Bank code. However, 
00036 once the templates cover both the equal line and an other line ($m_1={\rm mMin}$ 
00037 or $m_2 ={\rm mMax}$), then there is no need to carry on any square/hexagonal 
00038 placement. One can simply populate templates along a bissectrice. 
00039 
00040 \subsubsection*{Algorithm}
00041 The algorithm is identical to the hexagonal placement. However, once a template covers
00042 both the equal mass line and the upper boundary, then the hexagonal placement stops. 
00043 So, an additional placement is needed to finalise the bank. In principle the placement 
00044 needs to be completed on bothe side of the template bank, at low mass and high mass. So, 
00045 we should start from the two templates which covers the two boundaries and populate the 
00046 parameter space along a bissectrice. 
00047 
00048 
00049 The coordinates of the bissectrice at a given $tau_0$ coordinate is estimated by tracing a vertical 
00050 line in the $\tau_0/tau_3$ plane, estimate the vlue of $tau_3$ on the upper boundary and low 
00051 boundary ($\eta=1/4$ line), and finally take the mean of the two values. Although,  is is an approximation
00052 since we should also take into account the orientation of the ellipse, we 
00053 think this is good enough.  The vertical line crosses the parameter space on the
00054 $\eta=1/4$ line and the other parameter space boundary which is define either by (1)
00055 $m_1=variable$ and $m_2=mMin$ or (2) $m_1=variable$ and $m_2=mMax$. Concerning (1), 
00056 $\eta=1/4$, this is a trivial computation, since 
00057 \begin{equation}
00058 \tau_3 =    \frac{  A3}{\eta}  \left( \frac{\eta \tau_0}{A0} \right)^{2/5},
00059 \end{equation}
00060 which in the case of $\eta=1/4$ simply becomes :
00061 \begin{equation}
00062 \tau_3 =     4 A3  \left( \frac{\tau_0}{4 A0} \right)^{2/5}.
00063 \end{equation}
00064 In the case (2), if $\tau_0$ is provided, if we can extract the total mass and $\eta$ parameter, 
00065 then $tau_3$ is given by 
00066 \begin{equation}
00067 \tau_3 =    \frac{  A3}{\eta}  M^{-2/3}.
00068 \end{equation}
00069 So, we need $M$ and $\eta$. Starting from
00070 \begin{equation}
00071 \tau_0 =    \frac{  A0}{\eta}  \left( M \right)^{-5/3}, 
00072 \end{equation}
00073 we can extract a cubic equation
00074 \begin{equation}
00075 x^3 - px+q=0
00076 \end{equation}
00077 where $x = M^{1/3}$, $p = -\frac{A0}{\tau_0/m_{\rm Extreme}}$ and $q= - m_{\rm Extreme}=0$. $ m_{\rm Extreme}$ 
00078 is either set to mMin or mMax depending on which side of the parameter space we are. 
00079 
00080 The solution for $x$ is standard and takes the expression : 
00081 \begin{equation}
00082 x =  \left(-\frac{q}{2}-\frac{1}{2}*\sqrt{\frac{27 q^2 + 4 p^3}{27}}\right)^{\frac{1}{3}}
00083    + \left(-\frac{q}{2}+\frac{1}{2}*\sqrt{\frac{27 q^2 + 4 p^3}{27}}\right)^{\frac{1}{3}};
00084 \end{equation}
00085 
00086 \begin{figure}[]
00087 \begin{center}
00088 \includegraphics[angle=-180, width=-3.5 true in]{LALInspiralHybridHexa2}
00089 \label{fig:hybridhexa1}
00090 \end{center}
00091 \caption{Example of hybrid hexagonal placement. Once an ellipse covers the upper and lower boundary, then the hexagonal
00092 placement stops. This occurs neccesseraly at low and high mass range. }
00093 \end{figure}
00094  
00095 
00096 \begin{figure}[]
00097 \begin{center}
00098 \includegraphics[angle=-180, width=-3.5 true in]{LALInspiralHybridHexa1}
00099 \label{fig:hybridhexa1}
00100 \end{center}
00101 \caption{Example of hybrid hexagonal placement. Once the ellipses covers the upper and lower part of the parameter space (at
00102 tau0=3.6 and tau0=0.4), then the placement is switched from the hexagonal to a placement along the bissectric of the
00103 upper/lower boundaries as described in the text.}
00104 \end{figure}
00105  
00106 
00107 \subsubsection*{Uses}
00108 \begin{verbatim}
00109 LALPopulateNarrowEdge()
00110 XLALInspiralBissectionLine ()
00111 \end{verbatim}
00112 
00113 \subsubsection*{Notes}
00114 
00115 \vspace{0.1in}
00116 \vfill{\footnotesize\input{LALInspiralHybridHexagonalBankCV}}
00117 </lalLaTeX>  */
00118 
00119 #include <stdio.h>
00120 #include <lal/LALInspiralBank.h>
00121 #include <lal/AVFactories.h>
00122 #include <lal/SeqFactories.h>
00123 #include <lal/LALStdio.h>
00124 #include <lal/FindRoot.h>
00125 
00126 
00127 
00128 
00129   
00130 void
00131 LALPopulateNarrowEdge(LALStatus         *status,
00132                       InspiralMomentsEtc      *moments,
00133                       InspiralCell            **cell, 
00134                       INT4                     headId,
00135                       InspiralTemplate        *paramsIn,
00136                       HexaGridParam           *gridParam,
00137                       CellEvolution           *cellEvolution, 
00138                       CellList **cellList,
00139                       INT4 flag
00140                       );
00141 
00142 
00143 NRCSID(LALINSPIRALHYBRIDHEXAGONALBANKC, "$Id: LALInspiralHybridHexagonalBank.c,v 1.7 2007/06/08 14:41:42 bema Exp $");
00144 
00145 /*  <lalVerbatim file="LALInspiralHybridHexagonalBankCP"> */
00146 void 
00147 LALInspiralCreatePNCoarseBankHybridHexa(
00148     LALStatus            *status, 
00149     InspiralTemplateList **list, 
00150     INT4                 *nlist,
00151     InspiralCoarseBankIn coarseIn
00152     ) 
00153 {  /*  </lalVerbatim>  */
00154   INT4                  i; 
00155   INT4                  firstId = 0;
00156   REAL4                 A0, A3; 
00157   REAL4                 piFl;
00158   InspiralBankParams    bankPars;
00159   InspiralTemplate      *tempPars;
00160   InspiralMomentsEtc    moments;
00161   InspiralCell          *cells;  
00162   HexaGridParam         gridParam;
00163   CellEvolution         cellEvolution;
00164   CellList              *cellList = NULL;
00165 
00166   INITSTATUS( status, "LALInspiralHybridHexagonalBank", 
00167       LALINSPIRALHYBRIDHEXAGONALBANKC );
00168   ATTATCHSTATUSPTR( status );
00169 
00170   ASSERT( coarseIn.mMin > 0., status, 
00171       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00172   ASSERT( coarseIn.mMax > 0., status, 
00173       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00174   ASSERT( coarseIn.MMax >= 2.*coarseIn.mMin, status, 
00175       LALINSPIRALBANKH_ESIZE, LALINSPIRALBANKH_MSGESIZE );
00176 
00177   /* Set the elements of the metric and tempPars structures in  */
00178   /* conformity with the coarseIn structure                     */ 
00179   if ( !(tempPars = (InspiralTemplate *) 
00180                         LALCalloc( 1, sizeof(InspiralTemplate)))) 
00181   {
00182     LALFree(tempPars);
00183     LALFree(cells);
00184     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00185   }
00186 
00187   
00188   LALInspiralSetParams( status->statusPtr, tempPars, coarseIn );
00189   CHECKSTATUSPTR( status );
00190   
00191   /* Identify the boundary of search and parameters for the     */
00192   /* first lattice point                                        */
00193   LALInspiralSetSearchLimits( status->statusPtr, &bankPars, coarseIn );
00194   CHECKSTATUSPTR( status );
00195   
00196   tempPars->totalMass   = coarseIn.MMax;
00197   tempPars->eta         = 0.25;
00198   tempPars->ieta        = 1.L;
00199   tempPars->fLower      = coarseIn.fLower;
00200   tempPars->massChoice  = m1Andm2;
00201   tempPars->mass1       = coarseIn.mMin;
00202   tempPars->mass2       = coarseIn.mMax;
00203   
00204   LALInspiralParameterCalc( status->statusPtr, tempPars );
00205   CHECKSTATUSPTR( status );
00206   
00207   /* Get the moments of the PSD integrand and other parameters */
00208   /* required in the computation of the metric  once for all.   */
00209   LALGetInspiralMoments( 
00210                 status->statusPtr, 
00211                 &moments,
00212                 &coarseIn.shf,
00213                 tempPars );
00214   CHECKSTATUSPTR( status );
00215   
00216   /* Allocate memory for one cell */
00217   cells = (InspiralCell*)
00218       LALCalloc(1,   sizeof(InspiralCell) );
00219 
00220   /*define gridParam*/
00221   gridParam.mm          = coarseIn.mmCoarse;
00222   gridParam.x0Min       = bankPars.x0Min;
00223   gridParam.x0Max       = bankPars.x0Max;
00224   gridParam.x1Min       = bankPars.x1Min;
00225   gridParam.x1Max       = bankPars.x1Max;
00226   gridParam.mMin        = coarseIn.mMin;
00227   gridParam.mMax        = coarseIn.mMax;
00228   gridParam.MMin        = coarseIn.MMin;
00229   gridParam.MMax        = coarseIn.MMax;
00230   gridParam.etaMin      = coarseIn.etamin;
00231   gridParam.space       = coarseIn.space;
00232   gridParam.massRange   = coarseIn.massRange;
00233   gridParam.gridSpacing = coarseIn.gridSpacing;
00234   gridParam.fLower      = coarseIn.fLower;
00235 
00236 
00237   cellEvolution.nTemplate               = 1;
00238   cellEvolution.nTemplateMax    = 1;
00239   cellEvolution.fertile                 = 0;
00240 
00241   /* initialise that first cell */
00242   tempPars->massChoice  = t03;
00243   cells[0].t0           = tempPars->t0;
00244   cells[0].t3           = tempPars->t3;
00245 
00246   /* some aliases */
00247   piFl  = LAL_PI * tempPars->fLower;
00248   A0    = 5. / pow(piFl, 8./3.) / 256.;
00249   A3    = LAL_PI / pow(piFl, 5./3.)/8.;
00250 
00251 
00252   /* Initialise the first template */
00253   LALInitHexagonalBank(
00254                         status->statusPtr, 
00255                         &cells, firstId, 
00256                         &moments, tempPars,
00257                         &gridParam, &cellEvolution, 
00258                         &cellList);
00259   CHECKSTATUSPTR( status );
00260 
00261 
00262   {
00263     INT4 k, kk; /*some indexes*/
00264     INT4 *list          = NULL;
00265     CellList *ptr       = NULL;
00266     INT4 length         = 1; /* default size of the bank when we 
00267                                                 start the bank generation. */
00268 
00269     /* we re-allocate an array which size equals the 
00270      * template bank size. */
00271     if (! (list =  LALMalloc(length*sizeof(INT4))))
00272     {
00273       ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00274     }
00275 
00276     /* while there are cells/template which can propagate, we carry on the loop.*/
00277     while (cellEvolution.fertile) 
00278     {
00279       length = LALListLength(cellList);
00280       /*realloc some memory for the next template*/
00281       if (! (list =  LALRealloc(list, length*sizeof(INT4))))
00282       {
00283                 ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00284                 /* freeing memory here ? */
00285       }
00286       ptr = cellList;
00287       /* we extract the ids which might change within the LALPopulateCell 
00288        * function. Indeed the bank might grow and then we will lost track 
00289        * of ids/bank size and so on. */
00290       for ( k = 0; k < length; k++)
00291       {
00292                 list[k] = ptr->id;      
00293                 ptr = ptr->next;
00294       }
00295       /* look at all the template/ids in the current bank to search for fertile cells */
00296       for (kk = 0; kk < length; kk++)
00297           {     
00298                 k = list[kk];
00299                 if ( cells[k].status == Fertile) 
00300                 {
00301           LALPopulateCell(status->statusPtr, &moments, &cells,
00302               k,  tempPars, &gridParam, &cellEvolution, &cellList);          
00303                   CHECKSTATUSPTR( status );                       
00304                   /* now the bank might have grown, but we only look at the 
00305                    * template created before this for loop, when we entered 
00306                    * in the while loop
00307                    * */
00308         }
00309       }
00310     }
00311     LALFree(list);
00312   }
00313 
00314 #if 1 
00315   {
00316 
00317         
00318         
00319     INT4 edge1=0, edge2=0; 
00320     
00321         gridParam.gridSpacing = Hexagonal;
00322 
00323     i=0;
00324     while (i<cellEvolution.nTemplate){    
00325       if (cells[i].status == Edge){
00326         edge1 = i;
00327         cells[i].status = In;   
00328         i=cellEvolution.nTemplate;
00329       }
00330       i++;
00331     }
00332     i=0;
00333     while (i<cellEvolution.nTemplate){    
00334       if (cells[i].status == Edge){
00335         edge2=i;
00336         cells[i].status = In;   
00337         i=cellEvolution.nTemplate;
00338       }
00339       i++;
00340     }
00341     
00342   
00343     
00344     if (cells[edge1].t0 > cells[edge2].t0){
00345       LALPopulateNarrowEdge(status->statusPtr, &moments, &cells,
00346                             edge1,  tempPars, &gridParam, &cellEvolution, &cellList, 0);          
00347       CHECKSTATUSPTR( status );          
00348       LALPopulateNarrowEdge(status->statusPtr, &moments, &cells,
00349                             edge2,  tempPars, &gridParam, &cellEvolution, &cellList, 1);          
00350       CHECKSTATUSPTR( status );          
00351     }
00352     else
00353     {
00354       LALPopulateNarrowEdge(status->statusPtr, &moments, &cells,
00355                             edge1,  tempPars, &gridParam, &cellEvolution, &cellList, 1);          
00356       CHECKSTATUSPTR( status );          
00357       LALPopulateNarrowEdge(status->statusPtr, &moments, &cells,
00358                             edge2,  tempPars, &gridParam, &cellEvolution, &cellList, 0);          
00359       CHECKSTATUSPTR( status );               
00360     }
00361   }
00362 
00363 
00364 #endif
00365   
00366 
00367       
00368   if (cellList != NULL)
00369     ABORT(status, LALINSPIRALBANKH_EHEXAINIT,LALINSPIRALBANKH_MSGEHEXAINIT);
00370         /* Here is the current number of template generated. Now, we need 
00371          * to clean some of them which might be redundant.
00372          * */
00373   *nlist = cellEvolution.nTemplate;
00374 
00375   {
00376     INT4 k ;
00377     INT4 length;
00378     length = cellEvolution.nTemplate;
00379 
00380     for ( k = 0; k < length; k++)
00381     {  
00382       REAL4 a;
00383       REAL4 b;
00384       REAL4 x0;
00385       REAL4 tempA3;
00386       SFindRootIn input;
00387       INT4 valid;
00388 
00389       PRIN  prin;
00390         
00391       tempA3              = pow(A3, -5./2.)/pow(0.25,-1.5);
00392       tempPars->t0        = cells[k].t0;
00393       tempPars->t3        = cells[k].t3;
00394       /* if non physical parameter i.e below eta=0.25*/
00395       if(cells[k].RectPosition[0] == Below ) 
00396       {   
00397         INT4 above=0, below=0, in=0, out=0;
00398                   
00399                 /*first, we define the line which is along the long semi-axis of the 
00400                  * ambiguity function, defined by the angle theta and the position of 
00401                  * the template.
00402                  * */                     
00403                 a = tan(cells[k].metric.theta);
00404                 b = cells[k].t3 - a * cells[k].t0;
00405                 /* and call a function to search for a solution along eta=1/4 */
00406                 input.function  = LALSPAF;
00407                 input.xmin              = cells[k].t3-1e-3;
00408                 input.xmax              = 1000;
00409                 input.xacc              = 1e-6;
00410         
00411                 prin.ct = a * A0 * tempA3;
00412                 prin.b = b;
00413         
00414                 LALSBisectionFindRoot(status->statusPtr,
00415                         &x0, &input, (void *)&prin);
00416                 CHECKSTATUSPTR( status );         
00417         
00418                 tempPars->t3 = x0 + 1e-3; /* to be sure it is physical */
00419                 tempPars->t0 = (tempPars->t3 - b)/a;
00420                 if (tempPars->t0 > 0) 
00421                 {
00422                   LALInspiralParameterCalc(status->statusPtr, tempPars);
00423                   CHECKSTATUSPTR( status );                       
00424                 }
00425                 else 
00426                 {
00427                         LALWarning(status,"HybridHexagonal placement: nothing to be done since t0<=0\n");
00428                 }
00429                 
00430                 cells[k].t0  = tempPars->t0;
00431                 cells[k].t3  = tempPars->t3;    
00432                 
00433                 /* update its position values */
00434                 valid = 1;
00435                 GetPositionRectangle(status->statusPtr, &cells, k,  tempPars , 
00436                              &gridParam, 
00437                              &cellEvolution, 
00438                              &cellList, 
00439                              &valid);
00440                 {
00441 
00442                         switch (cells[k].RectPosition[1]){
00443                           case In:    in    +=1; break;
00444                           case Below: below +=1; break;
00445                           case Above: above +=1; break;
00446                           case Out:   out   +=1; break;
00447                           }
00448                           switch (cells[k].RectPosition[2]){
00449                           case In:    in    +=1; break;
00450                           case Below: below +=1; break;
00451                           case Above: above +=1; break;
00452                           case Out:   out   +=1; break;
00453                           }
00454                           switch (cells[k].RectPosition[3]){
00455                           case In:    in    +=1; break;
00456                           case Below: below +=1; break;
00457                           case Above: above +=1; break;
00458                           case Out:   out   +=1; break;
00459                           }
00460                           switch (cells[k].RectPosition[4]){
00461                           case In:    in    +=1; break;
00462                           case Below: below +=1; break;
00463                           case Above: above +=1; break;
00464                           case Out:   out   +=1; break;
00465                           }
00466                         }
00467 
00468 
00469                   if (above == 2 && cells[k].position == In)
00470                   {
00471                   if (cells[k].child[0] >=0 )
00472                    {
00473                      cells[cells[k].child[0]].position = Out;   
00474                    }
00475                    else
00476                    {
00477                      /* nothing to be done, the child is not valid anyway*/
00478                    }
00479 
00480                   }
00481                   else 
00482                   {
00483 
00484                   }
00485         }
00486         else
00487          {
00488          
00489          }
00490     }
00491   }
00492 
00493   for (i=0; i<cellEvolution.nTemplate; i++) {
00494     if (cells[i].position == In ) {
00495       *nlist = *nlist +1; 
00496     }
00497   }
00498   
00499 
00500 
00501   /* allocate appropriate memory and fill the output bank */
00502   *list = (InspiralTemplateList*) 
00503     LALRealloc( *list, sizeof(InspiralTemplateList) * (*nlist+1) );
00504   if ( ! *list )
00505   {
00506     LALFree( tempPars );
00507     ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00508   }
00509   memset( *list + *nlist, 0, sizeof(InspiralTemplateList) );
00510   {
00511     *nlist = 0 ;
00512     for (i=0; i<cellEvolution.nTemplate; i++) 
00513     {
00514       if (cells[i].position == In & cells[i].t0>0) 
00515       {
00516         tempPars->t0  = cells[i].t0;
00517         tempPars->t3  = cells[i].t3;
00518         tempPars->massChoice = t03;
00519         tempPars->fLower = coarseIn.fLower;
00520         LALInspiralParameterCalc( status->statusPtr, tempPars );
00521         CHECKSTATUSPTR( status );
00522             
00523         (*list)[*nlist].ID            = *nlist; 
00524         (*list)[*nlist].params        = *tempPars; 
00525         (*list)[*nlist].metric        = cells[i].metric; 
00526         ++(*nlist); 
00527       }
00528     }
00529   }
00530   
00531     
00532   LALFree( cells );
00533   LALFree( tempPars );
00534   
00535   DETATCHSTATUSPTR( status );
00536   RETURN ( status );
00537 }
00538   
00539 
00540 
00541 
00542 
00543 
00544 
00545 
00546 REAL8
00547 XLALInspiralBissectionLine (
00548         REAL8 tau0,
00549         REAL8 fL,
00550         REAL8 mMin,
00551         REAL8 mMax)
00552 {
00553   REAL8 piFa;
00554   REAL8 tau3_a, tau3_b, M, eta, massSep;
00555   
00556   /* First we solve for the lower (equal mass) limit */
00557   tau3_a = XLALInspiralTau3FromTau0AndEqualMassLine( tau0, fL);
00558 
00559   /* Figure out the boundary between m1 = mMin and m1 = mMax */
00560   M = mMin + mMax;
00561   eta = (mMin*mMax)/pow(M, 2.0);  
00562   massSep = XLALInspiralTau0FromMEta(M, eta, fL);
00563   
00564   /* Next we solve for the upper part */
00565   if (tau0 >= massSep )
00566   { 
00567     M = XLALInspiralMFromTau0AndNonEqualMass (tau0,  mMin, fL);
00568     eta = mMin*(M-mMin)/ pow(M,2.0);
00569   }
00570   else
00571   {
00572     M = XLALInspiralMFromTau0AndNonEqualMass (tau0,  mMax, fL);
00573     eta = mMax*(M-mMax)/ pow(M,2.0);
00574   }
00575  
00576   tau3_b = XLALInspiralTau3FromNonEqualMass(M,eta,fL);
00577  
00578   return (0.5 * (tau3_a + tau3_b));
00579 }
00580 
00581 
00582 
00583 void
00584 LALPopulateNarrowEdge(LALStatus               *status,
00585                       InspiralMomentsEtc      *moments,
00586                       InspiralCell            **cell, 
00587                       INT4                     headId,
00588                       InspiralTemplate        *paramsIn,
00589                       HexaGridParam           *gridParam,
00590                       CellEvolution           *cellEvolution, 
00591                       CellList **cellList, 
00592                       INT4                    flag
00593                       )
00594 {
00595   REAL4 dx0, dx1;  
00596   REAL4 theta, ctheta,stheta;
00597   INT4 offSpring;
00598   INT4 next, iteration;
00599   REAL4 x_int, y_int,xr_int, yr_int, c,s, dy,theta_min, theta_max, theta_int, a, b, t0, t3;
00600 
00601   INITSTATUS( status, "LALPopulateNarrowEdge",
00602               LALINSPIRALHYBRIDHEXAGONALBANKC );
00603   ATTATCHSTATUSPTR( status );
00604 
00605   /* aliases to get the characteristics of the parent template, that we refer
00606    * to its ID (headId) */  
00607   
00608   while ( (*cell)[headId].t0 < gridParam->x0Max && (*cell)[headId].t0 > gridParam->x0Min) {
00609 
00610     dx0           = (*cell)[headId].dx0/sqrt(2.);
00611     dx1           = (*cell)[headId].dx1/sqrt(2.);
00612     theta         = (*cell)[headId].metric.theta;
00613     ctheta        = cos(theta); /*aliases*/
00614     stheta        = sin(theta); /*aliases*/
00615     offSpring     = cellEvolution->nTemplate;
00616       
00617     /* reallocate memory by set of 1000 cells if needed*/
00618     if ( cellEvolution->nTemplate  >= cellEvolution->nTemplateMax){
00619       *cell = (InspiralCell*) 
00620         LALRealloc( *cell, sizeof(InspiralCell) * (cellEvolution->nTemplateMax + 1000) );
00621       if ( ! cell ) {
00622         ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM );
00623       }
00624       cellEvolution->nTemplateMax +=  1000;
00625     }
00626     
00627     next = cellEvolution->nTemplate;
00628     
00629     theta_min = 0.+.1 +LAL_PI/2.;
00630     theta_max = 2*LAL_PI-.1+LAL_PI/2.;
00631 
00632     theta_min = 0.+.1 ;
00633     theta_max = 2*LAL_PI-.1;
00634 
00635     /* we will search the intersection between the bissectrice of the parameter space and
00636     the ellipse which crosses the center of the ellipses next to this point. Such an ellipse 
00637     has semi axes scaled by sqrt(3).*/
00638     t0 = (*cell)[headId].t0;
00639     t3 = (*cell)[headId].t3;
00640     a  = dx0 * sqrt(3.);
00641     b  = dx1 * sqrt(3.);
00642     c = cos(theta);
00643     s = sin(theta);    
00644 
00645 
00646     iteration = 1;
00647     while (fabs(theta_max-theta_min)>(.1/180.*LAL_PI) && iteration<20)
00648     {
00649       /*for a given angle, what is the ellipse point whivh is the closest to the bissectrice?*/
00650       theta_int = (theta_max + theta_min)/2.;
00651 
00652       xr_int = a*cos(theta_int);
00653       yr_int = b*sin(theta_int);
00654       
00655       /*here are the coordinates of the point we are looking at, which stans on an ellipse of semi axis scaled by sqrt(3)
00656       (suppose to cross all relevant template center)*/
00657       x_int = xr_int *c - yr_int * s +t0;
00658       y_int = xr_int *s + yr_int * c +t3;
00659                   
00660       /* how far this point is far away of the bissectrice ? */
00661       dy = y_int -  XLALInspiralBissectionLine(x_int, gridParam->fLower, gridParam->mMin,gridParam->mMax);
00662       /* which direction shall we go for the dichotomy ? */     
00663       if (flag==0){
00664         if (dy>0 )
00665           theta_max = theta_int;
00666         else
00667           theta_min = theta_int;
00668       }
00669       else{
00670         if (dy>0 )
00671           theta_min = theta_int;
00672         else
00673           theta_max = theta_int;
00674       }
00675       iteration++;
00676     }
00677 
00678     /* let us save this new cell coordinate  */
00679     
00680     (*cell)[next].t0   = x_int;
00681     (*cell)[next].t3   = y_int;
00682 
00683      /*special case when the new position is outside the parameter space requested. */
00684     if ( (*cell)[next].t0  > gridParam->x0Max ){
00685       (*cell)[next].t0 = gridParam->x0Max;
00686       (*cell)[next].t3 = XLALInspiralBissectionLine(gridParam->x0Max, gridParam->fLower, gridParam->mMin,gridParam->mMax);
00687     }
00688 
00689     if ( (*cell)[next].t3  > gridParam->x1Max ){
00690       (*cell)[next].t0 = gridParam->x0Max;
00691       (*cell)[next].t3 = XLALInspiralBissectionLine(gridParam->x0Max, gridParam->fLower, gridParam->mMin,gridParam->mMax);
00692     }
00693 
00694     if ( (*cell)[next].t0  < gridParam->x0Min ){
00695           (*cell)[next].t0 = gridParam->x0Min;
00696           (*cell)[next].t3 = XLALInspiralBissectionLine(gridParam->x0Min, gridParam->fLower, gridParam->mMin,gridParam->mMax);
00697     }
00698 
00699     /*Finally, we initialise the cell properly*/
00700     LALInitHexagonalBank(status->statusPtr,  cell,  next, 
00701                 moments, paramsIn, gridParam, cellEvolution, cellList);
00702     /* and change the size of the population accordingly*/
00703     cellEvolution->nTemplate++;
00704 
00705     /* the parent celle can not populate anymore*/
00706     (*cell)[next].status = Sterile;
00707     (cellEvolution->fertile)=cellEvolution->fertile-1;
00708     LALListDelete(cellList, next);
00709     headId=next;
00710     
00711     
00712   }
00713 
00714   /*Similarly fot the first parent. */
00715  (*cell)[headId].status = Sterile;
00716  (cellEvolution->fertile)=cellEvolution->fertile-1;
00717   LALListDelete(cellList, headId);      
00718   DETATCHSTATUSPTR( status );
00719   RETURN ( status );
00720 
00721 }

Generated on Tue Oct 14 02:31:58 2008 for LAL by  doxygen 1.5.2