Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
DetInverseTest.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Teviet Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/**
21 * \file
22 * \ingroup MatrixUtils_h
23 * \author Creighton, T. D.
24 *
25 * \brief Computes the inverse and determinant of a matrix.
26 *
27 * ### Usage ###
28 *
29 * \code
30 * DetInverseTest [-n size | -i infile] [-o outfile] [-v] [-t] [-s] [-d debuglevel]
31 * \endcode
32 *
33 * ### Description ###
34 *
35 * This program computes the inverse and determinant of a square real
36 * matrix using the routines in \ref DetInverse_c.
37 * The following option flags are accepted:
38 * <ul>
39 * <li>[<tt>-n</tt>] Generates a random symmetric
40 * \c size\f$\times\f$\c size metric. If this option is not given,
41 * <tt>-n 3</tt> is assumed. This option (or its default) is
42 * \e overridden by the <tt>-i</tt> option, below.</li>
43 * <li>[<tt>-i</tt>] Reads a matrix from an input file \c infile
44 * using the function <tt>LALSReadVector()</tt>. If the input file is
45 * specified as \c stdin, the data is read from standard input (not a
46 * file named \c stdin).</li>
47 * <li>[<tt>-o</tt>] Writes the determinant and inverse matrix to an
48 * output file \c outfile. If the output file is specified as
49 * \c stdout or \c stderr, the data is written to standard output
50 * or standard error (not to files named \c stdout or \c stderr).</li>
51 * <li>[<tt>-v</tt>] Specifies that the inverse matrix is to be computed
52 * as well the determinant.</li>
53 * <li>[<tt>-t</tt>] Specifies that the computation is to be timed;
54 * timing information is written to \c stderr.</li>
55 * <li>[<tt>-s</tt>] Specifies that the calculations are to be done to
56 * single-precision (\c REAL4) rather than double-precision
57 * (\c REAL8).</li>
58 * <li>[<tt>-d</tt>] Sets the debug level to \c debuglevel. If not
59 * specified, level 0 is assumed.</li>
60 * </ul>
61 *
62 * \par Input format:
63 * If an input file or stream is specified, it
64 * should consist of \f$N\f$ consecutive lines of \f$N\f$ whitespace-separated
65 * numbers, that will be parsed using <tt>LALDReadVector()</tt>, or
66 * <tt>LALSReadVector()</tt> if the <tt>-s</tt> option was given. The data
67 * block may be preceded by blank or comment lines (lines containing no
68 * parseable numbers), but once a parseable number is found, the rest
69 * should follow in a contiguous block. If the lines contain different
70 * numbers of data columns, or if there are fewer lines than columns,
71 * then an error is returned; if there are \e more lines than
72 * columns, then the extra lines are ignored.
73 *
74 * \par Output format:
75 * If an output file or stream is specified,
76 * the input matrix is first written as \f$N\f$ consecutive lines of \f$N\f$
77 * whitespace-separated numbers. This will be followed with a blank
78 * line, then a single number representing the determinant. If the
79 * <tt>-v</tt> option is specified, then another blank line will be
80 * appended to the output, followed by the inverse matrix written as \f$N\f$
81 * lines of \f$N\f$ whitespace-separated numbers.
82 *
83 */
84
85/** \name Error Codes */
86/** @{ */
87#define DETINVERSETESTC_ENORM 0 /**< Normal exit */
88#define DETINVERSETESTC_ESUB 1 /**< Subroutine failed */
89#define DETINVERSETESTC_EARG 2 /**< Error parsing arguments */
90#define DETINVERSETESTC_EMEM 3 /**< Out of memory */
91#define DETINVERSETESTC_EFILE 4 /**< Could not open file */
92#define DETINVERSETESTC_EFMT 5 /**< Bad input file format */
93/** @} */
94
95
96
97
98/** \cond DONT_DOXYGEN */
99#define DETINVERSETESTC_MSGENORM "Normal exit"
100#define DETINVERSETESTC_MSGESUB "Subroutine failed"
101#define DETINVERSETESTC_MSGEARG "Error parsing arguments"
102#define DETINVERSETESTC_MSGEMEM "Out of memory"
103#define DETINVERSETESTC_MSGEFILE "Could not open file"
104#define DETINVERSETESTC_MSGEFMT "Bad input file format"
105
106
107#include <math.h>
108#include <time.h>
109#include <stdlib.h>
110#include <lal/LALStdio.h>
111#include <lal/LALStdlib.h>
112#include <lal/AVFactories.h>
113#include <lal/StreamInput.h>
114#include <lal/Random.h>
115#include <lal/MatrixUtils.h>
116
117/* Default parameter settings. */
118#define SIZE 3
119
120/* Usage format string. */
121#define USAGE "Usage: %s [-n size | -i infile] [-o outfile]\n" \
122"\t[-v] [-t] [-s] [-d debuglevel]\n"
123
124/* Macros for printing errors and testing subroutines. */
125#define ERROR( code, msg, statement ) \
126do \
127if ( lalDebugLevel & LALERROR ) \
128{ \
129 LALPrintError( "Error[0] %d: program %s, file %s, line %d, %s\n" \
130 " %s %s\n", (code), *argv, __FILE__, \
131 __LINE__, "$Id$", statement ? \
132 statement : "", (msg) ); \
133} \
134while (0)
135
136#define INFO( statement ) \
137do \
138if ( lalDebugLevel & LALINFO ) \
139{ \
140 LALPrintError( "Info[0]: program %s, file %s, line %d, %s\n" \
141 " %s\n", *argv, __FILE__, __LINE__, \
142 "$Id$", (statement) ); \
143} \
144while (0)
145
146#define WARNING( statement ) \
147do \
148if ( lalDebugLevel & LALWARNING ) \
149{ \
150 LALPrintError( "Warning[0]: program %s, file %s, line %d, %s\n" \
151 " %s\n", *argv, __FILE__, __LINE__, \
152 "$Id$", (statement) ); \
153} \
154while (0)
155
156#define SUB( func, statusptr ) \
157do \
158if ( (func), (statusptr)->statusCode ) \
159{ \
160 ERROR( DETINVERSETESTC_ESUB, DETINVERSETESTC_MSGESUB, \
161 "Function call \"" #func "\" failed:" ); \
162 return DETINVERSETESTC_ESUB; \
163} \
164while (0)
165
166int
167main( int argc, char **argv )
168{
169 static LALStatus stat; /* status structure */
170 int arg; /* command-line argument counter */
171 UINT4 n = SIZE, i, j; /* array size and indecies */
172 CHAR *infile = NULL; /* input filename */
173 CHAR *outfile = NULL; /* output filename */
174 BOOLEAN timing = 0; /* whether -t option was given */
175 BOOLEAN single = 0; /* whether -s option was given */
176 BOOLEAN invert = 0; /* whether -v option was given */
177 REAL4 sDet = 0.0; /* determinant if -s option is given */
178 REAL8 dDet = 0.0; /* determinant if -s option isn't given */
179 REAL4Array *sMatrix = NULL; /* matrix if -s option is given */
180 REAL8Array *dMatrix = NULL; /* matrix if -s option is not given */
181 REAL4Array *sInverse = NULL; /* inverse if -s option is given */
182 REAL8Array *dInverse = NULL; /* inverse if -s option isn't given */
183 UINT4Vector dimLength; /* dimensions used to create matrix */
184 UINT4 dims[2]; /* dimLength.data array */
185 clock_t start = 0, stop = 0; /* start and stop times for timing */
186 FILE *fp = NULL; /* input/output file pointer */
187
188
189 /*******************************************************************
190 * PARSE ARGUMENTS (arg stores the current position) *
191 *******************************************************************/
192
193 arg = 1;
194 while ( arg < argc ) {
195
196 /* Parse matrix size option. */
197 if ( !strcmp( argv[arg], "-n" ) ) {
198 if ( argc > arg + 1 ) {
199 arg++;
200 n = atoi( argv[arg++] );
201 } else {
202 ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
203 LALPrintError( USAGE, *argv );
205 }
206 }
207
208 /* Parse input option. */
209 else if ( !strcmp( argv[arg], "-i" ) ) {
210 if ( argc > arg + 1 ) {
211 arg++;
212 infile = argv[arg++];
213 } else {
214 ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
215 LALPrintError( USAGE, *argv );
217 }
218 }
219
220 /* Parse output option. */
221 else if ( !strcmp( argv[arg], "-o" ) ) {
222 if ( argc > arg + 1 ) {
223 arg++;
224 outfile = argv[arg++];
225 } else {
226 ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
227 LALPrintError( USAGE, *argv );
229 }
230 }
231
232 /* Parse inversion, single-precision, and timing options. */
233 else if ( !strcmp( argv[arg], "-v" ) ) {
234 arg++;
235 invert = 1;
236 }
237 else if ( !strcmp( argv[arg], "-s" ) ) {
238 arg++;
239 single = 1;
240 }
241 else if ( !strcmp( argv[arg], "-t" ) ) {
242 arg++;
243 timing = 1;
244 }
245
246 /* Parse debug level option. */
247 else if ( !strcmp( argv[arg], "-d" ) ) {
248 if ( argc > arg + 1 ) {
249 arg++;
250 }else{
251 ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
252 LALPrintError( USAGE, *argv );
254 }
255 }
256
257 /* Check for unrecognized options. */
258 else {
259 ERROR( DETINVERSETESTC_EARG, DETINVERSETESTC_MSGEARG, 0 );
260 LALPrintError( USAGE, *argv );
262 }
263 } /* End of argument parsing loop. */
264
265
266 /*******************************************************************
267 * GET INPUT MATRIX *
268 *******************************************************************/
269
270 /* Set up array creation vector. */
271 dimLength.length = 2;
272 dimLength.data = dims;
273
274 /* Read input matrix file. */
275 if ( infile ) {
276
277 /* Open input file. */
278 if ( !strcmp( infile, "stdin" ) )
279 fp = stdin;
280 else if ( !( fp = fopen( infile, "r" ) ) ) {
281 ERROR( DETINVERSETESTC_EFILE, "- " DETINVERSETESTC_MSGEFILE, infile );
283 }
284
285 /* Single-precision mode: */
286 if ( single ) {
287 REAL4Vector *vec = NULL; /* parsed input line */
288
289 /* Read first non-comment line and create array. */
290 do {
291 SUB( LALSReadVector( &stat, &vec, fp, 0 ), &stat );
292 } while ( ( n = vec->length ) == 0 );
293 dimLength.data[0] = dimLength.data[1] = n;
294 SUB( LALSCreateArray( &stat, &sMatrix, &dimLength ), &stat );
295 for ( j = 0; j < n; j++ )
296 sMatrix->data[j] = vec->data[j];
297 SUB( LALSDestroyVector( &stat, &vec ), &stat );
298
299 /* Read remaining lines. */
300 for ( i = 1; i < n; i++ ) {
301 SUB( LALSReadVector( &stat, &vec, fp, 1 ), &stat );
302 if ( vec->length != n ) {
303 ERROR( DETINVERSETESTC_EFMT, DETINVERSETESTC_MSGEFMT, 0 );
305 }
306 for ( j = 0; j < n; j++ )
307 sMatrix->data[i*n+j] = vec->data[j];
308 SUB( LALSDestroyVector( &stat, &vec ), &stat );
309 }
310 }
311
312 /* Double-precision mode: */
313 else {
314 REAL8Vector *vec = NULL; /* parsed input line */
315
316 /* Read first non-comment line and create array. */
317 do {
318 SUB( LALDReadVector( &stat, &vec, fp, 0 ), &stat );
319 } while ( ( n = vec->length ) == 0 );
320 dimLength.data[0] = dimLength.data[1] = n;
321 SUB( LALDCreateArray( &stat, &dMatrix, &dimLength ), &stat );
322 for ( j = 0; j < n; j++ )
323 dMatrix->data[j] = vec->data[j];
324 SUB( LALDDestroyVector( &stat, &vec ), &stat );
325
326 /* Read remaining lines. */
327 for ( i = 1; i < n; i++ ) {
328 SUB( LALDReadVector( &stat, &vec, fp, 1 ), &stat );
329 if ( vec->length != n ) {
330 ERROR( DETINVERSETESTC_EFMT, DETINVERSETESTC_MSGEFMT, 0 );
332 }
333 for ( j = 0; j < n; j++ )
334 dMatrix->data[i*n+j] = vec->data[j];
335 SUB( LALDDestroyVector( &stat, &vec ), &stat );
336 }
337 }
338 }
339
340 /* Generate random matrix. */
341 else {
342 RandomParams *params;
343 params = XLALCreateRandomParams( 0 );
344 dimLength.data[0] = dimLength.data[1] = n;
345
346 /* Single-precision mode: */
347 if ( single ) {
348 SUB( LALSCreateArray( &stat, &sMatrix, &dimLength ), &stat );
349 for ( i = 0; i < n; i++ ) {
350 for ( j = 0; j < n; j++ ) {
351 sMatrix->data[i*n+j] = 2.0*XLALUniformDeviate( params ) - 1.0;
352 }
353 }
354 }
355
356 /* Double-precision mode: */
357 else {
358 SUB( LALDCreateArray( &stat, &dMatrix, &dimLength ), &stat );
359 for ( i = 0; i < n; i++ ) {
360 for ( j = 0; j < n; j++ ) {
361 dMatrix->data[i*n+j] = 2.0*(REAL8)( XLALUniformDeviate( params ) ) - 1.0;
362 }
363 }
364 }
365
366 XLALDestroyRandomParams( params );
367 }
368
369 /* Write input matrix to output file. */
370 if ( outfile ) {
371
372 /* Open output file. */
373 if ( !strcmp( outfile, "stdout" ) )
374 fp = stdout;
375 else if ( !strcmp( outfile, "stderr" ) )
376 fp = stderr;
377 else if ( !( fp = fopen( outfile, "r" ) ) ) {
378 ERROR( DETINVERSETESTC_EFILE, "- " DETINVERSETESTC_MSGEFILE, outfile );
380 }
381
382 /* Single-precision mode: */
383 if ( single ) {
384 for ( i = 0; i < n; i++ ) {
385 fprintf( fp, "%16.9e", sMatrix->data[i*n] );
386 for ( j = 1; j < n; j++ )
387 fprintf( fp, " %16.9e", sMatrix->data[i*n+j] );
388 fprintf( fp, "\n" );
389 }
390 }
391
392 /* Double-precision mode: */
393 else {
394 for ( i = 0; i < n; i++ ) {
395 fprintf( fp, "%25.17e", dMatrix->data[i*n] );
396 for ( j = 1; j < n; j++ )
397 fprintf( fp, " %25.17e", dMatrix->data[i*n+j] );
398 fprintf( fp, "\n" );
399 }
400 }
401 }
402
403
404 /*******************************************************************
405 * COMPUTE INVERSE *
406 *******************************************************************/
407
408 if ( timing )
409 start = clock();
410
411 /* Single-precision mode: */
412 if ( single ) {
413 if ( invert ) {
414 SUB( LALSCreateArray( &stat, &sInverse, &dimLength ), &stat );
415 SUB( LALSMatrixInverse( &stat, &sDet, sMatrix, sInverse ),
416 &stat );
417 }
418 }
419
420 /* Double-precision mode: */
421 else {
422 if ( invert ) {
423 SUB( LALDCreateArray( &stat, &dInverse, &dimLength ), &stat );
424 SUB( LALDMatrixInverse( &stat, &dDet, dMatrix, dInverse ),
425 &stat );
426 } else {
427 SUB( LALDMatrixDeterminant( &stat, &dDet, dMatrix ), &stat );
428 }
429 }
430
431 if ( timing ) {
432 stop = clock();
433 fprintf( stderr, "Elapsed time: %.2f s\n",
434 (double)( stop - start )/CLOCKS_PER_SEC );
435 }
436
437 /* Write output. */
438 if ( outfile ) {
439
440 /* Write determinant. */
441 fprintf( fp, "\n" );
442 if ( single )
443 fprintf( fp, "%16.9e\n", sDet );
444 else
445 fprintf( fp, "%25.17e\n", dDet );
446
447 /* Write inverse. */
448 if ( invert ) {
449 fprintf( fp, "\n" );
450 if ( single ) {
451 for ( i = 0; i < n; i++ ) {
452 fprintf( fp, "%16.9e", sInverse->data[i*n] );
453 for ( j = 1; j < n; j++ )
454 fprintf( fp, " %16.9e", sInverse->data[i*n+j] );
455 fprintf( fp, "\n" );
456 }
457 } else {
458 for ( i = 0; i < n; i++ ) {
459 fprintf( fp, "%25.17e", dInverse->data[i*n] );
460 for ( j = 1; j < n; j++ )
461 fprintf( fp, " %25.17e", dInverse->data[i*n+j] );
462 fprintf( fp, "\n" );
463 }
464 }
465 }
466
467 /* Finished output. */
468 if ( fp != stdout && fp != stderr )
469 fclose( fp );
470 }
471
472 /* Clean up and exit. */
473 if ( single ) {
474 SUB( LALSDestroyArray( &stat, &sMatrix ), &stat );
475 if ( invert ) {
476 SUB( LALSDestroyArray( &stat, &sInverse ), &stat );
477 }
478 } else {
479 SUB( LALDDestroyArray( &stat, &dMatrix ), &stat );
480 if ( invert ) {
481 SUB( LALDDestroyArray( &stat, &dInverse ), &stat );
482 }
483 }
485 INFO( DETINVERSETESTC_MSGENORM );
487}
488/** \endcond */
#define DETINVERSETESTC_EARG
Error parsing arguments.
#define DETINVERSETESTC_EFMT
Bad input file format.
#define DETINVERSETESTC_ENORM
Normal exit.
#define DETINVERSETESTC_EFILE
Could not open file.
#define USAGE
Definition: GzipTest.c:27
void LALCheckMemoryLeaks(void)
Definition: LALMalloc.c:784
#define SUB(func, statusptr)
#define ERROR(code, msg, statement)
#define INFO(statement)
#define SIZE
#define fprintf
int main(int argc, char *argv[])
Definition: cache.c:25
void LALSCreateArray(LALStatus *, REAL4Array **, UINT4Vector *)
void LALDCreateArray(LALStatus *, REAL8Array **, UINT4Vector *)
void LALSDestroyArray(LALStatus *, REAL4Array **)
void LALDDestroyArray(LALStatus *, REAL8Array **)
void LALDMatrixInverse(LALStatus *stat, REAL8 *det, REAL8Array *matrix, REAL8Array *inverse)
Definition: DetInverse.c:734
void LALDMatrixDeterminant(LALStatus *stat, REAL8 *det, REAL8Array *matrix)
Definition: DetInverse.c:691
void LALSMatrixInverse(LALStatus *stat, REAL4 *det, REAL4Array *matrix, REAL4Array *inverse)
Definition: DetInverse.c:616
unsigned char BOOLEAN
Boolean logical type, see Headers LAL(Atomic)Datatypes.h for more details.
double REAL8
Double precision real floating-point number (8 bytes).
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint32_t UINT4
Four-byte unsigned integer.
float REAL4
Single precision real floating-point number (4 bytes).
int LALPrintError(const char *fmt,...)
Definition: LALError.c:46
RandomParams * XLALCreateRandomParams(INT4 seed)
Definition: Random.c:102
REAL4 XLALUniformDeviate(RandomParams *params)
Definition: Random.c:146
void XLALDestroyRandomParams(RandomParams *params)
Definition: Random.c:140
void LALDReadVector(LALStatus *status, REAL8Vector **vector, FILE *stream, BOOLEAN strict)
void LALSReadVector(LALStatus *status, REAL4Vector **vector, FILE *stream, BOOLEAN strict)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALSDestroyVector(LALStatus *, REAL4Vector **)
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
Multidimentional array of REAL4, see DATATYPE-Array types for more details.
Definition: LALDatatypes.h:220
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:222
Vector of type REAL4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:145
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:149
Multidimentional array of REAL8, see DATATYPE-Array types for more details.
Definition: LALDatatypes.h:226
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:228
Vector of type REAL8, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:154
REAL8 * data
Pointer to the data array.
Definition: LALDatatypes.h:159
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:158
This structure contains the parameters necessary for generating the current sequence of random number...
Definition: Random.h:86
Vector of type UINT4, see DATATYPE-Vector types for more details.
Definition: LALDatatypes.h:118
UINT4 length
Number of elements in array.
Definition: LALDatatypes.h:122
UINT4 * data
Pointer to the data array.
Definition: LALDatatypes.h:123
FILE * fp
Definition: tconvert.c:105