00001 /*************************************************************************** 00002 * @file gnn_gaussian_noise_input.c 00003 * @brief gnn_gaussian_noise Implementation. 00004 * 00005 * @date : 05-10-03 12:48 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_gaussian_noise_input_doc gnn_gaussian_noise_input : Adds Gaussian Noise to Input Samples. 00029 * @ingroup gnn_input_doc 00030 * @brief Adds gaussian noise to input samples. 00031 * 00032 * The \ref gnn_gaussian_noise_input samples draws its input samples from 00033 * an associated \ref gnn_input input device, and adds gaussian noise with 00034 * mean zero and standard deviation of your choice. 00035 * 00036 * \f[ x_i = \overline{x}_i + n(t, \sigma) \f] 00037 * 00038 * where the \f$x\f$, is the pattern returned by this device, 00039 * \f$\overline{x}\f$ is the input sample drawn from the underlying input 00040 * device, and \f$n(t, \sigma)\f$ is the gaussian noise. 00041 * 00042 * A \ref gnn_gaussian_noise_input should be built giving it a pointer to 00043 * an already existing \ref gnn_input device. The \ref gnn_gaussian_noise_input 00044 * owns a random number generator that is uses to generate the noise. 00045 */ 00046 00047 00048 00049 /******************************************/ 00050 /* Include Files */ 00051 /******************************************/ 00052 00053 #include <time.h> 00054 #include <gsl/gsl_rng.h> 00055 #include <gsl/gsl_randist.h> 00056 #include "gnn_gaussian_noise_input.h" 00057 00058 00059 00060 /******************************************/ 00061 /* Static Declaration */ 00062 /******************************************/ 00063 00064 /** 00065 * @brief The datatype for gaussian_noise inputs. 00066 * @ingroup gnn_gaussian_noise_input_doc 00067 * 00068 * This is the datatype for gaussian_noise inputs. It extends the basic 00069 * \ref gnn_input structure to include the additional pointer 00070 * to the \ref gnn_input device, a buffer for storing the current pattern 00071 * that was built, etc. 00072 */ 00073 typedef struct _gnn_gaussian_noise_input gnn_gaussian_noise_input; 00074 00075 struct _gnn_gaussian_noise_input 00076 { 00077 gnn_input set; /**< The underlying \ref gnn_input */ 00078 gnn_input *subset; /**< A pointer to the sub-input patterns. */ 00079 gsl_vector *buf; /**< The buffer for evaluations. */ 00080 gsl_rng *rng; /**< Pointer to the random number generator. */ 00081 double sigma; /**< The noise deviation \f$\sigma\f$. */ 00082 }; 00083 00084 static const gsl_vector * 00085 gnn_gaussian_noise_input_get (gnn_input *set, size_t k); 00086 00087 static void 00088 gnn_gaussian_noise_input_destroy (gnn_input *set); 00089 00090 00091 00092 /******************************************/ 00093 /* Static Implementation */ 00094 /******************************************/ 00095 00096 /** 00097 * @brief The "get" function for a gaussian_noise input set. 00098 * @ingroup gnn_gaussian_noise_input_doc 00099 * 00100 * This function is returns the k-th pattern in the set. 00101 * 00102 * @param set A pointer to a \ref gnn_gaussian_noise_input. 00103 * @param k The index of the pattern to be retrieved. 00104 * @return A pointer to the sample vector. 00105 */ 00106 static const gsl_vector * 00107 gnn_gaussian_noise_input_get (gnn_input *set, size_t k) 00108 { 00109 size_t n; 00110 size_t P; 00111 size_t i; 00112 const gsl_vector *x; 00113 gnn_gaussian_noise_input *gset; 00114 00115 assert (set != NULL); 00116 00117 /* get gaussian_noise dataset view */ 00118 gset = (gnn_gaussian_noise_input *) set; 00119 00120 /* get sizes */ 00121 n = gnn_input_sample_get_size (set); 00122 P = gnn_input_get_size (set); 00123 00124 /* check index */ 00125 if (k < 0 || P <= k) 00126 { 00127 GSL_ERROR_VAL ("pattern index out of bounds", GSL_EINVAL, NULL); 00128 } 00129 00130 /* build the new pattern, summing gaussian noise to its values. */ 00131 x = gnn_input_get (gset->subset, k); 00132 00133 for (i=0; i<n; ++i) 00134 { 00135 double ni; 00136 double xi; 00137 double xni; 00138 00139 xi = gsl_vector_get (x, i); 00140 ni = gsl_ran_gaussian (gset->rng, gset->sigma); 00141 xni = xi + ni; 00142 gsl_vector_set (gset->buf, i, xni); 00143 } 00144 00145 return gset->buf; 00146 } 00147 00148 /** 00149 * @brief Destroy function. 00150 * @ingroup gnn_gaussian_noise_input_doc 00151 * 00152 * This is the \ref gnn_gaussian_noise_input destroy function. 00153 * @param set A pointer to a \ref gnn_gaussian_noise_input dataset. 00154 */ 00155 static void 00156 gnn_gaussian_noise_input_destroy (gnn_input *set) 00157 { 00158 gnn_gaussian_noise_input *gset; 00159 00160 assert (set != NULL); 00161 00162 /* get gaussian_noise set view */ 00163 gset = (gnn_gaussian_noise_input *) set; 00164 00165 /* free buffer vector and the random number generator */ 00166 if (gset->buf != NULL) 00167 gsl_vector_free (gset->buf); 00168 if (gset->rng != NULL) 00169 gsl_rng_free (gset->rng); 00170 } 00171 00172 00173 00174 /******************************************/ 00175 /* Public Interface */ 00176 /******************************************/ 00177 00178 /** 00179 * @brief Builds a gaussian noise device. 00180 * @ingroup gnn_gaussian_noise_input_doc 00181 * 00182 * This function creates a new \ref gnn_gaussian_noise_input from a given 00183 * \ref gnn_input device \a input. The noises' deviation \f$\sigma\f$ 00184 * is given by \a sigma. 00185 * 00186 * @param input The input device whose input samples should be contaminated 00187 * with gaussian noise. 00188 * @param sigma The gaussian's standard deviation \f$\sigma\f$. 00189 * @return Returns a pointer to a new \ref gnn_gaussian_noise_input set. 00190 */ 00191 gnn_input * 00192 gnn_gaussian_noise_new (gnn_input *input, double sigma) 00193 { 00194 size_t P; 00195 size_t n; 00196 int status; 00197 gnn_input *set; 00198 gnn_gaussian_noise_input *gset; 00199 00200 assert (input != NULL); 00201 00202 /* alloc gaussian_noise for input set */ 00203 gset = 00204 (gnn_gaussian_noise_input *) malloc (sizeof (gnn_gaussian_noise_input)); 00205 00206 /* get view as a input set */ 00207 set = (gnn_input *) gset; 00208 00209 /* get sizes */ 00210 P = gnn_input_get_size (input); 00211 n = gnn_input_sample_get_size (input); 00212 00213 /* initialize */ 00214 status = gnn_input_init (set, 00215 P, 00216 n, 00217 NULL, 00218 gnn_gaussian_noise_input_get, 00219 gnn_gaussian_noise_input_destroy); 00220 if (status) 00221 { 00222 gnn_input_destroy (set); 00223 GSL_ERROR_VAL ("could not initialize gnn_gaussian_noise_input", 00224 GSL_EFAILED, NULL); 00225 } 00226 00227 /* set fields */ 00228 gset->subset = input; 00229 gset->sigma = sigma; 00230 gset->buf = gsl_vector_alloc (n); 00231 00232 if (gset->buf == NULL) 00233 { 00234 gnn_input_destroy (set); 00235 GSL_ERROR_VAL ("couldn't allocate memory for " 00236 "gnn_gaussian_noise_input's buffer", GSL_ENOMEM, NULL); 00237 } 00238 00239 /* create the own random number generator */ 00240 gset->rng = gsl_rng_alloc (GNN_GAUSSIAN_NOISE_INPUT_RNG); 00241 if (gset->rng == NULL) 00242 { 00243 gnn_input_destroy (set); 00244 GSL_ERROR_VAL ("couldn't allocate the random number generator for " 00245 "gnn_gaussian_noise_input", GSL_ENOMEM, NULL); 00246 } 00247 00248 /* initialize the random number generator */ 00249 gsl_rng_set (gset->rng, time (NULL)); 00250 00251 return set; 00252 } 00253 00254 /** 00255 * @brief Sets a new \f$\sigma\f$ for the gaussian noise. 00256 * @ingroup gnn_gaussian_noise_input_doc 00257 * 00258 * @param input A pointer to the \ref gnn_gaussian_noise_input device. 00259 * @param sigma A positive real number. 00260 * @return Returns 0 if succeeded. 00261 */ 00262 int 00263 gnn_gaussian_noise_set_sigma (gnn_input *input, double sigma) 00264 { 00265 gnn_gaussian_noise_input *gset; 00266 00267 assert (input != NULL); 00268 00269 /* check for positive sigma */ 00270 if (sigma < 0.0) 00271 { 00272 GSL_ERROR ("deviation sigma should be positive", GSL_EINVAL); 00273 } 00274 00275 /* get view as a gaussian noise set */ 00276 gset = (gnn_gaussian_noise_input *) input; 00277 00278 /* set the new noise deviation's value */ 00279 gset->sigma = sigma; 00280 00281 return 0; 00282 } 00283 00284 /** 00285 * @brief Returns the current \f$\sigma\f$. 00286 * @ingroup gnn_gaussian_noise_input_doc 00287 * 00288 * @param input A pointer to the \ref gnn_gaussian_noise_input device. 00289 * @return Returns the current value for \f$\sigma\f$. 00290 */ 00291 double 00292 gnn_gaussian_noise_get_sigma (gnn_input *input) 00293 { 00294 gnn_gaussian_noise_input *gset; 00295 00296 assert (input != NULL); 00297 00298 /* get view as a gaussian noise set */ 00299 gset = (gnn_gaussian_noise_input *) input; 00300 00301 return gset->sigma; 00302 } 00303
1.2.18