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

gnn_divergence.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file gnn_divergence.c
00003  *  @brief gnn_divergence Implementation.
00004  *
00005  *  @date   : 28-09-03 13:14
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  * @defgroup gnn_divergence_doc gnn_divergence : Input Divergence.
00027  * @ingroup gnn_atomic_doc
00028  *
00029  * This node type implements the function given by:
00030  *
00031  * \f[ y = [x, x, x, x]^T \f]
00032  *
00033  * In other words, it replicates the input several times on the output vector.
00034  * If the output vector's size isn't a multiple of the input vector's size,
00035  * that is, if \f$m\f$ can't be written as \f$kn\f$, then only the first inputs
00036  * will be copied, e.g. if \f$x=[x_0, \ldots, x_3]^T\f$ and \f$y\f$ is of size
00037  * \f$6 \times 1\f$ then
00038  *
00039  * \f[ y = [x_0, x_1, x_2, x_3, x_0, x_1]^T \f]
00040  *
00041  * Schematically, this idea can be depicted as
00042  *
00043  * <img src="images/gnn_divergence1.png">
00044  *
00045  * The function's gradient is:
00046  * \f[ \frac{\partial E}{\partial x_i}
00047  *     = \sum_k \frac{\partial E}{\partial y_{kn+i}}
00048  * \f]
00049  */
00050 
00051 
00052 /******************************************/
00053 /* Include Files                          */
00054 /******************************************/
00055 
00056 #include "gnn_divergence.h"
00057 
00058 
00059 
00060 /******************************************/
00061 /* Static Declaration                     */
00062 /******************************************/
00063 
00064 static int
00065 gnn_divergence_f (gnn_node *node,
00066                   const gsl_vector *x,
00067                   const gsl_vector *w,
00068                   gsl_vector *y);
00069 
00070 static int
00071 gnn_divergence_dx (gnn_node *node,
00072                    const gsl_vector *x,
00073                    const gsl_vector *w,
00074                    const gsl_vector *dy,
00075                    gsl_vector *dx);
00076 
00077 static int
00078 gnn_divergence_dw (gnn_node *node,
00079                    const gsl_vector *x,
00080                    const gsl_vector *w,
00081                    const gsl_vector *dy,
00082                    gsl_vector *dw);
00083 
00084 static void
00085 gnn_divergence_destroy (gnn_node *node);
00086 
00087 
00088 
00089 /******************************************/
00090 /* Static Implementation                  */
00091 /******************************************/
00092 
00093 /**
00094  * @brief Computes the output.
00095  * @ingroup gnn_divergence_doc
00096  *
00097  * @param   node A pointer to the \ref gnn_divergence node.
00098  * @param x The input vector \f$x\f$.
00099  * @param w The parameter vector \f$w\f$.
00100  * @param y The output buffer vector \f$y\f$.
00101  * @return Returns 0 on success.
00102  */
00103 static int
00104 gnn_divergence_f (gnn_node *node,
00105                   const gsl_vector *x,
00106                   const gsl_vector *w,
00107                   gsl_vector *y)
00108 {
00109     size_t n;
00110     size_t m;
00111     size_t k;
00112     gnn_divergence *dnode;
00113 
00114     /* get views */
00115     dnode = (gnn_divergence *) node;
00116 
00117     /* get sizes */
00118     n = gnn_node_input_get_size (node);
00119     m = gnn_node_output_get_size (node);
00120 
00121     /* evaluate */
00122     for (k=0; k<m; ++k)
00123     {
00124         size_t i;
00125         double yk;
00126 
00127         i  = k % n;
00128         yk = gsl_vector_get (x, i);
00129         gsl_vector_set (y, k, yk);
00130     }
00131 
00132     return 0;
00133 }
00134 
00135 /**
00136  * @brief Computes \f$ \frac{\partial E}{\partial x} \f$.
00137  * @ingroup gnn_divergence_doc
00138  *
00139  * @param    node A pointer to the \ref gnn_divergence node.
00140  * @param x  The input vector \f$x\f$.
00141  * @param w  The parameter vector \f$w\f$.
00142  * @param dy The vector \f$\frac{\partial E}{\partial y}\f$.
00143  * @param dx The output buffer vector \f$\frac{\partial E}{\partial x}\f$.
00144  * @return Returns 0 on success.
00145  */
00146 static int
00147 gnn_divergence_dx (gnn_node *node,
00148                    const gsl_vector *x,
00149                    const gsl_vector *w,
00150                    const gsl_vector *dy,
00151                    gsl_vector *dx)
00152 {
00153     size_t n;
00154     size_t m;
00155     size_t k;
00156     gnn_divergence *dnode;
00157 
00158     /* get views */
00159     dnode = (gnn_divergence *) node;
00160 
00161     /* get sizes */
00162     n = gnn_node_input_get_size (node);
00163     m = gnn_node_output_get_size (node);
00164 
00165     /* evaluate */
00166     gsl_vector_set_zero (dx);
00167     for (k=0; k<m; ++k)
00168     {
00169         size_t i;
00170         double dxi;
00171 
00172         i    = k % n;
00173         dxi  = gsl_vector_get (dx, i);
00174         dxi += gsl_vector_get (dy, k);
00175         gsl_vector_set (dx, i, dxi);
00176     }
00177 
00178     return 0;
00179 }
00180 
00181 /**
00182  * @brief Computes \f$ \frac{\partial E}{\partial w} \f$.
00183  * @ingroup gnn_divergence_doc
00184  *
00185  * @param    node A pointer to the \ref gnn_divergence node.
00186  * @param x  The input vector \f$x\f$.
00187  * @param w  The parameter vector \f$w\f$.
00188  * @param dy The vector \f$\frac{\partial E}{\partial y}\f$.
00189  * @param dx The output buffer vector \f$\frac{\partial E}{\partial w}\f$.
00190  * @return Returns 0 on success.
00191  */
00192 static int
00193 gnn_divergence_dw (gnn_node *node,
00194                    const gsl_vector *x,
00195                    const gsl_vector *w,
00196                    const gsl_vector *dy,
00197                    gsl_vector *dw)
00198 {
00199     return 0;
00200 }
00201 
00202 
00203 
00204 /******************************************/
00205 /* Public Interface                       */
00206 /******************************************/
00207 
00208 /**
00209  * @brief Creates an input divergence node.
00210  * @ingroup gnn_divergence_doc
00211  *
00212  * This function creates a node of the \ref gnn_divergence type.
00213  *
00214  * @param input_size  The input size \f$n\f$.
00215  * @param output_size The output size \f$m\f$.
00216  * @return A pointer to a new \ref gnn_divergence node.
00217  */
00218 gnn_node *
00219 gnn_divergence_new (size_t input_size, size_t output_size)
00220 {
00221     int status;
00222     size_t k;
00223     gnn_node *node;
00224     gnn_divergence *dnode;
00225 
00226     /* check sizes */
00227     if (input_size < 1)
00228     {
00229         GSL_ERROR_VAL ("input size should be strictly positive",
00230                        GSL_EINVAL, NULL);
00231     }
00232     if (input_size > output_size)
00233     {
00234         GSL_ERROR_VAL ("output size should be greater than the input size",
00235                        GSL_EINVAL, NULL);
00236     }
00237 
00238     /* allocate the node */
00239     dnode = (gnn_divergence *) malloc (sizeof (gnn_divergence));
00240     if (dnode == NULL)
00241     {
00242         GSL_ERROR_VAL ("could not allocate memory for gnn_divergence node",
00243                        GSL_ENOMEM, NULL);
00244     }
00245 
00246     /* get view as a gnn_node */
00247     node = (gnn_node *) dnode;
00248 
00249     /* Initialize the node */
00250     status = gnn_node_init (node,
00251                             "gnn_divergence",
00252                             gnn_divergence_f,
00253                             gnn_divergence_dx,
00254                             gnn_divergence_dw,
00255                             NULL);
00256     if (status)
00257     {
00258         GSL_ERROR_VAL ("could not initialize gnn_divergence node",
00259                        GSL_EFAILED, NULL);
00260     }
00261 
00262     status = gnn_node_set_sizes (node, input_size, output_size, 0);
00263     if (status)
00264     {
00265         GSL_ERROR_VAL ("could not set sizes for gnn_divergence node",
00266                        GSL_EFAILED, NULL);
00267     }
00268 
00269     /* compute amount of replications */
00270     dnode->rep =  output_size / input_size;
00271     dnode->rep += (output_size % input_size == 0)? 0 : 1;
00272 
00273     return node;
00274 }
00275 
00276 

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