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

gnn_node.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file  gnn_node.c
00003  *  @brief gnn_node Implementation File.
00004  *
00005  *  @date   : 11-08-03 22:45
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  * @brief The underlying basic building block for composite gradient machines.
00029  * @defgroup gnn_node_doc gnn_node : Basic Building Block for Gradient Machines.
00030  * @ingroup  libgnn_node
00031  *
00032  * This is the basic building block for \ref libgnn's trainable functions.
00033  * The \ref gnn_node data type and its programming interface provide the
00034  * machinery for the construction, composition, evaluation and training
00035  * of vector functions. The \ref gnn_node structure is optimized for the
00036  * evaluation of its gradient (with respect to its inputs and its parameters)
00037  * using the error-backpropagation scheme (a type of
00038  * cascade-gradient-evaluation).
00039  *
00040  * \ref gnn_node shouldn't be used by themself. Instead, new node types extend
00041  * the \ref gnn_node data type.
00042  *
00043  * The conventions for notation used throughout this documentation is:
00044  *
00045  * A \ref gnn_node implements a set \f$\mathbb{F}\f$ of vectorial functions
00046  * \f$f: \mathbb{R}^n \rightarrow \mathbb{R}^m\f$ that map an input vector
00047  * \f$x\f$ of size \f$n \times 1\f$ to an ouput vector \f$y\f$ of size
00048  * \f$m \times 1\f$.
00049  * This set can be a singleton, or,
00050  * optionally, it can have a vector of adjustable parameters
00051  * \f$w \in \mathbb{R}^l\f$ of size \f$l \times 1\f$ so that
00052  * \f[ \mathbb{F} =
00053  *     \{ f(\cdot) | f(\cdot) = F(\cdot, w), w\in \mathbb{R}^l \}
00054  * \f]
00055  * In this case, we will talk about the "generic" function
00056  * \f$F : \mathbb{R}^{n+l} \rightarrow \mathbb{R}^m\f$ as the "Machine" or
00057  * the "Model".
00058  *
00059  * A general machine \f$F\f$ can be built by connecting several subfunctions
00060  * in a variety of forms. The resulting function can then be feed with inputs
00061  * to compute its output. Since \ref libgnn's main purpose is to offer a
00062  * unified way to train this function using the error-backpropagation scheme
00063  * to compute the function's gradient with respect to its parameters
00064  * \f$\frac{\partial E}{\partial w}\f$, the \ref gnn_node structure has
00065  * been designed to provide a simple yet powerful extendable skeleton
00066  * for the implementation of highly customized models.
00067  *
00068  * The evaluation of the result is the <b>Forward Evaluation</b>, triggered
00069  * by the \ref gnn_node_evaluate_f function, and the computation of both
00070  * gradient is called <b>Backward Evaluation</b>, triggered (in order) by
00071  * \ref gnn_node_evaluate_dx and \ref gnn_node_evaluate_dw .
00072  *
00073  * <img src="images/gnn_node1.png" border="0">
00074  *
00075  * In order to compute the result and the gradients for one (and only one!)
00076  * given input example, you should call, in order:
00077  *
00078  * -# \ref gnn_node_evaluate_init : Cleans the old parameter gradient.
00079  * -# \ref gnn_node_evaluate_f    : Evaluates the output.
00080  * -# \ref gnn_node_evaluate_dx   : Computes the gradient with respect to
00081  *    its inputs.
00082  * -# \ref gnn_node_evaluate_dw   : Computes the gradient with respect to
00083  *    its outputs.
00084  *
00085  * The order function calling sequence above must be respected,
00086  * and repeated for each input example. Nevertheless, it isn't mandatory
00087  * to perform all steps in the sequence, i.e. if you want to compute only
00088  * the output, perform only the first two steps; if you don't need the
00089  * gradient with respect to the paremeters, then don't call
00090  * \ref gnn_node_evaluate_dw .
00091  *
00092  *
00093  * <b>More about extensions:</b>
00094  *
00095  * Although all specific extensions have their own specific features, they all
00096  * are (or can be casted to) a \ref gnn_node. A \ref gnn_node can be manipulated
00097  * with the following APIs:
00098  *
00099  * - Basic API: This interface provides the basic functionality, such as
00100  *              retrieving the internal attributes, evaluating an input and
00101  *              evaluating its gradients \f$\frac{\partial E}{\partial x}\f$
00102  *              and \f$\frac{\partial E}{\partial w}\f$.
00103  * - \ref gnn_node_param_doc : Offers the functionality to change the node's
00104  *              parameters.
00105  * - \ref gnn_node_ext_doc : This interface provides the functions needed for
00106  *              extending a \ref gnn_node for your particular purposes.
00107  * - \ref gnn_node_sub_doc : This last interface is also an extension API, but
00108  *              it offers the functions for connecting and traversing a tree of
00109  *              nodes. This is only needed when you want to implement a
00110  *              construction node (a node which groups other nodes).
00111  *
00112  *
00113  */
00114 
00115 /**
00116  * @brief Atomic Nodes.
00117  * @defgroup gnn_atomic_doc Atomic Nodes.
00118  * @ingroup  libgnn_node
00119  *
00120  * Atomic nodes are implementations of the \ref gnn_node interface that
00121  * do not depend on subnodes to compute its result and gradients. Most
00122  * node types are <b>atomic</b>.
00123  */
00124 
00125 /**
00126  * @brief Constructor Nodes.
00127  * @defgroup gnn_constructor_doc Constructor Nodes.
00128  * @ingroup  libgnn_node
00129  *
00130  * Constructor nodes are nodes that do depend on subnodes in order to compute
00131  * the represented function's result and gradients. They usually provide a
00132  * way to compose modules, like the \ref gnn_serial or \ref gnn_parallel
00133  * constructor nodes.
00134  *
00135  * Constructor nodes are the glue of Gradient Backpropagation Machines.
00136  *
00137  */
00138 
00139 
00140 
00141 /******************************************/
00142 /* Include Files                          */
00143 /******************************************/
00144 
00145 #include <assert.h>
00146 #include <stdarg.h>
00147 #include <gsl/gsl_block.h>
00148 #include <string.h>
00149 #include "gnn_utilities.h"
00150 #include "gnn_node.h"
00151 
00152 
00153 /******************************************/
00154 /* Static Definitions                     */
00155 /******************************************/
00156 
00157 
00158 static void
00159 gnn_node_destroy_structure (gnn_node *node);
00160 
00161 static int
00162 gnn_node_default_f (gnn_node      *node,
00163                     const gsl_vector *x,
00164                     const gsl_vector *w,
00165                     gsl_vector       *y );
00166 
00167 static int
00168 gnn_node_default_dx (gnn_node *node,
00169                      const gsl_vector *x,
00170                      const gsl_vector *w,
00171                      const gsl_vector *dy,
00172                      gsl_vector *dx );
00173 
00174 static int
00175 gnn_node_default_dw (gnn_node *node,
00176                      const gsl_vector *x,
00177                      const gsl_vector *w,
00178                      const gsl_vector *dy,
00179                      gsl_vector *dw );
00180 
00181 static void
00182 gnn_node_default_destructor (gnn_node *node);
00183 
00184 static int
00185 gnn_node_sub_search_params_recurse (gnn_node    *node,
00186                                     const char  *type,
00187                                     gnn_pbundle *pb);
00188                                     
00189                                     
00190 
00191 /******************************************/
00192 /* Static Implementations                 */
00193 /******************************************/
00194 
00195 /**
00196  * @brief Destroys a \ref gnn_node.
00197  * @ingroup gnn_node_ext_doc
00198  *
00199  * This function destroys the underlying \ref gnn_node structure by freeing
00200  * the memory associated to the fields of the node and freeing the structure
00201  * itself. It also calls the \ref gnn_node_destroy function on all subnodes.
00202  *
00203  * This function should not be called directly. Instead, \ref gnn_node_destroy
00204  * should be called instead in order to free also additional resources that
00205  * could have been allocated specifically for the node's type. Please read also
00206  * the details available in \ref gnn_node_destroy's documentation.
00207  *
00208  * @param node A pointer to a \ref gnn_node.
00209  */
00210 static void
00211 gnn_node_destroy_structure (gnn_node *node)
00212 {
00213     int i;
00214     gnn_node *subnode;
00215     
00216     assert (node != NULL);
00217     
00218     /* destroy subnodes */
00219     for (i=0; i<node->nsub; ++i)
00220     {
00221         node->sub[i]->super = NULL;
00222         gnn_node_destroy (node->sub[i]);
00223     }
00224     
00225     /* destroy fields */
00226     gnn_pbundle_destroy (node->pb);
00227     gnn_phandle_unref (node->ph);
00228     free ((char *) node->type);
00229     
00230     if (node->sub != NULL)
00231         free (node->sub);
00232 
00233     /* free node memory */
00234     free (node);
00235 }
00236 
00237 /**
00238  * @brief Default evaluation function.
00239  * @ingroup gnn_node_ext_doc
00240  *
00241  * This is the default evaluation function for a \ref gnn_node when initialized
00242  * with NULL in \ref gnn_node_init. It computes
00243  * \f[ y = [x,x,x,\ldots]^t \f]
00244  * that is, it copies the input vector \f$x\f$ several times into the output
00245  * vector until it is completely filled.
00246  *
00247  * @param node A pointer to a \ref gnn_node.
00248  * @param x    The input vector \f$x\f$.
00249  * @param w    The node's parameter vector \f$w\f$.
00250  * @param y    The output vector \f$y\f$ where the result should be placed.
00251  * @return 0 if succeeded.
00252  */
00253 static int
00254 gnn_node_default_f (gnn_node      *node,
00255                     const gsl_vector *x,
00256                     const gsl_vector *w,
00257                     gsl_vector       *y )
00258 {
00259     int i;
00260     int j;
00261     
00262     assert (node != NULL);
00263     
00264     /* copy input to output several times */
00265     j = 0;
00266     while (j < node->m)
00267     {
00268         i = 0;
00269         while (i < node->n && j < node->m)
00270         {
00271             gsl_vector_set (y, j, gsl_vector_get (x, i));
00272             ++j;
00273             ++i;
00274         }
00275     }
00276     
00277     return 0;
00278 }
00279 
00280 /**
00281  * @brief Default \f$\frac{\partial E}{\partial x}\f$ evaluation function.
00282  * @ingroup gnn_node_ext_doc
00283  *
00284  * This is the default \f$\frac{\partial E}{\partial x}\f$ evaluation function
00285  * for a \ref gnn_node when initialized with NULL in \ref gnn_node_init. It
00286  * computes
00287  * \f[ ? \f]
00288  * @todo Not implemented yet.
00289  *
00290  * @param node A pointer to a \ref gnn_node.
00291  * @param x    The input vector \f$x\f$ where the gradient should be evaluated.
00292  * @param w    The function's parameters \f$w\f$ where the gradient should be
00293  *             evaluated at.
00294  * @param dy   The vector \f$\frac{\partial E}{\partial y}\f$ that should
00295  *             be retropropagated.
00296  * @param dx   A sufficiently large vector for storing the resulting
00297  *             \f$\frac{\partial E}{\partial x}\f$ should be placed at.
00298  * @return 0 if succeeded.
00299  */
00300 static int
00301 gnn_node_default_dx (gnn_node *node,
00302                      const gsl_vector *x,
00303                      const gsl_vector *w,
00304                      const gsl_vector *dy,
00305                      gsl_vector *dx )
00306 {
00307     return 0;
00308 }
00309 
00310 /**
00311  * @brief Default \f$\frac{\partial E}{\partial w}\f$ evaluation function.
00312  * @ingroup gnn_node_ext_doc
00313  *
00314  * This is the default \f$\frac{\partial E}{\partial w}\f$ evaluation function
00315  * for a \ref gnn_node when initialized with NULL in \ref gnn_node_init. It
00316  * computes
00317  * \f[ ? \f]
00318  * @todo Not implemented yet.
00319  *
00320  * @param node A pointer to a \ref gnn_node.
00321  * @param x    The input vector \f$x\f$ where the gradient should be evaluated.
00322  * @param w    The function's parameters \f$w\f$ where the gradient should be
00323  *             evaluated at.
00324  * @param dy   The vector \f$\frac{\partial E}{\partial y}\f$ that should
00325  *             be retropropagated.
00326  * @param dw   A sufficiently large vector for storing the resulting
00327  *             \f$\frac{\partial E}{\partial w}\f$ should be placed at.
00328  * @return 0 if succeeded.
00329  */
00330 static int
00331 gnn_node_default_dw (gnn_node *node,
00332                      const gsl_vector *x,
00333                      const gsl_vector *w,
00334                      const gsl_vector *dy,
00335                      gsl_vector *dw )
00336 {
00337     return 0;
00338 }
00339 
00340 /**
00341  * @brief Default \ref gnn_node destructor.
00342  * @ingroup gnn_node_ext_doc
00343  *
00344  * This is the default destructor for a \ref gnn_node when initialized
00345  * with NULL in \ref gnn_node_init. It asumes that the current \ref gnn_node
00346  * type hasn't allocated any additional memory nor contains any other specific
00347  * info other than a \ref gnn_node's default.
00348  *
00349  * Consecuently, it doesn't anything than just return.
00350  *
00351  * @param node A pointer to a \ref gnn_node.
00352  */
00353 static void
00354 gnn_node_default_destructor (gnn_node *node)
00355 {
00356     assert (node != NULL);
00357     return;
00358 }
00359 
00360 /**
00361  * @brief The recursive function for parameters searchs.
00362  * @ingroup gnn_node_sub_doc
00363  *
00364  * This function is invoked by \ref gnn_node_sub_search_params. 
00365  *
00366  * @param node A pointer to a \ref gnn_node.
00367  * @param type A string identifying the searched nodes.
00368  * @param pb   A pointer to a \ref gnn_pbundle.
00369  * @return 0 if succeeded.
00370  */
00371 static int
00372 gnn_node_sub_search_params_recurse (gnn_node    *node,
00373                                     const char  *type,
00374                                     gnn_pbundle *pb)
00375 {
00376     size_t i;
00377 
00378     assert (node != NULL);
00379 
00380     /* insert parameter handle into parameter bundle if type matches */
00381     if (strcmp (node->type, type) == 0)
00382         gnn_pbundle_insert (pb, node->ph, 1);
00383 
00384     /* base case : no more subnodes available */
00385     if (node->nsub == 0)
00386         return 0;
00387 
00388     /* recursion case : search all subtrees */
00389     for (i=0; i<node->nsub; ++i)
00390         gnn_node_sub_search_params_recurse (node->sub[i], type, pb);
00391 
00392     return 0;
00393 }
00394 
00395 
00396 
00397 /******************************************/
00398 /* Public Interface                       */
00399 /******************************************/
00400 
00401 /*************/
00402 /* Basic API */
00403 /*************/
00404 
00405 /**
00406  * @brief Check if node is root node.
00407  * @ingroup gnn_node_doc
00408  *
00409  * This function returns 1 if the current node is a root node, or 0 if not.
00410  *
00411  * @param  node A \ref gnn_node.
00412  * @return 1 if root node, 0 if not.
00413  */
00414 int
00415 gnn_node_is_root (gnn_node *node)
00416 {
00417     assert (node != NULL);
00418     if (node->super == NULL)
00419         return 1;
00420     else
00421         return 0;
00422 }
00423 
00424 /**
00425  * @brief Get the node's type.
00426  * @ingroup gnn_node_doc
00427  *
00428  * This function returns the node's type: an unique string 
00429  * which identifies a node's type.
00430  *
00431  * Generally speaking, the type depends on which constructor function was used
00432  * to instantiate the node. Per example, gnn_weight_new () creates a
00433  * "gnn_weight" node, gnn_tanh_new () creates a "gnn_tanh" node.
00434  *
00435  * The returned string is owned by the node and should not be freed or
00436  * manipulated in any other way.
00437  *
00438  * @param  node A \ref gnn_node.
00439  * @return A string containing n integer identifying the layer's type.
00440  */
00441 const char *
00442 gnn_node_get_type_name (gnn_node *node)
00443 {
00444     assert (node != NULL);
00445     return node->type;
00446 }
00447 
00448 /**
00449  * @brief Get the node's input size.
00450  * @ingroup gnn_node_doc
00451  *
00452  * This function returns the size \f$n\f$ of the input vector \f$x\f$ that
00453  * the current node's function \f$f\f$ demands for computing its output
00454  * \f$y\f$.
00455  *
00456  * @param  node A pointer to an \ref gnn_node.
00457  * @return The input size.
00458  */
00459 int
00460 gnn_node_input_get_size (gnn_node *node)
00461 {
00462     assert (node != NULL);
00463     return node->n;
00464 }
00465 
00466 /**
00467  * @brief Get the node's output size.
00468  * @ingroup gnn_node_doc
00469  *
00470  * This function returns the size \f$m\f$ of the output vector \f$y\f$ that
00471  * the current node's function \f$f\f$ computes.
00472  *
00473  * @param  node A pointer to an \ref gnn_node.
00474  * @return The output size.
00475  */
00476 int
00477 gnn_node_output_get_size (gnn_node *node)
00478 {
00479     assert (node != NULL);
00480     return node->m;
00481 }
00482 
00483 /**
00484  * @brief Destroys the current node.
00485  * @ingroup gnn_node_doc
00486  *
00487  * This function detroys the node given as a parameter: it calls first the
00488  * installed destructor and the \ref gnn_node_destroy_structure to destroy
00489  * itself.
00490  *
00491  * This is a virtual function: the specific destruction of the node is given
00492  * by the installed \ref gnn_node::destroy function, and the destruction of
00493  * the underlying's node structure by itself is performed by
00494  * \ref gnn_node_destroy_structure.
00495  *
00496  * @warning Only root nodes can be destroyed.
00497  *
00498  * @param  node A pointer to an \ref gnn_node.
00499  * @return Returns 0 if succeeded.
00500  */
00501 int
00502 gnn_node_destroy (gnn_node *node)
00503 {
00504     int i;
00505     gnn_node *subnode;
00506     
00507     assert (node != NULL);
00508     
00509     /* check that node isn't subnode */
00510     if (node->super != NULL)
00511         GSL_ERROR ("only root nodes can be destroyed", GSL_EINVAL);
00512 
00513     /* call destructor */
00514     node->destroy (node);
00515 
00516     /* destroy subyacent node structure */
00517     gnn_node_destroy_structure (node);
00518     
00519     return 0;
00520 }
00521 
00522 /**
00523  * @brief Evaluates the output of the function recursively.
00524  * @ingroup gnn_node_doc
00525  *
00526  * This function computes the output of the node's function. First, it sets the
00527  * appropiate values for initiating the recursive evaluation, and then calls
00528  * \ref gnn_node_eval_f.
00529  *
00530  * @warning: If you want to compute \f$\frac{\partial E}{\partial x}\f$, then
00531  *           you should not change the content of the input buffer \f$x\f$.
00532  *
00533  * @param  node A pointer to an \ref gnn_node.
00534  * @param  x    The input vector \f$x\f$ of the correct size that should be
00535  *              evaluated.
00536  * @param  y    A gsl_vector, where the result should be placed.
00537  * @return Returns 0 if suceeded.
00538  */
00539 int
00540 gnn_node_evaluate_f (gnn_node *node, const gsl_vector *x, gsl_vector *y)
00541 {
00542     assert (node != NULL);
00543 
00544     /* check sizes */
00545     if (   (x == NULL && node->n != 0)
00546         || (x != NULL && node->n != x->size))
00547         GSL_ERROR ("incorrect size of x vector", GSL_EINVAL);
00548 
00549     if (   (y == NULL && node->m != 0)
00550         || (y != NULL && node->m != y->size))
00551         GSL_ERROR ("incorrect size of y vector", GSL_EINVAL);
00552 
00553     /* clear y vector */
00554     gsl_vector_set_zero (y);
00555 
00556     /* call evaluation */
00557     gnn_node_eval_f (node, x, y);
00558 
00559     return 0;
00560 }
00561 
00562 /**
00563  * @brief Initializes the evaluations.
00564  * @ingroup gnn_node_doc
00565  *
00566  * This function initializes the gradient evaluation routines. It should be
00567  * called before \ref gnn_node_eval_f, for every single pattern or input
00568  * evaluation. The complete sequence for evaluations is:
00569  *
00570  * - \ref gnn_node_evaluate_init
00571  * - \ref gnn_node_evaluate_f
00572  * - \ref gnn_criterion_e
00573  * - \ref gnn_criterion_de
00574  * - \ref gnn_node_evaluate_dx
00575  * - \ref gnn_node_evaluate_dw
00576  *
00577  * @param  node A pointer to an \ref gnn_node.
00578  * @return Returns 0 if suceeded.
00579  */
00580 int
00581 gnn_node_evaluate_init (gnn_node *node)
00582 {
00583     assert (node != NULL);
00584 
00585     /* clear gradient */
00586     gnn_pbundle_set_dw_all (node->pb, 0.0);
00587 
00588     return 0;
00589 }
00590 
00591 /**
00592  * @brief Evaluates the gradient \f$\frac{\partial E}{\partial x}\f$.
00593  * @ingroup gnn_node_doc
00594  *
00595  * This function computes \f$\frac{\partial E}{\partial x}\f$ of the node's
00596  * function. First, it sets the
00597  * appropiate values for initiating the recursive evaluation, and then calls
00598  * \ref gnn_node_eval_dx.
00599  *
00600  * @warning: The \f$\frac{\partial E}{\partial x}\f$ gradient will be evaluated
00601  *           at \f$(x,w)\f$, where \f$x\f$ is the last evaluated input vector,
00602  *           and \f$w\f$ is the last parameter vector. That is, the last values
00603  *           given at \ref gnn_node_evaluate_f.
00604  *
00605  * @param  node A pointer to an \ref gnn_node.
00606  * @param  dy   The \f$\frac{\partial E}{\partial y}\f$ vector.
00607  * @param  dx   A gsl_vector, where the result should be placed.
00608  * @return Returns 0 if suceeded.
00609  */
00610 int
00611 gnn_node_evaluate_dx (gnn_node         *node,
00612                       const gsl_vector *dy,
00613                       gsl_vector       *dx)
00614 {
00615     assert (node != NULL);
00616     assert (dy   != NULL);
00617     assert (dx   != NULL);
00618 
00619     /* check sizes */
00620     if (dy->size != node->m)
00621         GSL_ERROR ("incorrect size of dy vector", GSL_EINVAL);
00622 
00623     if (dx->size != node->n)
00624         GSL_ERROR ("incorrect size of dx vector", GSL_EINVAL);
00625 
00626     /* clear dx vector */
00627     gsl_vector_set_zero (dx);
00628     
00629     /* call gradient evaluation */
00630     return gnn_node_eval_dx (node, dy, dx);
00631 }
00632 
00633 /**
00634  * @brief Evaluates the gradient \f$\frac{\partial E}{\partial w}\f$.
00635  * @ingroup gnn_node_doc
00636  *
00637  * This function computes \f$\frac{\partial E}{\partial w}\f$ of the node's
00638  * function. First, it sets the
00639  * appropiate values for initiating the recursive evaluation, and then calls
00640  * \ref gnn_node_eval_dw.
00641  *
00642  * @warning: The \f$\frac{\partial E}{\partial w}\f$ gradient will be evaluated
00643  *           at \f$(x,w)\f$, where \f$x\f$ is the last evaluated input vector,
00644  *           and \f$w\f$ is the last parameter vector. Also, it will use
00645  *           the last given \f$\frac{\partial E}{\partial x}\f$ for its
00646  *           error-backpropagation. In other words, the buffers used for
00647  *           both \ref gnn_node_evaluate_f and \ref gnn_node_evaluate_dx
00648  *           shouldn't have changed!
00649  *
00650  * @param  node A pointer to an \ref gnn_node.
00651  * @param  dw   A gsl_vector, where the result should be placed.
00652  * @return Returns 0 if suceeded.
00653  */
00654 int
00655 gnn_node_evaluate_dw (gnn_node         *node,
00656                       gsl_vector       *dw)
00657 {
00658     int size;
00659 
00660     assert (node != NULL);
00661     assert (dw   != NULL);
00662 
00663     /* get bundle size */
00664     size = gnn_pbundle_get_size (node->pb);
00665 
00666     /* check sizes */
00667     if (size == 0)
00668         GSL_ERROR ("node doesn't contain any parameters", GSL_EINVAL);
00669 
00670     if (size != dw->size)
00671         GSL_ERROR ("incorrect size of dw vector", GSL_EINVAL);
00672 
00673     /* call recursive gradient evaluation */
00674     gnn_node_eval_dw (node);
00675 
00676     /* copy gradient result */
00677     gnn_pbundle_get_dw (node->pb, dw);
00678 
00679     return 0;
00680 }
00681 
00682 
00683 
00684 /*****************/
00685 /* Parameter API */
00686 /*****************/
00687 
00688 /**
00689  * @brief Set of functions for the manipulation of a node's parameters.
00690  * @defgroup gnn_node_param_doc gnn_node Parameters API
00691  * @ingroup gnn_node_doc
00692  *
00693  * The Parameter API (Applicaction Programming Interface) provides
00694  * extended functionality to manipulate a \ref gnn_node's parameters.
00695  *
00696  * Every \ref gnn_node contains a set of parameters (it can be empty of
00697  * course). By changing them, the function's behaviour is changed. Formally,
00698  * the parameters allow the model to be adapted to a particular case.
00699  * It is, therefore, very important to provide extended functionality for
00700  * manipulating them.
00701  *
00702  * Every node contains two types of parameters:
00703  *
00704  * - The node's own parameters.
00705  * - The node's total parameters, which are formed by all parameters in the
00706  *   tree rooted at the current node.
00707  *
00708  * Schematically, this can be depicted as (for an atomic node):
00709  *
00710  * <img src="images/gnn_node2.png" border="0">
00711  *
00712  * When two nodes <i>A</i> and <i>B</i> are composed using a third node
00713  * <i>C</i>, then <i>C</i> will be at the root, and will provide direct
00714  * access to all parameters (that is, the parameters of the whole tree):
00715  *
00716  *  <img src="images/gnn_node3.png" border="0">
00717  *
00718  * This is absolutely transparent to the programmer. Note that each node
00719  * knows exactly which ones are its local parameters, but to get direct
00720  * access to them, <b>use the extension API</b>.
00721  *
00722  * Note that in general, a node which is not a leaf rarely posseses its own
00723  * parameters.
00724  *
00725  * The good thing here is that you gain direct access to the new
00726  * (concatenated) parameter as it were a single vector.
00727  *
00728  * There are two more objects you should know of: the gradient with respect
00729  * to the parameters, and the freeze flags, both vectors of the same size
00730  * as the parameter vector. The first is a buffer, were the gradient should
00731  * be computed. The second is a special flag vector: they specify if a given
00732  * parameter is actually free to be changed (free parameter) of if it has
00733  * been frozen (and can't be changed). These additional vectors can also be
00734  * manipulated using this interface.
00735  *
00736  *
00737  *
00738  * <b>Some technical details:</b>
00739  *
00740  * So, the node accesses its local parameters (which are some kind of "global"
00741  * and independent entities that can perfectly be shared with other nodes)
00742  * through a parameter handle.
00743  *
00744  * Simultaneously, the node also posseses a special parameter bundle, which
00745  * gives him access to the whole tree's parameters.
00746  *
00747  * Although it can be useful to know about the internal details of the
00748  * parameter managing and its implementation, the \ref gnn_node_param_doc
00749  * provides a transparent set of functions to manipulate them. The important
00750  * things to note are:
00751  *
00752  * - Each node has local and total parameters.
00753  *
00754  */
00755  
00756  
00757  
00758 /**
00759  * @brief Returns the size of the parameter vector.
00760  * @ingroup gnn_node_param_doc
00761  *
00762  * This function returns \f$l\f$, the size of the parameter vector.
00763  *
00764  * @param  node A pointer to an \ref gnn_node.
00765  * @return The size of the parameter vector \f$w\f$.
00766  */
00767 int
00768 gnn_node_param_get_size (gnn_node *node)
00769 {
00770     assert (node != NULL);
00771     return gnn_pbundle_get_size (node->pb);
00772 }
00773 
00774 /**
00775  * @brief Get the node's parameters.
00776  * @ingroup gnn_node_param_doc
00777  *
00778  * This function fills the input buffer w with the node's parameter values.
00779  *
00780  * Implementation Note: The parameter vector is build with the node's
00781  *                      parameter bundle.
00782  *
00783  * @param  node A pointer to an \ref gnn_node.
00784  * @param  w    A gsl_vector sufficiently large to store the values.
00785  * @return Returns 0 if suceeded.
00786  */
00787 int
00788 gnn_node_param_get (gnn_node *node, gsl_vector *w)
00789 {
00790     assert (node != NULL);
00791     return gnn_pbundle_get_w (node->pb, w);
00792 }
00793 
00794 /**
00795  * @brief Sets new values for the parameter vector.
00796  * @ingroup gnn_node_param_doc
00797  *
00798  * This function sets new values for the node's parameter vector. The new
00799  * values are taken by the buffer w (of the correct size) given as input
00800  * argument.
00801  *
00802  * @param  node A pointer to an \ref gnn_node.
00803  * @param  w    A gsl_vector containing the new values for the parameter vector.
00804  * @return Returns 0 if suceeded.
00805  */
00806 int
00807 gnn_node_param_set (gnn_node *node, const gsl_vector *w)
00808 {
00809     assert (node != NULL);
00810     return gnn_pbundle_set_w (node->pb, w);
00811 }
00812 
00813 /**
00814  * @brief Get the freeze flags.
00815  * @ingroup gnn_node_param_doc
00816  *
00817  * This function fills the given integer vector \a f with the node's freeze
00818  * flags.
00819  *
00820  * Implementation Note: The parameter vector is build with the node's
00821  *                      parameter bundle.
00822  *
00823  * @param  node A pointer to an \ref gnn_node.
00824  * @param  f    A \c gsl_vector_int sufficiently large to store the values.
00825  * @return Returns 0 if suceeded.
00826  */
00827 int
00828 gnn_node_param_freeze_flags_get (gnn_node *node, gsl_vector_int *f)
00829 {
00830     assert (node != NULL);
00831     return gnn_pbundle_get_f (node->pb, f);
00832 }
00833 
00834 /**
00835  * @brief Sets new freeze flags.
00836  * @ingroup gnn_node_param_doc
00837  *
00838  * This function sets new freeze flags for the node. They should be given
00839  * as a \c gsl_vector_int, where 1=freeze and 0=free-parameter.
00840  *
00841  * @param  node A pointer to an \ref gnn_node.
00842  * @param  f    A \c gsl_vector_int containing the new values for the
00843  *              parameter vector.
00844  * @return Returns 0 if suceeded.
00845  */
00846 int
00847 gnn_node_param_freeze_flags_set (gnn_node *node, const gsl_vector_int *f)
00848 {
00849     assert (node != NULL);
00850     return gnn_pbundle_set_f (node->pb, f);
00851 }
00852 
00853 /**
00854  * @brief Freeze the i-th parameter.
00855  * @ingroup gnn_node_param_doc
00856  *
00857  * This function freezes the i-th parameter.
00858  *
00859  * @param  node A pointer to an \ref gnn_node.
00860  * @param  i    The index of the parameter to be frozen.
00861  * @return Returns 0 if suceeded.
00862  */
00863 int
00864 gnn_node_param_freeze (gnn_node *node, int i)
00865 {
00866     assert (node != NULL);
00867     return gnn_pbundle_set_f_at (node->pb, i, 1);
00868 }
00869 
00870 /**
00871  * @brief Unfreeze the i-th parameter.
00872  * @ingroup gnn_node_param_doc
00873  *
00874  * This function unfreezes the i-th parameter.
00875  *
00876  * @param  node A pointer to an \ref gnn_node.
00877  * @param  i    The index of the parameter to be unfrozen.
00878  * @return Returns 0 if suceeded.
00879  */
00880 int
00881 gnn_node_param_unfreeze (gnn_node *node, int i)
00882 {
00883     assert (node != NULL);
00884     return gnn_pbundle_set_f_at (node->pb, i, 0);
00885 }
00886 
00887 /**
00888  * @brief Check if the i-th parameter is frozen.
00889  * @ingroup gnn_node_param_doc
00890  *
00891  * This function returns 1 if the i-th parameter is frozen.
00892  *
00893  * @param  node A pointer to an \ref gnn_node.
00894  * @param  i    The index of the parameter to be checked.
00895  * @return Returns 1 if frozen, 0 if not.
00896  */
00897 int
00898 gnn_node_param_is_frozen (gnn_node *node, int i)
00899 {
00900     assert (node != NULL);
00901     return gnn_pbundle_get_f_at (node->pb, i);
00902 }
00903 
00904 /**
00905  * @brief Check if all the node's parameters are frozen.
00906  * @ingroup gnn_node_param_doc
00907  *
00908  * This function returns 1 if all parameters are frozen.
00909  *
00910  * @param  node A pointer to an \ref gnn_node.
00911  * @return Returns 1 if frozen, 0 if not.
00912  */
00913 int
00914 gnn_node_param_are_frozen (gnn_node *node)
00915 {
00916     assert (node != NULL);
00917     if (gnn_pbundle_get_n_free (node->pb) == 0)
00918         return 1;
00919     else
00920         return 0;
00921 }
00922 
00923 /**
00924  * @brief Freeze all parameters.
00925  * @ingroup gnn_node_param_doc
00926  *
00927  * This function freezes all the node's parameters.
00928  *
00929  * @param  node A pointer to an \ref gnn_node.
00930  * @return Returns 0 if suceeded.
00931  */
00932 int
00933 gnn_node_param_freeze_all (gnn_node *node)
00934 {
00935     assert (node != NULL);
00936     return gnn_pbundle_set_f_all (node->pb, 1);
00937 }
00938 
00939 /**
00940  * @brief Unfreeze all parameters.
00941  * @ingroup gnn_node_param_doc
00942  *
00943  * This function unfreezes all the node's parameters.
00944  *
00945  * @param  node A pointer to an \ref gnn_node.
00946  * @return Returns 0 if suceeded.
00947  */
00948 int
00949 gnn_node_param_unfreeze_all (gnn_node *node)
00950 {
00951     assert (node != NULL);
00952     return gnn_pbundle_set_f_all (node->pb, 0);
00953 }
00954 
00955 /**
00956  * @brief Share the node's parameters.
00957  * @ingroup gnn_node_param_doc
00958  *
00959  * This function share the node's parameters with the client node.
00960  *
00961  * @warning: This function should be called on nodes that aren't connected only.
00962  *
00963  * @param  node   A pointer to an \ref gnn_node.
00964  * @param  client A pointer to an \ref gnn_node.
00965  * @return Returns 0 if suceeded.
00966  */
00967 int
00968 gnn_node_param_share (const gnn_node *node, gnn_node *client)
00969 {
00970     assert (node   != NULL);
00971     assert (client != NULL);
00972 
00973     /* check if both nodes haven't any parent nor children */
00974     if (   (node->super   != NULL)
00975         || (node->sub     != NULL)
00976         || (client->super != NULL)
00977         || (client->sub   != NULL))
00978         GSL_ERROR ("can't share a connected node's parameters", GSL_EINVAL);
00979 
00980     /* check parameter sizes */
00981     if (gnn_phandle_get_size (node->ph) != gnn_phandle_get_size (client->ph))
00982         GSL_ERROR ("can't share parameters of distinct size", GSL_EINVAL);
00983 
00984     /* free the client's parameters */
00985     gnn_pbundle_destroy (client->pb);
00986     gnn_phandle_unref (client->ph);
00987 
00988     /* share parameters */
00989     client->pb = node->pb;
00990     client->ph = node->ph;
00991 
00992     return 0;
00993 }
00994 
00995 
00996 
00997 /*****************/
00998 /* Extension API */
00999 /*****************/
01000 
01001 /**
01002  * @brief A set of functions for implementing an extension of gnn_node.
01003  * @defgroup gnn_node_ext_doc gnn_node Extension API
01004  * @ingroup gnn_node_doc
01005  *
01006  * The Extension API (Applicaction Programming Interface) provides
01007  * extended functionality to program new \ref libgnn node.
01008  *
01009  * <b>What is the Extension API's purpose?</b>
01010  *
01011  * The Extension API has been designed in order to provide a framework
01012  * to include custom node types, i.e. nodes that compute a specific
01013  * function that isn't included in the \ref libgnn distribution.
01014  *
01015  * The node types included in the distribution have also been built upon
01016  * this programming interface.
01017  *
01018  * <b>Basics</b>
01019  *
01020  * Creating a new node type requires the programmer to implement at least
01021  * 4 functions, which describe/incarnate the behaviour of the node, and
01022  * are attached to the new node type.
01023  *
01024  * All node types should built upon a basic node type: the \ref gnn_node.
01025  * The C structure which will implement the node type should contain, as
01026  * it's first field, a \ref gnn_node, followed by the additional data field
01027  * the node might need. Per example:
01028  *
01029  * \code
01030    // it's always nice to have a type definition
01031    typedef struct _myNodeType myNodeType;
01032  
01033    // the structure definition
01034    struct _myNodeType
01035    {
01036        gnn_node node;     // the underlying gnn_node
01037        
01038        // now comes the rest
01039        int    exampleField1;
01040        double exampleField2;
01041        ...
01042    }
01043    \endcode
01044  *
01045  * To create a custom node, you should provide a constructor. The constructor
01046  * should take the needed info to describe your new instance fully. The
01047  * constructor should allocate memory for the new structure, and initialize
01048  * the underlying \ref gnn_node, by calling the \ref gnn_node_init function:
01049  *
01050  * <i>Example for an Atomic Node Type:</i>
01051  *
01052    \code
01053    // you should return a gnn_node pointer to the new instance
01054    gnn_node *
01055    my_node_new (int input_size, int output_size, int param_size, ...)
01056    {
01057         gnn_node   *node;
01058         myNodeType *mynode;
01059 
01060         // allocate memory for your node type
01061         mynode = (myNodeType *) malloc (sizeof (myNodeType));
01062         
01063         // get a pointer to the instance, but viewed as a gnn_node :
01064         node = (gnn_node *) mynode;
01065         
01066         // call the initialization function
01067         gnn_node_init ( node,
01068                         "myNodeType",
01069                         my_node_type_f,
01070                         my_node_type_dx,
01071                         my_node_type_dw,
01072                         my_node_type_dest
01073                       );
01074 
01075         // if this node were a constructor node,
01076         // then install the subnodes HERE! In example, calling
01077         // gnn_node_sub_install_node_vector ...
01078 
01079         // initialize the node sizes
01080         gnn_node_set_sizes (node, input_size, output_size, param_size);
01081 
01082         // initialize the rest your node type might need
01083         ...
01084         
01085         // finally, return a pointer to the your instance as a gnn_node
01086         return node;
01087    }
01088 
01089    \endcode
01090  *
01091  * The \ref gnn_node_init function takes a pointer to the node, a string
01092  * which describes the node type, plus 4 additional functions:
01093  *
01094  * -# The evaluation of the function. (\ref gnn_node_f)
01095  * -# The gradient with respect to the inputs evaluation function.
01096  *    (\ref gnn_node_df)
01097  * -# The gradient with respect to the parameters evaluation function.
01098  *    (\ref gnn_node_df)
01099  * -# The destructor, which frees the memory. (\ref gnn_node_destructor)
01100  *
01101  * Basically, all these functions have specific datatypes that you should
01102  * respect. All these functions shouldn't access the underlying \ref gnn_node's
01103  * fields <b>ONLY</b> through the Extension API.
01104  *
01105  * <b>Coding Standards</b>
01106  *
01107  * The \ref libgnn library has been coded respecting a coding standard that
01108  * hasn't been documented yet :-) . But basically, you should look at
01109  * its source code and try to code as similar as posible. Some things you
01110  * <b>must</b> respect:
01111  *
01112  * -# Always provide a \c .h and a \c .c file. The first should contain
01113  *    the public interface definition, and the second, the implementation.
01114  *    Always protect the header file with \c #ifdef construct from multiple
01115  *    inclusion. The implementation should depend <b>only</b> on those
01116  *    files that it <b>really</b> needs.
01117  * -# Provide all necessary parameter manipulation functions. This is
01118  *    very important. Most nodes do have a differente way to view the
01119  *    parameters, i.e. not as a single vector, but as a vector and a
01120  *    matrix per example. Then, provide function calls to set new
01121  *    values and to freeze/unfreeze them. After <b>any</b> manipulation
01122  *    of parameters, gradients and/or freeze flags, you should call
01123  *    the \ref gnn_node_local_update routine.
01124  * -# Be very carefull when you try to optimize the evaluation routines.
01125  *    It is better to take and use only the objects that have been passed
01126  *    as arguments. <b>It is a very bad idea to use buffers for speeding up
01127  *    the cascade-evaluation of gradients!</b> If the gradients <b>do need</b>
01128  *    values that have been computed previously, then <b>recompute them</b>.
01129  * -# Document your heavily! There's nothing worse than undocumented source
01130  *    code, or <b>bad</b> documented code. If you don't want to find yourself
01131  *    in hell, then provide rich and intelligent documentation. Use the
01132  *    Doxygen commands to enhance and format.
01133  *
01134  */
01135 
01136 
01137  
01138 /**
01139  * @brief Initializes a \ref gnn_node structure.
01140  * @ingroup gnn_node_ext_doc
01141  *
01142  * This function initializes a \ref gnn_node structure. The memory for
01143  * the structure should be allocated manually. The sizes should be set after
01144  * calling this function.
01145  *
01146  * An example of its use is the following:
01147  *
01148    \code
01149    gnn_node *
01150    gnn_mifunction (int input_size, int output_size, int param_size)
01151    {
01152         gnn_node *node;
01153 
01154         node = (gnn_node *) malloc (sizeof (*node));
01155         gnn_node_init ( node,
01156                         "gnn_mifunction",
01157                         gnn_mifunction_f,
01158                         gnn_mifunction_dx,
01159                         gnn_mifunction_dw,
01160                         gnn_mifunction_dest);
01161 
01162         gnn_node_set_sizes (input_size, output_size, param_size);
01163 
01164         // initialize the rest
01165         ...
01166    \endcode
01167  *
01168  * If one of the function pointers is NULL, then it installs the
01169  * default functions:
01170  * - \ref gnn_node_default_f for    'f = NULL'
01171  * - \ref gnn_node_default_dedw for 'dedw = NULL'
01172  * - \ref gnn_node_default_dedx for 'dedx = NULL'
01173  * - \ref gnn_node_default_destructor for 'dest = NULL'
01174  *
01175  * @param node        A pointer to the node to be initialized.
01176  * @param type        A string containing the name of the layer's type. The
01177  *                    node will build a copy.
01178  * @param f     A pointer to the evaluation function.
01179  * @param dx    A pointer to the \f$\frac{\partial E}{\partial x}\f$ function.
01180  * @param dw    A pointer to the \f$\frac{\partial E}{\partial w}\f$ function.
01181  * @param dest  A pointer to the destroy function.
01182  * @return      0 on success.
01183  */
01184 int
01185 gnn_node_init (gnn_node           *node,
01186                const char         *type,
01187                gnn_node_f          f,
01188                gnn_node_df         dx,
01189                gnn_node_df         dw,
01190                gnn_node_destructor dest)
01191 {
01192     assert (node != NULL);
01193 
01194     /* set fields */
01195     node->type  = strdup (type);
01196     node->n     = 0;
01197     node->m     = 0;
01198     node->super = NULL;
01199     node->nsub  = 0;
01200     node->sub   = NULL;
01201     node->f       = gnn_node_default_f;
01202     node->dx      = gnn_node_default_dx;
01203     node->dw      = gnn_node_default_dw;
01204     node->destroy = gnn_node_default_destructor;
01205 
01206     /* set parameters */
01207     node->pb = gnn_pbundle_new ();
01208     node->ph = NULL;
01209 
01210     /* set functions */
01211     if (f != NULL)
01212         node->f = f;
01213 
01214     if (dx != NULL)
01215         node->dx = dx;
01216 
01217     if (dx != NULL)
01218         node->dw = dw;
01219 
01220     if (dest != NULL)
01221         node->destroy = dest;
01222 
01223     return 0;
01224 }
01225 
01226 /**
01227  * @brief Set the node's sizes.
01228  * @ingroup gnn_node_ext_doc
01229  *
01230  * This function sets the node's sizes for its input, output and parameter
01231  * vector. It should be called after calling the \ref gnn_node_init (and
01232  * the \ref gnn_node_sub_install in case of a constructor node) function.
01233  *
01234  * @warning It is not allowed to call this function twice for the same node.
01235  *
01236  * @param  node A pointer to an \ref gnn_node.
01237  * @param  n    The size of the node's input.
01238  * @param  m    The size of the node's output.
01239  * @param  l    The size of the node's parameter vector.
01240  * @return Returns 0 if succeeded.
01241  */
01242 int
01243 gnn_node_set_sizes (gnn_node *node, int n, int m, int l)
01244 {
01245     assert (node != NULL);
01246 
01247     node->n = n;
01248     node->m = m;
01249 
01250     /* check if parameters aren't installed yet */
01251     if (node->ph != NULL)
01252         GSL_ERROR ("parameters are already installed", GSL_EINVAL);
01253         
01254     /* set parameters */
01255     node->ph = gnn_phandle_new (l);
01256     if (l > 0)
01257         gnn_pbundle_insert (node->pb, node->ph, 1);
01258     
01259     return 0;
01260 }
01261 
01262 /**
01263  * @brief Get local parameters.
01264  * @ingroup gnn_node_ext_doc
01265  *
01266  * This function returns a pointer to the node's own parameters.
01267  * The returning vector is the parameter vector itself and its values can
01268  * be freely changed. When finished, call \ref gnn_node_local_update.
01269  *
01270  * @param  node A pointer to an \ref gnn_node.
01271  * @return Returns a pointer to the internal parameter vector \f$w\f$.
01272  */
01273 gsl_vector *
01274 gnn_node_local_get_w (gnn_node *node)
01275 {
01276     assert (node != NULL);
01277     return gnn_phandle_get_w (node->ph);
01278 }
01279 
01280 /**
01281  * @brief Get local parameter gradients.
01282  * @ingroup gnn_node_ext_doc
01283  *
01284  * This function returns a pointer to the node's own parameters gradient
01285  * \f$\frac{\partial E}{\partial w}\f$.
01286  * The returning vector is the gradient itself and its values can
01287  * be freely changed. When finished, call \ref gnn_node_local_update.
01288  *
01289  * @param  node A pointer to an \ref gnn_node.
01290  * @return Returns a pointer to the internal
01291  *         \f$\frac{\partial E}{\partial w}\f$ vector.
01292  */
01293 gsl_vector *
01294 gnn_node_local_get_dw (gnn_node *node)
01295 {
01296     assert (node != NULL);
01297     return gnn_phandle_get_dw (node->ph);
01298 }
01299 
01300 /**
01301  * @brief Get local parameters frozen flags.
01302  * @ingroup gnn_node_ext_doc
01303  *
01304  * This function returns a pointer to the node's own parameters frozen flags.
01305  * The returning vector is the flags vector itself and its values can be freely
01306  * changed. When finished, call \ref gnn_node_local_update.
01307  *
01308  * The values should be binary: 0 means that the parameter is free, and
01309  * 1 (non-zero) means that the parameter is frozen (fixed).
01310  *
01311  * @param  node A pointer to an \ref gnn_node.
01312  * @return Returns a pointer to the internal flags vector.
01313  */
01314 gsl_vector_int *
01315 gnn_node_local_get_f (gnn_node *node)
01316 {
01317     assert (node != NULL);
01318     return gnn_phandle_get_f (node->ph);
01319 }
01320 
01321 /**
01322  * @brief Get local parameters.
01323  * @ingroup gnn_node_ext_doc
01324  *
01325  * This function updates the local parameters and its changes. This function
01326  * should be called after any change in the parameters to make them effective.
01327  *
01328  * @param  node A pointer to an \ref gnn_node.
01329  * @return Returns a pointer to the internal parameter vector \f$w\f$.
01330  */
01331 int
01332 gnn_node_local_update (gnn_node *node)
01333 {
01334     assert (node != NULL);
01335     return gnn_phandle_update (node->ph);
01336 }
01337 
01338 /**
01339  * @brief Evaluates the output of the function recursively.
01340  * @ingroup gnn_node_ext_doc
01341  *
01342  * This function calls the installed \ref gnn_node::f function with the
01343  * appropiate arguments.
01344  *
01345  * This function should only be called from construction node's evaluation
01346  * functions. If you want to evaluate it from outside, you should call
01347  * \gnn_node_eval_f instead, which initiates the recursion parameters
01348  * appropiatelly.
01349  *
01350  * @param  node A pointer to an \ref gnn_node.
01351  * @param  x    The input vector to be evaluated.
01352  * @param  y    A gsl_vector, where the result should be placed.
01353  * @return Returns 0 if suceeded.
01354  */
01355 int
01356 gnn_node_eval_f (gnn_node *node, const gsl_vector *x, gsl_vector *y)
01357 {
01358     int status;
01359 
01360     assert (node != NULL);
01361 
01362     /* set pointer to last input */
01363     node->x = *x;
01364     
01365     /* call evaluation */
01366     status = node->f (node, &(node->x), gnn_phandle_get_w (node->ph), y);
01367     if (status)
01368         GSL_ERROR ("error computing y", GSL_ERANGE);
01369 
01370     return 0;
01371 }
01372 
01373 /**
01374  * @brief Evaluates \f$\frac{\partial E}{\partial x}\f$ recursively.
01375  * @ingroup gnn_node_ext_doc
01376  *
01377  * This function calls the installed \ref gnn_node::dx function with the
01378  * appropiate arguments.
01379  *
01380  * This function should only be called from construction node's evaluation
01381  * functions. If you want to evaluate it from outside, you should call
01382  * \gnn_node_eval_dx instead, which initiates the recursion parameters
01383  * appropiatelly.
01384  *
01385  * @param  node A pointer to an \ref gnn_node.
01386  * @param  dx   A gsl_vector, where the result should be placed.
01387  * @return Returns 0 if suceeded.
01388  */
01389 int
01390 gnn_node_eval_dx (gnn_node *node, const gsl_vector *dy, gsl_vector *dx)
01391 {
01392     int status;
01393 
01394     assert (node != NULL);
01395 
01396     /* set pointer to last input */
01397     node->dy = *dy;
01398     
01399     /* compute input gradient */
01400     status = node->dx (node,
01401                        &(node->x),
01402                        gnn_phandle_get_w (node->ph),
01403                        &(node->dy),
01404                        dx);
01405     if (status)
01406         GSL_ERROR ("error computing dw", GSL_ERANGE);
01407 
01408     return 0;
01409 }
01410 
01411 /**
01412  * @brief Evaluates \f$\frac{\partial E}{\partial w}\f$ recursively.
01413  * @ingroup gnn_node_ext_doc
01414  *
01415  * This function calls the installed \ref gnn_node::dw function with the
01416  * appropiate arguments.
01417  *
01418  * This function should only be called from construction node's evaluation
01419  * functions. If you want to evaluate it from outside, you should call
01420  * \gnn_node_eval_dw instead, which initiates the recursion parameters
01421  * appropiatelly.
01422  *
01423  * @param  node A pointer to an \ref gnn_node.
01424  * @return Returns 0 if suceeded.
01425  */
01426 int
01427 gnn_node_eval_dw (gnn_node *node)
01428 {
01429     int status;
01430 
01431     assert (node != NULL);
01432 
01433     /* if there aren't any free parameters,
01434        and the node is a leaf, return      */
01435     if (node->sub == NULL && gnn_phandle_get_free (node->ph) == 0)
01436         return 0;
01437 
01438     /* compute parameter gradient */
01439     status = node->dw (node,
01440                        &(node->x),
01441                        gnn_phandle_get_w (node->ph),
01442                        &(node->dy),
01443                        gnn_phandle_get_dw (node->ph));
01444 
01445     if (status)
01446         GSL_ERROR ("error computing dw", GSL_ERANGE);
01447 
01448     return 0;
01449 }
01450 
01451 
01452 
01453 /****************/
01454 /* Subnodes API */
01455 /****************/
01456 
01457 /**
01458  * @brief The API for connecting and traversing trees of nodes.
01459  * @defgroup gnn_node_sub_doc gnn_node Subnodes API
01460  * @ingroup gnn_node_doc
01461  *
01462  * This API provides the functionality for connecting and traversing
01463  * \ref gnn_node trees.
01464  *
01465  * Every \ref gnn_node can be connected to another node, forming a node tree.
01466  * A node can have a single parent node, called "supernode", and can also
01467  * have several children nodes, called "subnodes" in \ref libgnn.
01468  *
01469  * A node that contains subnodes is a node that computes a function whose
01470  * output depends on the result of each of the subnode's functions. Per
01471  * example, a \ref gnn_stack node is a special node who computes the
01472  * composition of each of its subnode's functions.
01473  *
01474  * In general, nodes that can have subnodes rarely have own parameters.
01475  * In \ref libgnn, these nodes are called "constructor" nodes, due to its
01476  * nature.
01477  *
01478  * Leaf nodes, that is, nodes that can't have subnodes (because it wouldn't
01479  * make any sense for them) are called "atomic" nodes, because they can't
01480  * be splitted into simpler nodes.
01481  *
01482  * There are several alternatives to install subnodes. The recommended scheme
01483  * is the following. First, declare a function with variable number of
01484  * arguments, that takes the \ref gnn_node to be installed. Then, call
01485  * the \ref gnn_node_sub_install function, like in this example code:
01486  *
01487  * \code
01488    // include the header file for variable
01489    // number of function arguments
01490    #include <stdarg.h>
01491    
01492    ...
01493    
01494    // Constructor for my own node type
01495    int
01496    gnn_mynode_new (int amount_subnodes, ...)
01497    {
01498        va_list argptr; // special data type for argument list
01499        int     status;
01500 
01501        va_start (argptr, amount_subnodes);
01502        status = gnn_node_sub_install (node, amount_subnodes, argptr);
01503        va_end (argptr);
01504 
01505        // do the rest
01506        ...
01507  * \endcode
01508  *
01509  * Once installed, a subnode at the i-th index can be recovered by calling the
01510  * \ref gnn_node_sub_get_node_at function.
01511  *
01512  * When destroying a node with \ref gnn_node_destroy, its subnodes are
01513  * automatically uninstalled.
01514  */
01515 
01516 
01517 /**
01518  * @brief Install subnodes.
01519  * @ingroup gnn_node_sub_doc
01520  *
01521  * This function installs the given nodes as subnodes.
01522  *
01523  * @param  node A pointer to an \ref gnn_node.
01524  * @param  nsub The number of subnodes.
01525  * @param  ...  A list of subnodes to be installed.
01526  * @return Returns 0 if suceeded.
01527  */
01528 int
01529 gnn_node_sub_install_specific (gnn_node *node, int nsub, ...)
01530 {
01531     va_list argptr;
01532     int     status;
01533 
01534     assert (node != NULL);
01535 
01536     va_start (argptr, nsub);
01537     status = gnn_node_sub_install (node, nsub, argptr);
01538     va_end (argptr);
01539 
01540     return status;
01541 }
01542 
01543 /**
01544  * @brief Install subnodes.
01545  * @ingroup gnn_node_sub_doc
01546  *
01547  * This function installs the given nodes as subnodes.
01548  *
01549  * @param  node A pointer to an \ref gnn_node.
01550  * @param  nsub The number of subnodes in the list.
01551  * @param  subs A va_list (C Standard Library) containing pointers to the
01552  *         subnodes to be installed.
01553  * @return Returns 0 if suceeded.
01554  */
01555 int
01556 gnn_node_sub_install (gnn_node *node, int nsub, va_list subs)
01557 {
01558     int i;
01559     gnn_node *ptr;
01560 
01561     assert (node != NULL);
01562     assert (nsub > 0);
01563 
01564     /* create node array */
01565     node->sub = (gnn_node **) calloc (sizeof (gnn_node *), nsub);
01566     if (node->sub == NULL)
01567         GSL_ERROR ("failed to create subnode array", GSL_ENOMEM);
01568 
01569     /* set number of subnodes */
01570     node->nsub = nsub;
01571 
01572     /* fill subnode array */
01573     for (i=0; i<nsub; ++i)
01574     {
01575         /* get the node from the parameter list */
01576         node->sub[i] = (gnn_node *) va_arg (subs, gnn_node *);
01577 
01578         if (node->sub[i] == NULL)
01579             GSL_ERROR ("error installing subnodes", GSL_EINVAL);
01580 
01581         /* set the "super" pointer */
01582         node->sub[i]->super = node;
01583 
01584         /* merge parameter bundles */
01585         gnn_pbundle_join (node->pb, node->sub[i]->pb);
01586     }
01587 
01588     return 0;
01589 }
01590 
01591 /**
01592  * @brief Install the nodes in the node vector as subnodes.
01593  * @ingroup gnn_node_sub_doc
01594  *
01595  * This function installs the non-NULL nodes in the node vector as subnodes.
01596  *
01597  * @param  node A pointer to an \ref gnn_node.
01598  * @param  vector A pointer to a \ref gnn_node_vector.
01599  * @return Returns 0 if suceeded.
01600  */
01601 int
01602 gnn_node_sub_install_node_vector (gnn_node *node, gnn_node_vector *vector)
01603 {
01604     size_t i;
01605     size_t j;
01606     size_t count;
01607     gnn_node *ptr;
01608 
01609     assert (node != NULL);
01610 
01611     /* count the number of non-null nodes */
01612     count = gnn_node_vector_count_nodes (vector);
01613 
01614     if (count < 1)
01615         GSL_ERROR ("the given vector doesn't contain any valid gnn_node",
01616                    GSL_EINVAL);
01617 
01618     /* create node array */
01619     node->sub = (gnn_node **) calloc (sizeof (gnn_node *), count);
01620     if (node->sub == NULL)
01621         GSL_ERROR ("failed to create subnode array", GSL_ENOMEM);
01622 
01623     /* set number of subnodes */
01624     node->nsub = count;
01625 
01626     /* fill subnode array */
01627     j = 0;
01628     for (i=0; i<vector->size; ++i)
01629     {
01630         /* check if there is a valid node */
01631         if (gnn_node_vector_get (vector, i) == NULL)
01632             continue;
01633 
01634         /* get node and install */
01635         node->sub[j] = gnn_node_vector_get (vector, i);
01636 
01637         /* set the "super" pointer */
01638         node->sub[j]->super = node;
01639 
01640         /* merge parameter bundles */
01641         gnn_pbundle_join (node->pb, node->sub[j]->pb);
01642         
01643         /* advance to next subnode element */
01644         j++;
01645     }
01646 
01647     return 0;
01648 }
01649 
01650 
01651 /**
01652  * @brief Get the number of subnodes.
01653  * @ingroup gnn_node_sub_doc
01654  *
01655  * This function returns the number of direct subnodes of the node.
01656  *
01657  * @param  node A pointer to an \ref gnn_node.
01658  * @return Returns the number of subnodes.
01659  */
01660 int
01661 gnn_node_sub_get_number (gnn_node *node)
01662 {
01663     assert (node != NULL);
01664     return node->nsub;
01665 }
01666 
01667 /**
01668  * @brief Get's the node's i-th subnode.
01669  * @ingroup gnn_node_sub_doc
01670  *
01671  * This function returns a pointer to the i-th subnode.
01672  *
01673  * @param  node A pointer to an \ref gnn_node.
01674  * @param  i The index of the subnode to be retrieved.
01675  * @return The pointer to the i-th subnode or NULL if failed.
01676  */
01677 gnn_node *
01678 gnn_node_sub_get_node_at (gnn_node *node, int i)
01679 {
01680     assert (node != NULL);
01681     assert (node->sub != NULL);
01682     assert (0 <= i && i < node->nsub);
01683 
01684     return node->sub[i];
01685 }
01686 
01687 /**
01688  * @brief Get all subnodes of a given type.
01689  * @ingroup gnn_node_sub_doc
01690  *
01691  * This function searches the whole node three for nodes of the given type,
01692  * and returns a parameter bundle of all their parameters.
01693  *
01694  * @param  node A pointer to an \ref gnn_node.
01695  * @param  type A string containing the type of the subnodes to be retrieved.
01696  * @return A \ref gnn_pbundle.
01697  */
01698 gnn_pbundle *
01699 gnn_node_sub_search_params (gnn_node *node, const char *type)
01700 {
01701     gnn_pbundle *pb;
01702     
01703     assert (node != NULL);
01704 
01705     /* create new parameter bundle */
01706     pb = gnn_pbundle_new ();
01707     
01708     /* call recursive function */
01709     gnn_node_sub_search_params_recurse (node, type, pb);
01710 
01711     return pb;
01712 }
01713 
01714 
01715 
01716 

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