FlatMeshTest.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton, 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="FlatMeshTestCV">
00021 Author: Creighton, T. D.
00022 $Id: FlatMeshTest.c,v 1.6 2007/06/08 14:41:52 bema Exp $
00023 **************************************************** </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 
00027 \subsection{Program \texttt{FlatMeshTest.c}}
00028 \label{ss:FlatMeshTest.c}
00029 
00030 Creates a template mesh for an arbitrary but constant $n$-dimensional
00031 mismatch metric.
00032 
00033 \subsubsection*{Usage}
00034 \begin{verbatim}
00035 FlatMeshTest [-o outfile] [-d debuglevel] [-m mismatch]
00036              [eigenvectorfile inversefile rangefile]
00037 \end{verbatim}
00038 
00039 \subsubsection*{Description}
00040 
00041 This test program creates a template mesh for a parameter space with a
00042 constant mismatch metric.  The following option flags are accepted:
00043 \begin{itemize}
00044 \item[\texttt{-o}] Writes the output mesh to the file \verb@outfile@.
00045 \item[\texttt{-d}] Sets the debug level to \verb@debuglevel@.
00046 \item[\texttt{-m}] Sets the maximum allowed mismatch to
00047 \verb@mismatch@, a positive number less than 1.
00048 \end{itemize}
00049 Once the above options are processed, any remaining command-line
00050 arguments must be the names of three files containing information
00051 about the eigenvectors of the metric and the desired search range;
00052 these files are described below.  They are read using the function
00053 \verb@LALSReadVectorSequence()@.  If the \verb@-o@ option is not
00054 specified, results are written to \verb@stdout@; if other options or
00055 arguments are not specified, the information is taken from
00056 \verb@#define@d constants.
00057 
00058 \paragraph{\texttt{eigenvectorfile}:} This file contains the
00059 eigenvectors of the $n$-dimensional mismatch metric $\mathsf{g}_{ab}$
00060 described in \verb@FlatMesh.h@.  The file format is simply $n$ lines
00061 each containing $n$ whitespace-separated numbers in any standard
00062 floating-point format.  Each line lists the components of a particular
00063 eigenvector; the eigenvector must be normalized so that its squared
00064 magnitude is 1 over the corresponding eigenvalue.
00065 
00066 \paragraph{\texttt{inversefile}:} This file also consists of $n$ lines
00067 each with $n$ floating-point numbers.  It is simply the matrix inverse
00068 of the contents of \verb@eigenvectorfile@ taken as an $n\times n$
00069 matrix.
00070 
00071 \paragraph{\texttt{rangefile}:} This file consists of two lines of $n$
00072 floating-point numbers; these specify two opposite corners of a
00073 rectilinear region in parameter space to be covered by the mesh.
00074 Additional lines will be ignored.
00075 
00076 \subsubsection*{Exit codes}
00077 ****************************************** </lalLaTeX><lalErrTable> */
00078 #define FLATMESHTESTC_ENORM 0
00079 #define FLATMESHTESTC_ESUB  1
00080 #define FLATMESHTESTC_EARG  2
00081 #define FLATMESHTESTC_EMEM  3
00082 #define FLATMESHTESTC_EDIM  4
00083 #define FLATMESHTESTC_ELEN  5
00084 #define FLATMESHTESTC_EFILE 6
00085 
00086 #define FLATMESHTESTC_MSGENORM "Normal exit"
00087 #define FLATMESHTESTC_MSGESUB  "Subroutine failed"
00088 #define FLATMESHTESTC_MSGEARG  "Error parsing arguments"
00089 #define FLATMESHTESTC_MSGEMEM  "Memory allocation error"
00090 #define FLATMESHTESTC_MSGEDIM  "Inconsistent parameter space dimension"
00091 #define FLATMESHTESTC_MSGELEN  "Too few points specified"
00092 #define FLATMESHTESTC_MSGEFILE "Could not open file"
00093 /******************************************** </lalErrTable><lalLaTeX>
00094 
00095 \subsubsection*{Algorithm}
00096 
00097 For the most part this test program simply reads the input arguments
00098 and files, passes them to the function \verb@LALCreateFlatMesh()@
00099 using \verb@LALRectIntersect()@ to define the parameter-space
00100 boundary, and prints the resulting mesh.  However, there are two
00101 additional bits of processing that deserve comment.
00102 
00103 The rows of the matrix in \verb@eigenvectorfile@ are already of the
00104 form $\mathsf{e}^i_{(j)}/\sqrt{\lambda_{(j)}}$, as discussed in
00105 \verb@FlatMesh.h@.  To get the proper orthonormalized transformation
00106 matrix, one must simply multiply each element by
00107 $2m_\mathrm{thresh}/\sqrt{n}$.  Similarly, the inverse transformation
00108 matrix elements should be \emph{divided} by this number.
00109 
00110 In order to ensure \emph{complete} coverage of the desired parameter
00111 space, \verb@FlatMeshTest@ extends the boundaries of the rectilinear
00112 region specified in \verb@rangefile@ to include any mesh point whose
00113 patch volume touches on the desired search region.  If
00114 $\mathsf{M}^a{}_b$ is the renormalized transformation matrix described
00115 above, then the sum of the magnitudes of the components along a
00116 column, $\Delta x_j=\sum_i|M^i{}_j|$ represents the maximum extent of
00117 a mesh point's patch in the $j^\mathrm{th}$ dimension.  The algorithm
00118 in \verb@FlatMeshTest@ extends the rectangular search region by half
00119 this amount in each direction to ensure that any patch touching on the
00120 desired search volume is included.  This assumes that the boundary of
00121 the search region is ``soft''; i.e.\ that no harm will come of
00122 stepping slightly outside it.
00123 
00124 \subsubsection*{Uses}
00125 \begin{verbatim}
00126 lalDebugLevel
00127 LALPrintError()                 LALCheckMemoryLeaks()
00128 LALCalloc()                     LALFree()
00129 LALCreateFlatMesh()             LALSReadVectorSequence()
00130 LALSCreateVectorSequence()      LALSDestroyVectorSequence()
00131 LALSCreateVector()              LALSDestroyVector()
00132 \end{verbatim}
00133 
00134 \subsubsection*{Notes}
00135 
00136 \vfill{\footnotesize\input{FlatMeshTestCV}}
00137 
00138 ******************************************************* </lalLaTeX> */
00139 
00140 #include <math.h>
00141 #include <stdlib.h>
00142 #include <lal/LALStdio.h>
00143 #include <lal/FileIO.h>
00144 #include <lal/LALStdlib.h>
00145 #include <lal/AVFactories.h>
00146 #include <lal/SeqFactories.h>
00147 #include <lal/FlatMesh.h>
00148 #include <lal/StreamInput.h>
00149 
00150 NRCSID(FLATMESHTESTC,"$Id: FlatMeshTest.c,v 1.6 2007/06/08 14:41:52 bema Exp $");
00151 
00152 /* Default parameter settings. */
00153 int lalDebugLevel = 0;
00154 #define MISMATCH 0.1
00155 #define DIM 2
00156 REAL4 defaultMatrix[] = { 1.0, 0.0, 0.0, 1.0 };
00157 REAL4 defaultMatrixInv[] = { 1.0, 0.0, 0.0, 1.0 };
00158 REAL4 defaultCorners[] = { 0.0, 0.0, 0.5, 1.0 };
00159 
00160 /* Usage format string. */
00161 #define USAGE "Usage: %s [-o outfile] [-d debuglevel] [-m mismatch]\n\
00162                     [eigenvectorfile inversefile rangefile]\n"
00163 
00164 /* Macros for printing errors and testing subroutines. */
00165 #define ERROR( code, msg, statement )                                \
00166 if ( lalDebugLevel & LALERROR )                                      \
00167 {                                                                    \
00168   LALPrintError( "Error[0] %d: program %s, file %s, line %d, %s\n"   \
00169                  "        %s %s\n", (code), *argv, __FILE__,         \
00170                  __LINE__, FLATMESHTESTC, statement ? statement : \
00171                  "", (msg) );                                        \
00172 }                                                                    \
00173 else (void)(0)
00174 
00175 #define INFO( statement )                                            \
00176 if ( lalDebugLevel & LALINFO )                                       \
00177 {                                                                    \
00178   LALPrintError( "Info[0]: program %s, file %s, line %d, %s\n"       \
00179                  "        %s\n", *argv, __FILE__, __LINE__,          \
00180                  FLATMESHTESTC, (statement) );                    \
00181 }                                                                    \
00182 else (void)(0)
00183 
00184 #define SUB( func, statusptr )                                       \
00185 if ( (func), (statusptr)->statusCode )                               \
00186 {                                                                    \
00187   ERROR( FLATMESHTESTC_ESUB, FLATMESHTESTC_MSGESUB,            \
00188          "Function call \"" #func "\" failed:" );                    \
00189   return FLATMESHTESTC_ESUB;                                      \
00190 }                                                                    \
00191 else (void)(0)
00192 
00193 /* A global pointer for debugging. */
00194 #ifndef NDEBUG
00195 char *lalWatch;
00196 #endif
00197 
00198 int
00199 main(int argc, char **argv)
00200 {
00201   INT4 arg;
00202   UINT4 dim;                 /* dimension of parameter space */
00203   static LALStatus stat;     /* top-level status structure */
00204   CHAR *outfile = NULL;      /* name of output file */
00205   CHAR *eigenfile = NULL;    /* name of eigenvector matrix file */
00206   CHAR *inversefile = NULL;  /* name of inverse matrix file */
00207   CHAR *rangefile = NULL;    /* name of parameter range file */
00208   REAL4 mismatch = MISMATCH; /* maximum mismatch level */
00209   REAL4VectorSequence *matrix = NULL;    /* tranformation matrix */
00210   REAL4VectorSequence *matrixInv = NULL; /* inverse tranformation */
00211   REAL4VectorSequence *corners = NULL;   /* corners of serach region */
00212   REAL4VectorSequence *mesh = NULL;      /* mesh of parameter values */
00213   FILE *fp;                  /* input/output file pointer */
00214 
00215   /* Parse argument list.  arg stores the current position. */
00216   arg = 1;
00217   while ( arg < argc ) {
00218     /* Parse output file option. */
00219     if ( !strcmp( argv[arg], "-o" ) ) {
00220       if ( argc > arg + 1 ) {
00221         arg++;
00222         outfile = argv[arg++];
00223       }else{
00224         ERROR( FLATMESHTESTC_EARG, FLATMESHTESTC_MSGEARG, 0 );
00225         LALPrintError( USAGE, *argv );
00226         return FLATMESHTESTC_EARG;
00227       }
00228     }
00229     /* Parse debug level option. */
00230     else if ( !strcmp( argv[arg], "-d" ) ) {
00231       if ( argc > arg + 1 ) {
00232         arg++;
00233         lalDebugLevel = atoi( argv[arg++] );
00234       }else{
00235         ERROR( FLATMESHTESTC_EARG, FLATMESHTESTC_MSGEARG, 0 );
00236         LALPrintError( USAGE, *argv );
00237         return FLATMESHTESTC_EARG;
00238       }
00239     }
00240     /* Parse mismatch level option. */
00241     else if ( !strcmp( argv[arg], "-m" ) ) {
00242       if ( argc > arg + 1 ) {
00243         arg++;
00244         mismatch = fabs( atof( argv[arg++] ) );
00245       }else{
00246         ERROR( FLATMESHTESTC_EARG, FLATMESHTESTC_MSGEARG, 0 );
00247         LALPrintError( USAGE, *argv );
00248         return FLATMESHTESTC_EARG;
00249       }
00250     }
00251     /* Check for unrecognized options. */
00252     else if ( argv[arg][0] == '-' ) {
00253       ERROR( FLATMESHTESTC_EARG, FLATMESHTESTC_MSGEARG, 0 );
00254       LALPrintError( USAGE, *argv );
00255       return FLATMESHTESTC_EARG;
00256     }
00257     /* Parse remaining parameters. */
00258     else {
00259       if ( argc > arg + 2 ) {
00260         eigenfile = argv[arg++];
00261         inversefile = argv[arg++];
00262         rangefile = argv[arg++];
00263       }else{
00264         ERROR( FLATMESHTESTC_EARG, FLATMESHTESTC_MSGEARG, 0 );
00265         LALPrintError( USAGE, *argv );
00266         return FLATMESHTESTC_EARG;
00267       }
00268     }
00269   } /* End of argument parsing loop. */
00270 
00271   /* If input files have been specified... */
00272   if ( eigenfile ) {
00273 
00274     /* Read input files into vector sequences. */
00275     if ( !( fp = LALOpenDataFile( eigenfile ) ) ) {
00276       ERROR( FLATMESHTESTC_EFILE, "- " FLATMESHTESTC_MSGEFILE,
00277              eigenfile );
00278       return FLATMESHTESTC_EFILE;
00279     }
00280     SUB( LALSReadVectorSequence( &stat, &matrix, fp ), &stat );
00281     fclose( fp );
00282     if ( !( fp = LALOpenDataFile( inversefile ) ) ) {
00283       ERROR( FLATMESHTESTC_EFILE, "- " FLATMESHTESTC_MSGEFILE,
00284              inversefile );
00285       return FLATMESHTESTC_EFILE;
00286     }
00287     SUB( LALSReadVectorSequence( &stat, &matrixInv, fp ), &stat );
00288     fclose( fp );
00289     if ( !( fp = LALOpenDataFile( rangefile ) ) ) {
00290       ERROR( FLATMESHTESTC_EFILE, "- " FLATMESHTESTC_MSGEFILE,
00291              rangefile );
00292       return FLATMESHTESTC_EFILE;
00293     }
00294     SUB( LALSReadVectorSequence( &stat, &corners, fp ), &stat );
00295     fclose( fp );
00296 
00297     /* Determine dimension, and check consistency. */
00298     dim = matrix->length;
00299     if ( matrix->vectorLength != dim ) {
00300       ERROR( FLATMESHTESTC_EDIM, FLATMESHTESTC_MSGEDIM,
00301              eigenfile );
00302       return FLATMESHTESTC_EDIM;
00303     }
00304     if ( ( matrixInv->length != dim ) ||
00305          ( matrixInv->vectorLength != dim ) ) {
00306       ERROR( FLATMESHTESTC_EDIM, FLATMESHTESTC_MSGEDIM, inversefile );
00307       return FLATMESHTESTC_EDIM;
00308     }
00309     if ( corners->vectorLength != dim ) {
00310       ERROR( FLATMESHTESTC_EDIM, FLATMESHTESTC_MSGEDIM, rangefile );
00311       return FLATMESHTESTC_EDIM;
00312     }
00313     if ( corners->length < 2 ) {
00314       ERROR( FLATMESHTESTC_ELEN, FLATMESHTESTC_MSGELEN, rangefile );
00315       return FLATMESHTESTC_ELEN;
00316     }
00317 
00318   } else {
00319     /* If no input files are specified, get data from #defined
00320        constants.  No consistency checks are required. */
00321     CreateVectorSequenceIn in;
00322     dim = DIM;
00323     in.length = dim;
00324     in.vectorLength = dim;
00325     SUB( LALSCreateVectorSequence( &stat, &matrix, &in ), &stat );
00326     memcpy( matrix->data, defaultMatrix, dim*dim*sizeof(REAL4) );
00327     SUB( LALSCreateVectorSequence( &stat, &matrixInv, &in ), &stat );
00328     memcpy( matrixInv->data, defaultMatrixInv, dim*dim*sizeof(REAL4) );
00329     in.length = 2;
00330     SUB( LALSCreateVectorSequence( &stat, &corners, &in ), &stat );
00331     memcpy( corners->data, defaultCorners, 2*dim*sizeof(REAL4) );
00332   }
00333 
00334   /* Apply mismatch threshold to the transformation matrices. */
00335   {
00336     UINT4 i;
00337     REAL4 adjust = 2.0*mismatch/sqrt( (REAL4)(dim) );
00338     REAL4 *data;  /* pointer to matrix data */
00339 
00340     i = matrix->length*matrix->vectorLength;
00341     data = matrix->data;
00342     while ( i-- )
00343       *(data++) *= adjust;
00344 
00345     adjust = 1.0/adjust;
00346     i = matrixInv->length*matrixInv->vectorLength;
00347     data = matrixInv->data;
00348     while ( i-- )
00349       *(data++) *= adjust;
00350   }
00351 
00352   /* Extend the range boundary to ensure edge coverage. */
00353   {
00354     UINT4 i, j;    /* indecies */
00355     INT2 direct;  /* sign of direction from first corner to second */
00356     REAL4 *data;  /* pointer to matrix data */
00357     REAL4 *width; /* maximum width of a patch in each dimension */
00358 
00359     /* Allocate local memory. */
00360     width = (REAL4 *)LALCalloc( dim, sizeof(REAL4) );
00361     if ( !width ) {
00362       ERROR( FLATMESHTESTC_EMEM, FLATMESHTESTC_MSGEMEM, 0 );
00363       return FLATMESHTESTC_EMEM;
00364     }
00365 
00366     /* Determine patch width. */
00367     for ( data = matrix->data, i = 0; i < dim; i++ )
00368       for ( j = 0; j < dim; j++, data++ )
00369         width[j] += fabs( *data );
00370 
00371     /* Extend each corner by 0.5*width in the appropriate
00372        direction. */
00373     for ( data = corners->data, i = 0; i < dim; i++, data++ ) {
00374       direct = ( data[0] < data[dim] ) ? -1 : 1;
00375       data[0] += 0.5*direct*width[i];
00376       data[dim] -= 0.5*direct*width[i];
00377     }
00378 
00379     /* Free local memory. */
00380     LALFree( width );
00381   }
00382 
00383   /* Generate mesh using LALFlatMesh() and LALRectIntersect(). */
00384   {
00385     /* Set up parameter structure for LALFlatMesh. */
00386     static FlatMeshParamStruc params;
00387     params.matrix = matrix;
00388     params.matrixInv = matrixInv;
00389     params.controlPoints = corners;
00390     params.intersection = LALRectIntersect;
00391     SUB( LALSCreateVector( &stat, &(params.xMin), dim ), &stat );
00392     memcpy( params.xMin->data, corners->data, dim*sizeof(REAL4) );
00393     SUB( LALSCreateVector( &stat, &(params.xMax), dim ), &stat );
00394     memcpy( params.xMax->data, corners->data+dim, dim*sizeof(REAL4) );
00395 
00396     /* Compute the mesh, and clean up local memory. */
00397     SUB( LALCreateFlatMesh( &stat, &mesh, &params ), &stat );
00398     SUB( LALSDestroyVector( &stat, &(params.xMin) ), &stat );
00399     SUB( LALSDestroyVector( &stat, &(params.xMax) ), &stat );
00400     SUB( LALSDestroyVectorSequence( &stat, &matrix ), &stat );
00401     SUB( LALSDestroyVectorSequence( &stat, &matrixInv ), &stat );
00402     SUB( LALSDestroyVectorSequence( &stat, &corners ), &stat );
00403   }
00404 
00405   /* Print result. */
00406   {
00407     UINT4 i;
00408     REAL4 *data;
00409     if ( outfile ) {
00410       if ( !( fp = fopen( outfile, "w" ) ) ) {
00411         ERROR( FLATMESHTESTC_EFILE, "- " FLATMESHTESTC_MSGEFILE,
00412             outfile );
00413         return FLATMESHTESTC_EFILE;
00414       }
00415     } else
00416       fp = stdout;
00417     i = mesh->length;
00418     data = mesh->data;
00419     while ( i-- ) {
00420       UINT4 j = mesh->vectorLength;
00421       while ( j-- )
00422         fprintf( fp, "%10.3e ", *(data++) );
00423       fprintf( fp, "\n" );
00424     }
00425     if ( outfile )
00426       fclose( fp );
00427   }
00428 
00429   /* Free the mesh, and exit. */
00430   SUB( LALSDestroyVectorSequence( &stat, &mesh ), &stat );
00431   LALCheckMemoryLeaks();
00432   INFO( FLATMESHTESTC_MSGENORM );
00433   return FLATMESHTESTC_ENORM;
00434 }

Generated on Tue Oct 7 02:39:43 2008 for LAL by  doxygen 1.5.2