Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

gnn_filewriter.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file gnn_filewriter.c
00003  *  @brief gnn_filewriter Implementation.
00004  *
00005  *  @date   : 28-09-03 18:10
00006  *  @author : Pedro Ortega C. <peortega@dcc.uchile.cl>
00007  *  Copyright  2003  Pedro Ortega C.
00008  ****************************************************************************/
00009 /*
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 
00025 
00026 
00027 /**
00028  * @defgroup gnn_filewriter_doc gnn_filewriter : File Output Device.
00029  * @ingroup gnn_output_doc
00030  * @brief Writes outputs sequentially to a file.
00031  *
00032  * The \ref gnn_filewriter implements a sequential file output device. The
00033  * output patterns are written to a given file stream.
00034  *
00035  * This is the datatype for a filewriter. It extends the basic
00036  * \ref gnn_output structure to include the additional pointer
00037  * to the output samples matrix, and a vector view.
00038  *
00039  * A filewriter, when created, opens the given file in ASCII mode.
00040  * Alternativelly, you can provide an already opened file pointer. After
00041  * that, it writes the given samples one after another (line per line) to
00042  * the opened output stream.
00043  *
00044  * By default, vectors are written line-wise, with the format "%g\t" to
00045  * seperate the elements (of the printed vector). A new format string can
00046  * be given, of course.
00047  *
00048  * Additionally, a prefix and a postfix format string can be used.
00049  * The are pre- and post-concatenated to the string containing the vector's
00050  * elements.
00051  *
00052  * As an example, the following output will be produced without pre- and
00053  * postfix strings:
00054  *
00055  * \code
00056  * 12.345   3.45     8
00057  * 0.1247   3.387    0.001
00058  * 78.56    5        89.23
00059  * 12.2356  0.147    0.235
00060  * \endcode
00061  *
00062  * Using the prefix "Pattern %d : [" and postfix "]", the same samples will
00063  * be printed as:
00064  *
00065  * \code
00066  * Pattern 0 : [12.345   3.45     8 ]
00067  * Pattern 1 : [0.1247   3.387    0.001 ]
00068  * Pattern 2 : [78.56    5        89.23 ]
00069  * Pattern 3 : [12.2356  0.147    0.235 ]
00070  * \endcode
00071  *
00072  * Please note that the prefix contains a "%d" substring. This is the one and
00073  * only allowed format command for the prefix, which will be replaced by the
00074  * number of the output sample to be written.
00075  */
00076 
00077 
00078 
00079 /******************************************/
00080 /* Include Files                          */
00081 /******************************************/
00082 
00083 #include <stdio.h>
00084 #include <string.h>
00085 #include "gnn_filewriter.h"
00086 
00087 
00088 
00089 /******************************************/
00090 /* Static Declaration                     */
00091 /******************************************/
00092 
00093 /**
00094  * @brief The datatype for a filewriter.
00095  * @ingroup gnn_filewriter_doc
00096  *
00097  */
00098 typedef struct _gnn_filewriter gnn_filewriter;
00099 
00100 struct _gnn_filewriter
00101 {
00102     gnn_output set;
00103     FILE *fp;        /*< The output file pointer. */
00104     int   fileowner; /*< 1 if the \ref gnn_filewriter owns the file. */
00105     char *format;    /*< The printing format for each vector component. */
00106     char *prefix;    /*< The prefix. */
00107     char *postfix;   /*< The postfix. */
00108 };
00109 
00110 static int
00111 gnn_filewriter_put (gnn_output *set, size_t k, const gsl_vector *v);
00112 
00113 static void
00114 gnn_filewriter_destroy (gnn_output *set);
00115 
00116 
00117 
00118 /******************************************/
00119 /* Static Implementation                  */
00120 /******************************************/
00121 
00122 /**
00123  * @brief The "put" function.
00124  * @ingroup gnn_filewriter_doc
00125  *
00126  * @param  set A pointer to a \ref gnn_filewriter.
00127  * @param  k   The index of the pattern to be stored.
00128  * @param  v   A pointer to the output vector to be stored.
00129  * @return Returns 0 if suceeded.
00130  */
00131 static int
00132 gnn_filewriter_put (gnn_output *set, size_t k, const gsl_vector *v)
00133 {
00134     size_t i;
00135     gnn_filewriter *fset;
00136     
00137     /* get view */
00138     fset = (gnn_filewriter *) set;
00139 
00140     /* print prefix */
00141     if (fset->prefix)
00142         fprintf (fset->fp, fset->prefix, k);
00143 
00144     /* printf output vector */
00145     for (i=0; i<v->size; ++i)
00146     {
00147         fprintf (fset->fp, fset->format, gsl_vector_get (v, i));
00148     }
00149     
00150     /* print postfix */
00151     if (fset->postfix)
00152         fprintf (fset->fp, fset->prefix, k);
00153 
00154     /* next line */
00155     fprintf (fset->fp, "\n");
00156 
00157     return 0;
00158 }
00159 
00160 /**
00161  * @brief The "destroy" function.
00162  * @ingroup gnn_filewriter_doc
00163  *
00164  * @param  set A pointer to a \ref gnn_filewriter.
00165  * @param  k   The index of the pattern to be stored.
00166  * @param  v   A pointer to the output vector to be stored.
00167  * @return Returns 0 if suceeded.
00168  */
00169 static void
00170 gnn_filewriter_destroy (gnn_output *set)
00171 {
00172     gnn_filewriter *fset;
00173     
00174     assert (set != NULL);
00175     
00176     fset = (gnn_filewriter *) set;
00177     
00178     if (fset->format != NULL)
00179         free (fset->format);
00180     if (fset->prefix != NULL)
00181         free (fset->prefix);
00182     if (fset->postfix != NULL)
00183         free (fset->postfix);
00184     if (fset->fileowner && fset->fp != NULL)
00185         fclose (fset->fp);
00186 }
00187 
00188 
00189 
00190 /******************************************/
00191 /* Public Interface                       */
00192 /******************************************/
00193 
00194 /**
00195  * @brief Builds a new filewriter device.
00196  * @ingroup gnn_filewriter_doc
00197  *
00198  * This function creates a new \ref gnn_filewriter device with the
00199  * given opened file pointer. When destroyed, the stream won't be closed.
00200  *
00201  * @param  fp A valid and opened file pointer.
00202  * @return Returns a pointer to a new \ref gnn_filewriter.
00203  */
00204 gnn_output *
00205 gnn_filewriter_new (FILE *fp)
00206 {
00207     int status;
00208     gnn_output *set;
00209     gnn_filewriter *fset;
00210 
00211     /* check filepointer */
00212     if (fp == NULL)
00213     {
00214         GSL_ERROR_VAL ("a valid file pointer should be given",
00215                        GSL_EINVAL, NULL);
00216     }
00217 
00218     /* allocate */
00219     fset = (gnn_filewriter *) calloc (sizeof (*fset), 1);
00220     if (fset == NULL)
00221     {
00222         GSL_ERROR_VAL ("could not allocate memory for gnn_filewriter",
00223                        GSL_ENOMEM, NULL);
00224     }
00225 
00226     /* get view */
00227     set = (gnn_output *) fset;
00228 
00229     /* initialize */
00230     status = gnn_output_stream_init (set, NULL,
00231                                           gnn_filewriter_put,
00232                                           gnn_filewriter_destroy);
00233     if (status)
00234     {
00235         gnn_output_destroy (set);
00236         GSL_ERROR_VAL ("could not initialize gnn_filewriter",
00237                        GSL_EFAILED, NULL);
00238     }
00239 
00240     /* set fields */
00241     fset->fp = fp;
00242     fset->fileowner = 0;
00243     fset->format  = strdup ("%g\t");
00244     fset->prefix  = NULL;
00245     fset->postfix = NULL;
00246 
00247     return set;
00248 }
00249 
00250 /**
00251  * @brief Builds a new filewriter device with a given filename.
00252  * @ingroup gnn_filewriter_doc
00253  *
00254  * This function creates a new \ref gnn_filewriter device. It opens the
00255  * file \a filename for printing. The \ref gnn_filewriter is the owner of
00256  * the file and closes it when destroyed.
00257  *
00258  * @param  filename A string containing the file name for printing.
00259  * @return Returns a pointer to a new \ref gnn_filewriter.
00260  */
00261 gnn_output *
00262 gnn_filewriter_with_file_new (const char *filename)
00263 {
00264     int status;
00265     FILE *fp;
00266     gnn_output *set;
00267     gnn_filewriter *fset;
00268 
00269     /* check filename */
00270     if (filename == NULL)
00271     {
00272         GSL_ERROR_VAL ("a valid file pointer should be given",
00273                        GSL_EINVAL, NULL);
00274     }
00275 
00276     /* open file */
00277     fp = fopen (filename, "w");
00278     if (fp == NULL)
00279     {
00280         GSL_ERROR_VAL ("couldn't open the given file", GSL_EINVAL, NULL);
00281     }
00282 
00283     /* create filewriter */
00284     set = gnn_filewriter_new (fp);
00285 
00286     /* set owner field */
00287     fset = (gnn_filewriter *) set;
00288     fset->fileowner = 1;
00289 
00290     return set;
00291 }
00292 
00293 /**
00294  * @brief Sets a new print format.
00295  * @ingroup gnn_filewriter_doc
00296  *
00297  * This function sets a new print format for the vector elements of the
00298  * samples. The default is \c "%g\t", which separates the elements by tabs.
00299  * The \em format specifier should contain a valid double-precision
00300  * specifier, like \c "%f ", \c "%e " or \c "%g " (do not forget to include
00301  * a separator).
00302  *
00303  * @param  set A pointer to a \ref gnn_filewriter.
00304  * @param  fmt A format string for double precision values.
00305  * @return Returns a pointer to a new \ref gnn_filewriter.
00306  */
00307 int
00308 gnn_filewriter_set_format (gnn_output *set, const char *fmt)
00309 {
00310     gnn_filewriter *fset;
00311 
00312     assert (set != NULL);
00313 
00314     if (fmt == NULL)
00315     {
00316         GSL_ERROR ("invalid format string", GSL_EINVAL);
00317     }
00318 
00319     fset = (gnn_filewriter *) set;
00320 
00321     if (fset->format != NULL)
00322         free (fset->format);
00323     fset->format = strdup (fmt);
00324 
00325     return 0;
00326 }
00327 
00328 /**
00329  * @brief Gets the print format.
00330  * @ingroup gnn_filewriter_doc
00331  *
00332  * This function returns a pointer to the currently used vector elements
00333  * print format.
00334  *
00335  * @param  fmt A format string for double precision values.
00336  * @return Returns a pointer to a new \ref gnn_filewriter.
00337  */
00338 const char *
00339 gnn_filewriter_get_format (gnn_output *set)
00340 {
00341     gnn_filewriter *fset;
00342 
00343     assert (set != NULL);
00344 
00345     fset = (gnn_filewriter *) set;
00346 
00347     return fset->format;
00348 }
00349 
00350 /**
00351  * @brief Sets a new printing prefix.
00352  * @ingroup gnn_filewriter_doc
00353  *
00354  * This function sets a new printing prefix, which will be prepended to every
00355  * printed output vector. This string can contain at most one integer
00356  * \em format specifier, like \c "N %d :". The placeholder will be filled
00357  * with the number of the written pattern.
00358  *
00359  * @param  set A pointer to a \ref gnn_filewriter.
00360  * @param  prefix A prefix format string or NULL.
00361  * @return Returns 0 if succeeded.
00362  */
00363 int
00364 gnn_filewriter_set_prefix (gnn_output *set, const char *prefix)
00365 {
00366     gnn_filewriter *fset;
00367 
00368     assert (set != NULL);
00369 
00370     fset = (gnn_filewriter *) set;
00371 
00372     if (fset->prefix != NULL)
00373         free (fset->prefix);
00374     fset->prefix = NULL;
00375     if (prefix != NULL)
00376         fset->prefix = strdup (prefix);
00377 
00378     return 0;
00379 }
00380 
00381 /**
00382  * @brief Gets the prefix format string.
00383  * @ingroup gnn_filewriter_doc
00384  *
00385  * This function returns a pointer to the currently used prefix string.
00386  *
00387  * @param  set A pointer to a \ref gnn_filewriter.
00388  * @return Returns a pointer to the prefix or NULL.
00389  */
00390 const char *
00391 gnn_filewriter_get_prefix (gnn_output *set)
00392 {
00393     gnn_filewriter *fset;
00394 
00395     assert (set != NULL);
00396 
00397     fset = (gnn_filewriter *) set;
00398 
00399     return fset->prefix;
00400 }
00401 
00402 /**
00403  * @brief Sets a new printing postfix.
00404  * @ingroup gnn_filewriter_doc
00405  *
00406  * This function sets a new printing postfix, which will be postpended to every
00407  * printed output vector. This string can contain at most one integer
00408  * \em format specifier, like \c "N %d :". The placeholder will be filled
00409  * with the number of the written pattern.
00410  *
00411  * @param  set A pointer to a \ref gnn_filewriter.
00412  * @param  prefix A postfix format string or NULL.
00413  * @return Returns 0 if succeeded.
00414  */
00415 int
00416 gnn_filewriter_set_postfix (gnn_output *set, const char *postfix)
00417 {
00418     gnn_filewriter *fset;
00419 
00420     assert (set != NULL);
00421 
00422     fset = (gnn_filewriter *) set;
00423 
00424     if (fset->postfix != NULL)
00425         free (fset->postfix);
00426     fset->postfix = NULL;
00427     if (postfix != NULL)
00428         fset->postfix = strdup (postfix);
00429 
00430     return 0;
00431 }
00432 
00433 /**
00434  * @brief Gets the postfix format string.
00435  * @ingroup gnn_filewriter_doc
00436  *
00437  * This function returns a pointer to the currently used postfix string.
00438  *
00439  * @param  set A pointer to a \ref gnn_filewriter.
00440  * @return Returns a pointer to the postfix or NULL.
00441  */
00442 const char *
00443 gnn_filewriter_get_postfix (gnn_output *set)
00444 {
00445     gnn_filewriter *fset;
00446 
00447     assert (set != NULL);
00448 
00449     fset = (gnn_filewriter *) set;
00450 
00451     return fset->postfix;
00452 }
00453 
00454 
00455 /**
00456  * @brief Check if it owns the file.
00457  * @ingroup gnn_filewriter_doc
00458  *
00459  * This function returns 1 if the \ref gnn_filewriter owns the file.
00460  *
00461  * @param  set A pointer to a \ref gnn_filewriter.
00462  * @return Returns 1 if it owns the file or 0 if not.
00463  */
00464 int
00465 gnn_filewriter_owns_file (gnn_output *set)
00466 {
00467     gnn_filewriter *fset;
00468 
00469     assert (set != NULL);
00470 
00471     fset = (gnn_filewriter *) set;
00472     if (fset->fileowner)
00473         return 1;
00474     else
00475         return 0;
00476 }
00477 
00478 

Generated on Sun Jun 13 20:50:11 2004 for libgnn Gradient Retropropagation Machine Library by doxygen1.2.18