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

gnn_pbundle.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file  gnn_pbundle.c
00003  *  @brief gnn_pbundle Implementation.
00004  *
00005  *  @date   : 15-08-03 02:13
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  * @brief Provides a unified view of multiple parameters.
00027  * @defgroup gnn_pbundle_doc gnn_pbundle : A Unified View of Parameter Sets.
00028  * @ingroup  gnn_node_doc
00029  *
00030  * The parameter bundle is a special datatype that holds the information of
00031  * multiple parameter handles. It hides its underlying compositional structure,
00032  * providing an unified access to the handles as it were a single parameter
00033  * vector.
00034  *
00035  * A bundle that starts with zero elements can be create with
00036  * \ref gnn_pbundle_new, and more \ref gnn_phandle can be
00037  * added with \ref gnn_pbundle_insert and removed with \ref gnn_pbundle_remove
00038  * functions. The bundle keeps track of the amount of times every handle has
00039  * been added.
00040  *
00041  * <img src="images/gnn_pbundle1.png">
00042  *
00043  * A bundle can me augmented with another bundle's element by invoking
00044  * the \ref gnn_pbundle_join function. To detach elements, use the
00045  * \ref gnn_pbundle_detach function. Each of this functions keep the
00046  * multiplicity counters consistent.
00047  *
00048  * By calling the \ref gnn_phandle_get function, you can retrieve the
00049  * bundle's parameter vector \f$w\f$, which is the ordered concatenation
00050  * of the \f$N\f$ subparameters of each of the handles:
00051  * \f[w = [w_1, w_2, \ldots, w_N]^t\f]
00052  * where \f$w_i\f$ is the \f$i\f$-th handle's parameter vector. The parameter's
00053  * total size is \ref gnn_pbundle_get_size.
00054  *
00055  * <img src="images/gnn_pbundle2.png">
00056  *
00057  * The specific order in which the handles are stored in the \ref gnn_pbundle
00058  * cannot be manipulated directly. It depends of the way the bundle was
00059  * built, i.e. on the order in which the elements were inserted. But, two
00060  * different bundles that were built by applying the same operations in the
00061  * same order are assured to be equal.
00062  *
00063  * The parameter \f$w\f$ can be accessed and manipulated using a set of
00064  * provided functions. Similarly, a set of analogous functions is available
00065  * for the gradient \f$\frac{\partial E}{\partial w}\f$ and the frozen flags
00066  * \f$f\f$.
00067  *
00068  * @note The inmplementation of bundles and handles is intimately related
00069  *       for efficiency reasons. Every change in one of both should be revised
00070  *       carefully.
00071  *
00072  * @warning The use of parameter bundles isn't thread safe at the time.
00073  */
00074 
00075 
00076 
00077 /******************************************/
00078 /* Include Files                          */
00079 /******************************************/
00080 
00081 #include <assert.h>
00082 #include <gsl/gsl_errno.h>
00083 #include "gnn_pbundle.h"
00084 #include "chunkallocator.h"
00085 
00086 
00087 /******************************************/
00088 /* Static Declaration                     */
00089 /******************************************/
00090 
00091 /**
00092  * @brief The internal \ref gnn_pbundle memory chunk allocator.
00093  * @ingroup gnn_pbundle_doc
00094  *
00095  * This static variable holds the internal memory chunk allocator for the
00096  * \ref gnn_pbundle type. Every single parameter bundle element is allocated
00097  * using this memory manager for efficiency.
00098  *
00099  * Because of its application-wide nature, the memory allocation scheme
00100  * isn't thread safe by now.
00101  */
00102 static chunkallocator *_ca = NULL;
00103 
00104 
00105 
00106 /******************************************/
00107 /* Public Interface Implementation        */
00108 /******************************************/
00109 
00110 /**
00111  * @brief Creates a new \ref gnn_pbundle.
00112  * @ingroup gnn_pbundle_doc
00113  *
00114  * This function allocates a new \ref gnn_pbundle with its values initialized
00115  * to zero parameter handles / elements.
00116  *
00117  * Implementation Note: The memory is managed (for efficiency) by a memory
00118  * chunk allocator.
00119  *
00120  * @return A pointer to the new \ref gnn_pbundle of NULL if failed.
00121  */
00122 gnn_pbundle *
00123 gnn_pbundle_new ()
00124 {
00125     gnn_pbundle *pb;
00126     
00127     /* initialize chunk allocator if not yet */
00128     if (_ca == NULL)
00129         _ca = chunkallocator_new (sizeof (gnn_pbundle));
00130 
00131     /* alloc */
00132     pb = (gnn_pbundle *) chunkallocator_alloc (_ca);
00133     if (pb == NULL)
00134         GSL_ERROR_VAL ("could not allocate memory for pbundle",
00135                                                              GSL_ENOMEM, NULL);
00136         
00137     /* set fields */
00138     pb->c    = 0;
00139     pb->ph   = NULL;
00140     pb->next = NULL;
00141     
00142     return pb;
00143 }
00144 
00145 /**
00146  * @brief Destroys a \ref gnn_pbundle.
00147  * @ingroup gnn_pbundle_doc
00148  *
00149  * This function destroys a given \ref gnn_pbundle by deallocating its memory
00150  * and by unreferencing the contained parameter handles.
00151  *
00152  * @return A pointer to the new \ref gnn_pbundle of NULL if failed.
00153  */
00154 void
00155 gnn_pbundle_destroy (gnn_pbundle *pb)
00156 {
00157     gnn_pbundle *ptr;
00158     gnn_pbundle *nextptr;
00159     
00160     assert (pb != NULL);
00161     
00162     ptr = pb;
00163     while (ptr != NULL)
00164     {
00165         gnn_pbundle *nextptr;
00166         
00167         nextptr = ptr->next;
00168         
00169         if (ptr->ph != NULL)
00170             gnn_phandle_unref (ptr->ph);
00171             
00172         chunkallocator_free (_ca, ptr);
00173         
00174         ptr = nextptr;
00175     }
00176 }
00177 
00178 /**
00179  * @brief Inserts a parameter handle into a parameter bundle.
00180  * @ingroup gnn_pbundle_doc
00181  *
00182  * This function takes a parameter bundle and a parameter handle as arguments.
00183  * It creates a new \ref gnn_pbundle element associated with the parameter
00184  * handle and inserts it into the bundle.
00185  * The argument "n" is the amount of times the given handle should be added.
00186  *
00187  * @param  pb A parameter bundle.
00188  * @param  ph A parameter handle.
00189  * @param  n  The multiplicity of the handle.
00190  * @return 0 if succeeded.
00191  */
00192 int
00193 gnn_pbundle_insert (gnn_pbundle *pb, gnn_phandle *ph, int n)
00194 {
00195     gnn_pbundle *ptr;
00196 
00197     assert (pb != NULL);
00198     assert (ph != NULL);
00199     
00200     /* search insertion place */
00201     ptr = pb;
00202     while ((ptr->next != NULL) && (ptr->next->ph != ph))
00203         ptr = ptr->next;
00204 
00205     /* insert */
00206     if (ptr->next == NULL)
00207     {
00208         /* alloc */
00209         ptr->next = (gnn_pbundle *) chunkallocator_alloc (_ca);
00210         if (ptr->next == NULL)
00211             GSL_ERROR ("could not alloc memory for pbundle", GSL_ENOMEM);
00212 
00213         ptr = ptr->next;
00214 
00215         /* set fields */
00216         ptr->c    = n;
00217         ptr->ph   = ph;
00218         ptr->next = NULL;
00219         
00220         /* increase handle's reference counter */
00221         gnn_phandle_ref (ptr->ph);
00222     }
00223     else
00224     {
00225         ptr = ptr->next;
00226         
00227         /* increase element multiplicity counter */
00228         ptr->c += n;
00229     }
00230 
00231     return 0;
00232 }
00233 
00234 /**
00235  * @brief Removes a parameter handle from a parameter bundle.
00236  * @ingroup gnn_pbundle_doc
00237  *
00238  * This function takes a parameter bundle and a parameter handle as arguments.
00239  * It removes "n" copies of the given parameter handle from the bundle.
00240  *
00241  * @param  pb A parameter bundle.
00242  * @param  ph A parameter handle.
00243  * @return 0 if succeeded.
00244  */
00245 int
00246 gnn_pbundle_remove (gnn_pbundle *pb, const gnn_phandle *ph, int n)
00247 {
00248     gnn_pbundle *ptr;
00249     
00250     assert (pb != NULL);
00251     assert (ph != NULL);
00252     
00253     /* find adecuate position */
00254     ptr = pb;
00255     while (pb->next != NULL && pb->next->ph != ph)
00256         ptr = ptr->next;
00257 
00258     /* remove if found */
00259     if (pb->next->ph == ph)
00260     {
00261         gnn_pbundle *found;
00262         
00263         found = ptr->next;
00264 
00265         /* decrease multiplicity counter */
00266         found->c -= n;
00267         
00268         /* remove if counter reached zero */
00269         if (found->c <= 0)
00270         {
00271             ptr->next = ptr->next->next;
00272             gnn_phandle_unref (found->ph);
00273             chunkallocator_free (found);
00274         }
00275     }
00276     else
00277         GSL_ERROR ("parameter handle could not be found in bundle", GSL_EINVAL);
00278     
00279     return 0;
00280 }
00281 
00282 /**
00283  * @brief Join two parameter bundles.
00284  * @ingroup gnn_pbundle_doc
00285  *
00286  * This function increases the parameter bundle "pb" with "pbop"'s elements
00287  * without changing the "pbop" bundle.
00288  *
00289  * @param  pb   A parameter bundle.
00290  * @param  pbop A parameter bundle.
00291  * @return 0 if suceeded.
00292  */
00293 int
00294 gnn_pbundle_join (gnn_pbundle *pb, const gnn_pbundle *pbop)
00295 {
00296     gnn_pbundle *ptr;
00297     
00298     assert (pb != NULL);
00299     assert (pbop != NULL);
00300     
00301     /* insert pbop's elements */
00302     ptr = pbop->next;
00303     while (ptr != NULL)
00304     {
00305         gnn_pbundle_insert (pb, ptr->ph, ptr->c);
00306         ptr = ptr->next;
00307     }
00308 
00309     return 0;
00310 }
00311 
00312 /**
00313  * @brief Detach a parameter bundle.
00314  * @ingroup gnn_pbundle_doc
00315  *
00316  * This function removes the parameter bundle "pbop" from "pb", respecting
00317  * the multiplicity of each element.
00318  *
00319  * @param  pb   A parameter bundle.
00320  * @param  pbop A parameter bundle.
00321  * @return 0 if suceeded.
00322  */
00323 int
00324 gnn_pbundle_detach (gnn_pbundle *pb, const gnn_pbundle *pbop)
00325 {
00326     gnn_pbundle *ptr;
00327     
00328     assert (pb != NULL);
00329     assert (pbop != NULL);
00330     
00331     /* remove pbop's elements */
00332     ptr = pbop->next;
00333     while (ptr != NULL)
00334     {
00335         gnn_pbundle_remove (pb, ptr->ph, ptr->c);
00336         ptr = ptr->next;
00337     }
00338 
00339     return 0;
00340 }
00341 
00342 /**
00343  * @brief Get the number of free parameters hold by the bundle.
00344  * @ingroup gnn_pbundle_doc
00345  *
00346  * This function returns the number of free parameters that the bundle manages.
00347  *
00348  * @param  pb A paramter bundle.
00349  * @return The number of free parameters.
00350  */
00351 int
00352 gnn_pbundle_get_n_free (gnn_pbundle *pb)
00353 {
00354     int c;
00355     gnn_pbundle *ptr;
00356 
00357     assert (pb != NULL);
00358 
00359     /* count */
00360     c   = 0;
00361     ptr = pb->next;
00362     while (ptr != NULL)
00363     {
00364         c += gnn_phandle_get_free (ptr->ph);
00365         ptr = ptr->next;
00366     }
00367 
00368     return c;
00369 }
00370 
00371 /**
00372  * @brief Get the size of the parameter hold by the bundle.
00373  * @ingroup gnn_pbundle_doc
00374  *
00375  * This function returns the number of parameters that the bundle manages.
00376  *
00377  * @param  pb A paramter bundle.
00378  * @return The number of total parameters.
00379  */
00380 int
00381 gnn_pbundle_get_size (gnn_pbundle *pb)
00382 {
00383     int c;
00384     gnn_pbundle *ptr;
00385 
00386     assert (pb != NULL);
00387 
00388     /* count */
00389     c   = 0;
00390     ptr = pb->next;
00391     while (ptr != NULL)
00392     {
00393         c += gnn_phandle_get_size (ptr->ph);
00394         ptr = ptr->next;
00395     }
00396 
00397     return c;
00398 }
00399 
00400 
00401 
00402 /**
00403  * @brief Get the complete parameter vector.
00404  * @ingroup gnn_pbundle_doc
00405  *
00406  * This function fills the given real vector with the parameter bundles
00407  * parameters.
00408  *
00409  * @param  pb A parameter bundle.
00410  * @param  w  A real vector of the correct size.
00411  * @return 0 if succeeded.
00412  */
00413 int
00414 gnn_pbundle_get_w (gnn_pbundle *pb, gsl_vector *w)
00415 {
00416     int poffset;
00417     gnn_pbundle *ptr;
00418 
00419     assert (pb != NULL);
00420 
00421     /* check null size */
00422     if (pb->next == NULL)
00423     {
00424         if (w != NULL)
00425             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00426         return 0;
00427     }
00428 
00429     /* copy values */
00430     poffset = 0;
00431     ptr     = pb->next;
00432     while (ptr != NULL)
00433     {
00434         size_t size;
00435         gsl_vector_view w_view;
00436 
00437         size = gnn_phandle_get_size (ptr->ph);
00438         if (size > 0)
00439         {
00440             w_view = gsl_vector_subvector (w, poffset, size);
00441             gsl_vector_memcpy (&(w_view.vector), gnn_phandle_get_w (ptr->ph));
00442         }
00443         
00444         poffset += size;
00445         ptr     = ptr->next;
00446     }
00447 
00448     return 0;
00449 }
00450 
00451 /**
00452  * @brief Set parameter vector.
00453  * @ingroup gnn_pbundle_doc
00454  *
00455  * This function takes fills the parameter bundle with the values given in
00456  * the real vector w. 
00457  *
00458  * @param  pb A pointer to a parameter bundle.
00459  * @param  w  A pointer to a real vector.
00460  * @return 0 if succeeded.
00461  */
00462 int
00463 gnn_pbundle_set_w (gnn_pbundle *pb, const gsl_vector *w)
00464 {
00465     int poffset;
00466     gnn_pbundle *ptr;
00467 
00468     assert (pb != NULL);
00469 
00470     /* check null size */
00471     if (pb->next == NULL)
00472     {
00473         if (w != NULL)
00474             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00475         return 0;
00476     }
00477 
00478     /* copy values */
00479     poffset = 0;
00480     ptr     = pb->next;
00481     while (ptr != NULL)
00482     {
00483         size_t size;
00484         gsl_vector_view w_view;
00485 
00486         size = gnn_phandle_get_size (ptr->ph);
00487         if (size > 0)
00488         {
00489             w_view = gsl_vector_subvector ((gsl_vector *) w, poffset, size);
00490             gsl_vector_memcpy (gnn_phandle_get_w (ptr->ph), &(w_view.vector));
00491         }
00492         
00493         poffset += size;
00494         ptr     = ptr->next;
00495     }
00496 
00497     return 0;
00498 }
00499 
00500 /**
00501  * @brief Set the i-th parameter.
00502  * @ingroup gnn_pbundle_doc
00503  *
00504  * @param  pb A parameter bundle.
00505  * @param  i  The index of the parameter to be set.
00506  * @param  wi The new value for the parameter.
00507  * @return 0 if succeeded.
00508  */
00509 int
00510 gnn_pbundle_set_w_at (gnn_pbundle *pb, size_t i, double wi)
00511 {
00512     int poffset;
00513     gnn_pbundle *ptr;
00514 
00515     assert (pb != NULL);
00516     assert (i >= 0);
00517 
00518     /* search position */
00519     poffset = 0;
00520     ptr     = pb->next;
00521     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
00522     {
00523         i  -= gnn_phandle_get_size (ptr->ph);
00524         ptr = ptr->next;
00525     }
00526 
00527     /* set value */
00528     if (ptr == NULL)
00529         GSL_ERROR ("index out of bounds", GSL_EINVAL);
00530     gsl_vector_set (gnn_phandle_get_w (ptr->ph), i, wi);
00531 
00532     return 0;
00533 }
00534 
00535 /**
00536  * @brief Sets a value for all parameters.
00537  * @ingroup gnn_pbundle_doc
00538  *
00539  * @param  pb A parameter bundle.
00540  * @param  wi The new value for the parameter.
00541  * @return 0 if succeeded.
00542  */
00543 int
00544 gnn_pbundle_set_w_all (gnn_pbundle *pb, double wi)
00545 {
00546     gnn_pbundle *ptr;
00547 
00548     assert (pb != NULL);
00549 
00550     /* set all zero */
00551     ptr = pb->next;
00552     while (ptr != NULL)
00553     {
00554         if (gnn_phandle_get_size (ptr->ph) > 0)
00555             gsl_vector_set_all (gnn_phandle_get_w (ptr->ph), wi);
00556         ptr = ptr->next;
00557     }
00558 
00559     return 0;
00560 }
00561 
00562 /**
00563  * @brief Gets the i-th paramter.
00564  * @ingroup gnn_pbundle_doc
00565  *
00566  * @param  pb A parameter bundle.
00567  * @param  i  The index of the parameter to be retrieved.
00568  * @return The value of the i-th parameter.
00569  */
00570 double
00571 gnn_pbundle_get_w_at (gnn_pbundle *pb, size_t i)
00572 {
00573     int poffset;
00574     gnn_pbundle *ptr;
00575 
00576     assert (pb != NULL);
00577     assert (i >= 0);
00578 
00579     /* search position */
00580     poffset = 0;
00581     ptr     = pb->next;
00582     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
00583     {
00584         i  -= gnn_phandle_get_size (ptr->ph);
00585         ptr = ptr->next;
00586     }
00587 
00588     /* get value */
00589     if (ptr == NULL)
00590         GSL_ERROR ("index out of bounds", GSL_EINVAL);
00591 
00592     return gsl_vector_get (gnn_phandle_get_w (ptr->ph), i);
00593 }
00594 
00595 
00596 
00597 
00598 /**
00599  * @brief Gets a the parameter gradient.
00600  * @ingroup gnn_pbundle_doc
00601  *
00602  * This function fills the vector dw with the parameter gradient values of
00603  * the parameter bundle. The frozen flags are respected.
00604  *
00605  * @param  pb A parameter bundle.
00606  * @param  dw A sufficiently large vector to be filled.
00607  * @return 0 if succeeded.
00608  */
00609 int
00610 gnn_pbundle_get_dw (gnn_pbundle *pb, gsl_vector *dw)
00611 {
00612     int poffset;
00613     gnn_pbundle *ptr;
00614 
00615     assert (pb != NULL);
00616 
00617     /* check null size */
00618     if (pb->next == NULL)
00619     {
00620         if (dw != NULL)
00621             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00622         return 0;
00623     }
00624 
00625     /* copy values */
00626     poffset = 0;
00627     ptr     = pb->next;
00628     while (ptr != NULL)
00629     {
00630         size_t size;
00631         gsl_vector_view dw_view;
00632 
00633         size = gnn_phandle_get_size (ptr->ph);
00634         if (size > 0)
00635         {
00636             /* get view */
00637             dw_view = gsl_vector_subvector (dw, poffset, size);
00638 
00639             /* update handle and copy values */
00640             gnn_phandle_update (ptr->ph);
00641             gsl_vector_memcpy (&(dw_view.vector), gnn_phandle_get_dw (ptr->ph));
00642         }
00643 
00644         poffset += size;
00645         ptr     = ptr->next;
00646     }
00647 
00648     return 0;
00649 }
00650 
00651 /**
00652  * @brief Sets a the parameter gradient.
00653  * @ingroup gnn_pbundle_doc
00654  *
00655  * This function fills the parameter bundles paramter gradient vector dw with
00656  * values given in the argument dw. The values at the frozen positions will be
00657  * ignored (they are always zero).
00658  *
00659  * @param  pb A parameter bundle.
00660  * @param  dw The values for the parameter gradient.
00661  * @return 0 if succeeded.
00662  */
00663 int
00664 gnn_pbundle_set_dw (gnn_pbundle *pb, const gsl_vector *dw)
00665 {
00666     int poffset;
00667     gnn_pbundle *ptr;
00668 
00669     assert (pb != NULL);
00670 
00671     /* check null size */
00672     if (pb->next == NULL)
00673     {
00674         if (dw != NULL)
00675             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00676         return 0;
00677     }
00678 
00679     /* copy values */
00680     poffset = 0;
00681     ptr     = pb->next;
00682     while (ptr != NULL)
00683     {
00684         size_t size;
00685         gsl_vector_view dw_view;
00686 
00687         size = gnn_phandle_get_size (ptr->ph);
00688         if (size > 0)
00689         {
00690             /* get view */
00691             dw_view = gsl_vector_subvector ((gsl_vector *) dw, poffset, size);
00692 
00693             /* copy values using freeze flags */
00694             gsl_vector_memcpy (gnn_phandle_get_dw (ptr->ph), &(dw_view.vector));
00695             gnn_phandle_update (ptr->ph);
00696         }
00697 
00698         poffset += size;
00699         ptr     = ptr->next;
00700     }
00701 
00702     return 0;
00703 }
00704 
00705 /**
00706  * @brief Sets the i-th parameter gradient value.
00707  * @ingroup gnn_pbundle_doc
00708  *
00709  * This function sets the value of the parameter gradient's i-th element.
00710  * The frozen flags are respected.
00711  *
00712  * @param  pb  A parameter bundle.
00713  * @param  i   The index of the value to be set.
00714  * @param  dwi The new value for the parameter gradient.
00715  * @return 0 if succeeded.
00716  */
00717 int
00718 gnn_pbundle_set_dw_at (gnn_pbundle *pb, size_t i, double dwi)
00719 {
00720     int poffset;
00721     gnn_pbundle *ptr;
00722 
00723     assert (pb != NULL);
00724     assert (i >= 0);
00725 
00726     /* search position */
00727     poffset = 0;
00728     ptr     = pb->next;
00729     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
00730     {
00731         i  -= gnn_phandle_get_size (ptr->ph);
00732         ptr = ptr->next;
00733     }
00734 
00735     /* set value */
00736     if (ptr == NULL)
00737         GSL_ERROR ("index out of bounds", GSL_EINVAL);
00738     if (gsl_vector_int_get (gnn_phandle_get_f (ptr->ph), i) != 0)
00739         gsl_vector_set (gnn_phandle_get_dw (ptr->ph), i, dwi);
00740 
00741     return 0;
00742 }
00743 
00744 /**
00745  * @brief Sets a unique value for all the parameter gradient's elements.
00746  * @ingroup gnn_pbundle_doc
00747  *
00748  * This function fills the vector dw with the value given as dwi. The
00749  * frozen flags are respected.
00750  *
00751  * @param  pb  A parameter bundle.
00752  * @param  dwi The new value for the parameter.
00753  * @return 0 if succeeded.
00754  */
00755 int
00756 gnn_pbundle_set_dw_all (gnn_pbundle *pb, double dwi)
00757 {
00758     gnn_pbundle *ptr;
00759 
00760     assert (pb != NULL);
00761 
00762     /* set all */
00763     ptr = pb->next;
00764     while (ptr != NULL)
00765     {
00766         if (gnn_phandle_get_size (ptr->ph) > 0)
00767         {
00768             gsl_vector_set_all (gnn_phandle_get_dw (ptr->ph), dwi);
00769             gnn_phandle_update (ptr->ph);
00770         }
00771         
00772         ptr = ptr->next;
00773     }
00774 
00775     return 0;
00776 }
00777 
00778 /**
00779  * @brief Gets the i-th parameter gradient.
00780  * @ingroup gnn_pbundle_doc
00781  *
00782  * This function returns the i-th parameter gradient, respecting its frozen
00783  * flag.
00784  *
00785  * @param  pb A parameter bundle.
00786  * @param  i  Index of the parameter gradient to be retrieved.
00787  * @return The i-th parameter gradient.
00788  */
00789 double
00790 gnn_pbundle_get_dw_at (gnn_pbundle *pb, size_t i)
00791 {
00792     int poffset;
00793     gnn_pbundle *ptr;
00794 
00795     assert (pb != NULL);
00796     assert (i >= 0);
00797 
00798     /* search position */
00799     poffset = 0;
00800     ptr     = pb->next;
00801     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
00802     {
00803         i  -= gnn_phandle_get_size (ptr->ph);
00804         ptr = ptr->next;
00805     }
00806 
00807     /* set value */
00808     if (ptr == NULL)
00809         GSL_ERROR ("index out of bounds", GSL_EINVAL);
00810 
00811     if (gsl_vector_int_get (gnn_phandle_get_f (ptr->ph), i) != 0)
00812         return gsl_vector_get (gnn_phandle_get_dw (ptr->ph), i);
00813     else
00814         return 0.0;
00815 }
00816 
00817 
00818 
00819 /**
00820  * @brief Gets freeze flag vector.
00821  * @ingroup gnn_pbundle_doc
00822  *
00823  * @param  pb A parameter bundle.
00824  * @param  f  A buffer vector to be filled with the freeze flags of the
00825  *            correct size.
00826  * @return 0 if succeeded.
00827  */
00828 int
00829 gnn_pbundle_get_f (gnn_pbundle *pb, gsl_vector_int *f)
00830 {
00831     int poffset;
00832     gnn_pbundle *ptr;
00833 
00834     assert (pb != NULL);
00835 
00836     /* check null size */
00837     if (pb->next == NULL)
00838     {
00839         if (f != NULL)
00840             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00841         return 0;
00842     }
00843 
00844     /* copy values */
00845     poffset = 0;
00846     ptr     = pb->next;
00847     while (ptr != NULL)
00848     {
00849         size_t size;
00850         gsl_vector_int_view f_view;
00851 
00852         size = gnn_phandle_get_size (ptr->ph);
00853         if (size > 0)
00854         {
00855             f_view = gsl_vector_int_subvector ((gsl_vector_int *) f,
00856                                                                  poffset, size);
00857             gsl_vector_int_memcpy (&(f_view.vector),
00858                                    gnn_phandle_get_f (ptr->ph));
00859         }
00860         
00861         poffset += gnn_phandle_get_size (ptr->ph);
00862         ptr     = ptr->next;
00863     }
00864 
00865     return 0;
00866 }
00867 
00868 /**
00869  * @brief Sets the freeze flags.
00870  * @ingroup gnn_pbundle_doc
00871  *
00872  * This function fills freeze flags vector with the binary {0,1} values given
00873  * in the integer vector f.
00874  *
00875  * @param  pb A parameter bundle.
00876  * @param  f  A integer vector with binary values.
00877  * @return 0 if succeeded.
00878  */
00879 int
00880 gnn_pbundle_set_f (gnn_pbundle *pb, const gsl_vector_int *f)
00881 {
00882     int poffset;
00883     gnn_pbundle *ptr;
00884 
00885     assert (pb != NULL);
00886 
00887     /* check null size */
00888     if (pb->next == NULL)
00889     {
00890         if (f != NULL)
00891             GSL_ERROR ("bundle and vector aren't of the same size", GSL_EINVAL);
00892         return 0;
00893     }
00894 
00895     /* copy values */
00896     poffset = 0;
00897     ptr     = pb->next;
00898     while (ptr != NULL)
00899     {
00900         size_t size;
00901         gsl_vector_int_view f_view;
00902 
00903         size = gnn_phandle_get_size (ptr->ph);
00904         if (size > 0)
00905         {
00906             /* set local values */
00907             f_view = gsl_vector_int_subvector ((gsl_vector_int *) f,
00908                                                         poffset, size);
00909             gsl_vector_int_memcpy (gnn_phandle_get_f (ptr->ph),
00910                                                       &(f_view.vector));
00911         
00912             /* update phandle */
00913             gnn_phandle_update (ptr->ph);
00914         }
00915         
00916         poffset += size;
00917         ptr     = ptr->next;
00918     }
00919 
00920     return 0;
00921 }
00922 
00923 /**
00924  * @brief Sets the i-th freeze flag.
00925  * @ingroup gnn_pbundle_doc
00926  *
00927  * @param  pb A parameter bundle.
00928  * @param  i  The index of the freeze flag to be set.
00929  * @param  fi The value (0=free or 1=frozen) of the flag.
00930  * @return 0 if succeeded.
00931  */
00932 int
00933 gnn_pbundle_set_f_at (gnn_pbundle *pb, size_t i, int fi)
00934 {
00935     int poffset;
00936     gnn_pbundle *ptr;
00937 
00938     assert (pb != NULL);
00939     assert (i >= 0);
00940     assert (fi == 0 || fi == 1);
00941 
00942     /* search position */
00943     poffset = 0;
00944     ptr     = pb->next;
00945     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
00946     {
00947         i  -= gnn_phandle_get_size (ptr->ph);
00948         ptr = ptr->next;
00949     }
00950 
00951     /* set value */
00952     if (ptr == NULL)
00953         GSL_ERROR ("index out of bounds", GSL_EINVAL);
00954     gsl_vector_int_set (gnn_phandle_get_f (ptr->ph), i, fi);
00955     
00956     /* update handle */
00957     gnn_phandle_update (ptr->ph);
00958 
00959     return 0;
00960 }
00961 
00962 /**
00963  * @brief Sets a value for all freeze flags.
00964  * @ingroup gnn_pbundle_doc
00965  *
00966  * This function fills the freeze flag vector with the value given a parameter.
00967  *
00968  * @param  pb A parameter bundle.
00969  * @param  fi The new value for all freeze flags. It should be 0 (free) or
00970  *            1 (frozen).
00971  * @return 0 if succeeded.
00972  */
00973 int
00974 gnn_pbundle_set_f_all (gnn_pbundle *pb, int fi)
00975 {
00976     gnn_pbundle *ptr;
00977 
00978     assert (pb != NULL);
00979     assert (fi == 0 || fi == 1);
00980 
00981     /* set all */
00982     ptr = pb->next;
00983     while (ptr != NULL)
00984     {
00985         if (gnn_phandle_get_size (ptr->ph) > 0)
00986         {
00987             gsl_vector_int_set_all (gnn_phandle_get_f (ptr->ph), fi);
00988             gnn_phandle_update (ptr->ph);
00989         }
00990         
00991         ptr = ptr->next;
00992     }
00993 
00994     return 0;
00995 }
00996 
00997 /**
00998  * @brief Gets the i-th freeze flag.
00999  * @ingroup gnn_pbundle_doc
01000  *
01001  * @param  pb A parameter bundle.
01002  * @param  i  The indexof the freeze flag to be returned.
01003  * @return 0 if the i-th parameter is free or 1 if frozen.
01004  */
01005 int
01006 gnn_pbundle_get_f_at (gnn_pbundle *pb, size_t i)
01007 {
01008     int poffset;
01009     gnn_pbundle *ptr;
01010 
01011     assert (pb != NULL);
01012     assert (i >= 0);
01013 
01014     /* search position */
01015     poffset = 0;
01016     ptr     = pb->next;
01017     while (ptr != NULL && gnn_phandle_get_size (ptr->ph) <= i)
01018     {
01019         i  -= gnn_phandle_get_size (ptr->ph);
01020         ptr = ptr->next;
01021     }
01022 
01023     /* set value */
01024     if (ptr == NULL)
01025         GSL_ERROR ("index out of bounds", GSL_EINVAL);
01026 
01027     return gsl_vector_int_get (gnn_phandle_get_f (ptr->ph), i);
01028 }
01029 
01030 
01031 
01032 

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