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

gnn_utilities.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file gnn_utilities.h
00003  *  @brief General \ref libgnn utilities.
00004  *  @defgroup gnn_utilities \ref libgnn general utility functions.
00005  *
00006  *  @date   : 06-08-03 09:34
00007  *  @author : Pedro Ortega C. <peortega@dcc.uchile.cl>
00008  *  Copyright  2003  Pedro Ortega C.
00009  ****************************************************************************/
00010 /*
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program; if not, write to the Free Software
00023  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024  */
00025  
00026 /**
00027  * @defgroup gnn_utilities_doc Utilities Interface.
00028  * @ingroup  libgnn
00029  *
00030  * This module contains miscelaneous utilities, like vector operations not
00031  * available in the original GSL specification, access to an application-wide
00032  * random number generator, etc.
00033  *
00034  */
00035  
00036 /******************************************/
00037 /* Include Files                          */
00038 /******************************************/
00039 
00040 #include <time.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <gsl/gsl_block.h>
00045 #include <assert.h>
00046 #include <math.h>
00047 #include "gnn_globals.h"
00048 #include "gnn_utilities.h"
00049 
00050 /******************************************/
00051 /* Public Interface Implementation        */
00052 /******************************************/
00053 
00054 /**
00055  * @brief Get the global random number generator.
00056  * @ingroup gnn_utilities_doc
00057  *
00058  * This function returns a pointer to an application-wide GSL random number
00059  * generator. It allocates a new one if not defined yet.
00060  *
00061  * The type of the random number generator is given by the constant
00062  * \ref GNN_DEFAULT_RNG.
00063  *
00064  * Note: This function is not thread safe.
00065  *
00066  * @return A pointer to the random number generator.
00067  */
00068 gsl_rng *
00069 gnn_get_rng ()
00070 {
00071     static gsl_rng * r = NULL;
00072     if (r == NULL)
00073     {
00074         r = gsl_rng_alloc(GNN_DEFAULT_RNG);
00075         gsl_rng_set (r, time (NULL));
00076     }
00077     return r;
00078 }
00079 
00080 
00081 
00082 /**
00083  * @brief Resize a vector
00084  * @ingroup gnn_utilities_doc
00085  *
00086  * This function resizes a vector and tries to preserve all posible values,
00087  * i.e.
00088  * \f[ \forall i=1,\ldots,m \quad v_i = w_i \f]
00089  * where \f$v=[v_1,\ldots,v_{n_1}]\f$ is the vector before and
00090  * \f$v=[w_1,\ldots,w_{n_2}]\f$ is the vector after resizing, and
00091  * \f$m = \min (n_1, n_2)\f$.
00092  *
00093  * @param vector   A vector.
00094  * @param new_size The new size (\f$n_2\f$ in the explanation above).
00095  * @return Returns 0 if succeeded.
00096  */
00097 int
00098 gnn_vector_resize (gsl_vector **vector, int new_size)
00099 {
00100     gsl_vector *v = NULL;
00101     gsl_vector *w = NULL;
00102     
00103     v = *vector;
00104 
00105     /* build the new vector w if the size is > 0 */
00106     if (new_size > 0)
00107     {
00108         /* alloc blank vector */
00109         w = gsl_vector_calloc (new_size);
00110         assert (w != NULL);
00111 
00112         /* copy old values if any */
00113         if (v != NULL)
00114         {
00115             int min_size;
00116             gsl_vector_view v_view;
00117             gsl_vector_view w_view;
00118 
00119             min_size = GNN_MIN (v->size, w->size);
00120             v_view = gsl_vector_subvector (v, 0, min_size);
00121             w_view = gsl_vector_subvector (w, 0, min_size);
00122 
00123             gsl_vector_memcpy (&(w_view.vector), &(v_view.vector));
00124         }
00125     }
00126 
00127     /* destroy old vector if any */
00128     if (v != NULL)
00129     {
00130         assert (v->block != NULL);
00131         gsl_block_free (v->block);
00132     }
00133     
00134     *vector = w;
00135 
00136     return 0;
00137 }
00138 
00139 /**
00140  * @brief Compute the sum of the vector's elements.
00141  * @ingroup gnn_utilities_doc
00142  *
00143  * This function computes the sum of the vector's elements, that is:
00144  * \f[ \sum_{i=1}^n x_i \f]
00145  *
00146  * @param v A pointer to a vector of size \f$n\f$.
00147  * @return Returns the sum of its elements.
00148  */
00149 int
00150 gnn_vector_sum_elements (gsl_vector *v)
00151 {
00152     size_t i;
00153     double s = 0.0;
00154     for (i=0; i<v->size; ++i)
00155         s += gsl_vector_get (v, i);
00156     return s;
00157 }
00158 
00159 /**
00160  * @brief Compute the euclidian distance between to vectors.
00161  * @ingroup gnn_utilities_doc
00162  *
00163  * This function computes the euclidian distance between to vectors, given
00164  * by:
00165  * \f[ \sqrt{ \sum_{i=1}^n (v_i - u_i)^2 } \f]
00166  *
00167  * @param v A pointer to a vector of size \f$n\f$.
00168  * @param u A pointer to a vector of size \f$n\f$.
00169  * @return Returns the distance.
00170  */
00171 double
00172 gnn_vector_euclidian_dist (const gsl_vector *v, const gsl_vector *u)
00173 {
00174     size_t i;
00175     double vi, ui;
00176     double d = 0.0;
00177 
00178     for (i=0; i<v->size; ++i)
00179     {
00180         vi = v->data[i*v->stride];
00181         ui = u->data[i*u->stride];
00182         d  += (vi - ui) * (vi - ui);
00183     }
00184     return sqrt(d);
00185 }
00186 
00187 /**
00188  * @brief Compute matrix size from a stream.
00189  * @ingroup gnn_utilities_doc
00190  * @todo Make this function check for the integrity of the matrix.
00191  *
00192  * This function reads a stream until it reaches EOF, and makes an estimation
00193  * of the contained matrix size.
00194  *
00195  * @param stream A file stream.
00196  * @param m      A pointer to the variable to store the number of rows.
00197  * @param n      A pointer to the variable to store the number of columns.
00198  * @return Returns 0 if succeeded.
00199  */
00200 int
00201 gnn_matrix_check_sizes_from_stream (FILE *stream, size_t *m, size_t *n)
00202 {
00203         int   i;
00204     int   j;
00205         char  buf[GNN_MAX_BUF + 1];
00206         char *tok;
00207 
00208     assert (stream != NULL);
00209     assert (m != NULL);
00210     assert (n != NULL);
00211 
00212         /* initialize sizes */
00213         *m = *n = 0;
00214 
00215         /* check for opened stream */
00216         if (stream == NULL)
00217                 GSL_ERROR ("stream invalid", GSL_EINVAL);
00218 
00219         /* determine the size of the matrix */
00220         if (fgets (buf, GNN_MAX_BUF + 1, stream) != NULL)
00221         {
00222                 if (strtok (buf, " \t\r\n") != NULL)
00223                         *n = 1;
00224                 while (strtok (NULL, " \t\r\n") != NULL)
00225                         (*n)++;
00226         if (*n > 0)
00227                 *m = 1;
00228                 while (fgets (buf, GNN_MAX_BUF + 1, stream) != NULL)
00229                         (*m)++;
00230         }
00231 
00232     return 0;
00233 }
00234 
00235 
00236 
00237 /**
00238  * @brief Load a vector from a file.
00239  * @ingroup gnn_utilities_doc
00240  *
00241  * This function loads a vector from a file. It creates a gsl_vector of the
00242  * correct size.
00243  *
00244  * @param filename The file name from where the vector should be loaded.
00245  * @return A pointer to a new gsl_vector.
00246  */
00247 gsl_vector *
00248 gnn_vector_load (const char *filename)
00249 {
00250         int   m;
00251         int   n;
00252     int   status;
00253         FILE *fp;
00254         gsl_vector *v;
00255 
00256         /* open file */
00257         fp = fopen (filename, "r");
00258         if (fp == NULL)
00259                 GSL_ERROR_VAL ("could not open vector file.", GSL_EINVAL, NULL);
00260 
00261         /* determine the size of the matrix */
00262     status = gnn_matrix_check_sizes_from_stream (fp, &m, &n);
00263     if (status)
00264         GSL_ERROR_VAL ("error determining the size of the vector",
00265                        GSL_EFAILED, NULL);
00266 
00267         /* close file */
00268         fclose (fp);
00269 
00270         /* check sizes */
00271         if (n == 0 || m == 0)
00272                 GSL_ERROR_VAL ("vector is empty", GSL_EINVAL, NULL);
00273 
00274     /* create and load vector */
00275         v  = gsl_vector_alloc (m * n);
00276         fp = fopen (filename, "r");
00277         if (fp == NULL)
00278                 GSL_ERROR_VAL ("could not open vector file.", GSL_EINVAL, NULL);
00279         gsl_vector_fscanf (fp, v);
00280         fclose (fp);
00281 
00282     return v;
00283 }
00284 
00285 /**
00286  * @brief Saves a vector to a file.
00287  * @ingroup gnn_utilities_doc
00288  *
00289  * This function saves a vector to a file.
00290  *
00291  * @param filename The file name from where the vector should be loaded.
00292  * @param A        A gsl_vector which should be saved.
00293  * @return Returns 0 if suceeded.
00294  */
00295 int
00296 gnn_vector_save (const char *filename, gsl_vector *v)
00297 {
00298     FILE *fp;
00299 
00300     /* open file and save vector */
00301         fp = fopen (filename, "w");
00302         if (fp == NULL)
00303         GSL_ERROR ("could not open file for output", GSL_EINVAL);
00304         gsl_vector_fprintf (fp, v, "%g");
00305         fclose (fp);
00306 
00307         return 0;
00308 }
00309 
00310 /**
00311  * @brief Load a matrix from a file.
00312  * @ingroup gnn_utilities_doc
00313  *
00314  * This function loads a matrix from a file. It creates a gsl_matrix of the
00315  * correct size.
00316  *
00317  * @param filename The file name from where the matrix should be loaded.
00318  * @return A pointer to a new gsl_matrix.
00319  */
00320 gsl_matrix *
00321 gnn_matrix_load (const char *filename)
00322 {
00323         int   m;
00324         int   n;
00325     int   status;
00326         FILE *fp;
00327         gsl_matrix *A;
00328 
00329         /* open file */
00330         fp = fopen (filename, "r");
00331         if (fp == NULL)
00332                 GSL_ERROR_VAL ("could not open matrix file.", GSL_EINVAL, NULL);
00333 
00334         /* determine the size of the matrix */
00335     status = gnn_matrix_check_sizes_from_stream (fp, &m, &n);
00336     if (status)
00337         GSL_ERROR_VAL ("error determining the size of the matrix",
00338                        GSL_EFAILED, NULL);
00339 
00340         /* close file */
00341         fclose (fp);
00342 
00343         /* check sizes */
00344         if (n == 0 || m == 0)
00345                 GSL_ERROR_VAL ("matrix is empty", GSL_EINVAL, NULL);
00346 
00347     /* create and load matrix */
00348         A  = gsl_matrix_alloc (m, n);
00349         fp = fopen (filename, "r");
00350         if (fp == NULL)
00351                 GSL_ERROR_VAL ("could not open matrix file.", GSL_EINVAL, NULL);
00352         gsl_matrix_fscanf (fp, A);
00353         fclose (fp);
00354 
00355     return A;
00356 }
00357 
00358 /**
00359  * @brief Saves a matrix to a file.
00360  * @ingroup gnn_utilities_doc
00361  *
00362  * This function saves a matrix to a file.
00363  *
00364  * @param filename The file name from where the matrix should be loaded.
00365  * @param A        A gsl_matrix which should be saved.
00366  * @return Returns 0 if suceeded.
00367  */
00368 int
00369 gnn_matrix_save (const char *filename, gsl_matrix *A)
00370 {
00371     FILE *fp;
00372     
00373     /* open file and save matrix */
00374         fp = fopen (filename, "w");
00375         if (fp == NULL)
00376         GSL_ERROR ("could not open file for output", GSL_EINVAL);
00377         gsl_matrix_fprintf (fp, A, "%g");
00378         fclose (fp);
00379         
00380         return 0;
00381 }
00382 
00383 
00384 

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