PLearn 0.1
ObjectOptionVariable.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 1998 Pascal Vincent
00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal
00006 
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 // 
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 // 
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 // 
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 // 
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00035 
00036  
00037 
00038 /* *******************************************************      
00039  * $Id: ObjectOptionVariable.cc 5354 2006-04-11 18:04:57Z tihocan $
00040  * This file is part of the PLearn library.
00041  ******************************************************* */
00042 
00043 #include "ObjectOptionVariable.h"
00044 #include <plearn/base/TypeTraits.h>
00045 #include <plearn/base/OptionBase.h>
00046 #include <plearn/base/lexical_cast.h>
00047 #include <plearn/math/TMat_maths.h>
00048 
00049 namespace PLearn {
00050 using namespace std;
00051 
00054 PLEARN_IMPLEMENT_OBJECT(
00055     ObjectOptionVariable,
00056     "Variable which wraps an option of an object.",
00057     "The option can refer to either an integer, a real value, a vector or a\n"
00058     "matrix within the object: the option will discover its size automatically.\n"
00059     "Furthermore, upon performing an fprop on the variable, this translates into\n"
00060     "a changeOption on the object.\n");
00061 
00062 ObjectOptionVariable::ObjectOptionVariable()
00063     : m_final_object(0),
00064       m_option_type(OptionTypeUnknown),
00065       m_option_int(0),
00066       m_index(-1)
00067 { }
00068 
00069 ObjectOptionVariable::ObjectOptionVariable(PP<Object> root, const string& option_name,
00070                                            const string& initial_value)
00071     : m_root(root),
00072       m_option_name(option_name),
00073       m_initial_value(initial_value),
00074       m_final_object(0),
00075       m_option_type(OptionTypeUnknown),
00076       m_option_int(0),
00077       m_index(-1)
00078 {
00079     if (m_root)
00080         build();
00081 }
00082 
00083 
00084 void ObjectOptionVariable::declareOptions(OptionList& ol)
00085 {
00086     inherited::declareOptions(ol);
00087 }
00088 
00089 
00090 void ObjectOptionVariable::build_()
00091 { 
00092     PLASSERT( m_root );
00093     PLASSERT( ! m_option_name.empty() );
00094     if (! m_initial_value.empty())
00095         m_root->changeOption(m_option_name, m_initial_value);
00096 
00097     // Infer the option type from the option, set related member variables, and
00098     // initialize the base-class variable size
00099     OptionList::iterator option_iter;
00100     string option_index;
00101     if (m_root->parseOptionName(m_option_name, m_final_object,
00102                                 option_iter,   option_index))
00103     {
00104         PLASSERT( m_final_object );
00105         void* bound_option = (*option_iter)->getAsVoidPtr(m_final_object);
00106         string option_type = (*option_iter)->optiontype();
00107         if (! option_index.empty())
00108             m_index = lexical_cast<int>(option_index);
00109         else
00110             m_index = -1;
00111 
00112         // Set the appropriate pointer depending on the actual option type.  If
00113         // an index is specified, don't immediately dereference it. Wait until
00114         // very last minute since the actual memory location the vector points
00115         // to may change with vector resizes/reallocations.
00116         if (option_type == TypeTraits<int>::name()) {
00117             m_option_type = OptionTypeInt;
00118             m_option_int  = static_cast<int*>(bound_option);
00119         }
00120         else if (option_type == TypeTraits<real>::name()) {
00121             m_option_type = OptionTypeReal;
00122             m_option_real = static_cast<real*>(bound_option);
00123         }
00124         else if (option_type == TypeTraits<Vec>::name()) {
00125             m_option_type = OptionTypeVec;
00126             m_option_vec  = static_cast<Vec*>(bound_option);
00127         }
00128         else if (option_type == TypeTraits<Mat>::name()) {
00129             m_option_type = OptionTypeMat;
00130             m_option_mat  = static_cast<Mat*>(bound_option);
00131         }
00132         else
00133             PLERROR("ObjectOptionVariable::build: unhandled type \"%s\" the option "
00134                     "\"%s\"; supported types are: { %s, %s, %s, %s }",
00135                     option_type.c_str(),
00136                     m_option_name.c_str(),
00137                     TypeTraits<int>::name() .c_str(),
00138                     TypeTraits<real>::name().c_str(),
00139                     TypeTraits<Vec>::name() .c_str(),
00140                     TypeTraits<Mat>::name() .c_str());
00141     }
00142 
00143     // Now properly set the size and initial contents of the variable
00144     switch (m_option_type) {
00145     case OptionTypeInt:
00146         PLASSERT( m_option_int );
00147         inherited::resize(1,1);
00148         value[0] = *m_option_int;
00149         break;
00150 
00151     case OptionTypeReal:
00152         PLASSERT( m_option_real );
00153         inherited::resize(1,1);
00154         value[0] = *m_option_real;
00155         break;
00156 
00157     case OptionTypeVec:
00158         // Assume row vector
00159         PLASSERT( m_option_vec );
00160         if (m_index < 0 || m_option_vec->size() == 0) {
00161             inherited::resize(1, m_option_vec->size());
00162             value << *m_option_vec;
00163         }
00164         else {
00165             inherited::resize(1,1);
00166             value[0] = (*m_option_vec)[m_index];
00167         }
00168         break;
00169         
00170     case OptionTypeMat:
00171         // Indexing works for ROWS in the case of matrices
00172         PLASSERT( m_option_mat );
00173         if (m_index < 0 || m_option_mat->length() == 0) {
00174             inherited::resize(m_option_mat->length(), m_option_mat->width());
00175             matValue << *m_option_mat;
00176         }
00177         else {
00178             inherited::resize(1, m_option_mat->width());
00179             value << (*m_option_mat)(m_index);
00180         }
00181         break;
00182 
00183     default:
00184         PLASSERT( false );
00185     }
00186 }
00187 
00188 void ObjectOptionVariable::build()
00189 {
00190     inherited::build();
00191     build_();
00192 }
00193 
00194 
00195 
00196 void ObjectOptionVariable::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00197 {
00198     inherited::makeDeepCopyFromShallowCopy(copies);
00199     deepCopyField(m_root, copies);
00200     build();
00201 }
00202 
00203 void ObjectOptionVariable::fprop()
00204 {
00205     // Depending on the type of the option, set the proper contents of the option.
00206     switch (m_option_type) {
00207     case OptionTypeInt:
00208     {
00209         PLASSERT( m_option_int );
00210         *m_option_int = int(value[0]);
00211         break;
00212     }
00213 
00214     case OptionTypeReal:
00215     {
00216         PLASSERT( m_option_real );
00217         *m_option_real = value[0];
00218         break;
00219     }
00220 
00221     case OptionTypeVec:
00222     {
00223         PLASSERT( m_option_vec );
00224         if (m_index < 0)
00225             *m_option_vec << value;
00226         else
00227             (*m_option_vec)[m_index] = value[0];
00228         break;
00229     }
00230 
00231     case OptionTypeMat:
00232     {
00233         PLASSERT( m_option_mat );
00234         if (m_index < 0)
00235             *m_option_mat << matValue;
00236         else
00237             (*m_option_mat)(m_index)<< value;
00238         break;
00239     }
00240 
00241     default:
00242         PLASSERT( false );
00243     }
00244 
00245     // Rebuild the object to reflect the change; we should find a smart way to
00246     // optimize this away in the future
00247     PLASSERT( m_final_object );
00248     m_final_object->build();
00249 }
00250 
00251 void ObjectOptionVariable::setParents(const VarArray& parents)
00252 {
00253     PLERROR("ObjectOptionVariable::setParents: this variable has no parents.");
00254 }
00255 
00256 void ObjectOptionVariable::bprop() {} // No input: nothing to bprop
00257 void ObjectOptionVariable::bbprop() {} // No input: nothing to bbprop
00258 void ObjectOptionVariable::rfprop() {} // No input: nothing to rfprop
00259 void ObjectOptionVariable::symbolicBprop() {} // No input: nothing to bprop
00260 
00261 VarArray ObjectOptionVariable::sources() 
00262 { 
00263     if (!marked)
00264     {
00265         setMark();
00266         return Var(this);
00267     }
00268     return VarArray(0,0);
00269 }
00270 
00271 VarArray ObjectOptionVariable::random_sources() 
00272 { 
00273     if (!marked)
00274         setMark();
00275     return VarArray(0,0);
00276 }
00277 
00278 VarArray ObjectOptionVariable::ancestors() 
00279 { 
00280     if (marked)
00281         return VarArray(0,0);
00282     setMark();
00283     return Var(this);
00284 }
00285 
00286 void ObjectOptionVariable::unmarkAncestors()
00287 { 
00288     if (marked)
00289         clearMark();
00290 }
00291 
00292 VarArray ObjectOptionVariable::parents()
00293 {
00294     return VarArray(0,0);
00295 }
00296 
00297 bool ObjectOptionVariable::markPath()
00298 {
00299     return marked;
00300 }
00301 
00302 void ObjectOptionVariable::buildPath(VarArray& proppath)
00303 {
00304     if(marked)
00305     {
00306         proppath.append(Var(this));
00307         clearMark();
00308     }
00309 }
00310 
00311 
00312 //#####  update*  #############################################################
00313 
00314 bool ObjectOptionVariable::update(real step_size, Vec direction_vec, real coeff, real b)
00315 {
00316     bool ret = inherited::update(step_size, direction_vec, coeff, b);
00317     fprop();
00318     return ret;
00319 }
00320 
00321 bool ObjectOptionVariable::update(Vec step_sizes, Vec direction_vec, real coeff, real b)
00322 {
00323     bool ret = inherited::update(step_sizes, direction_vec, coeff, b);
00324     fprop();
00325     return ret;
00326 }
00327 
00328 bool ObjectOptionVariable::update(real step_size, bool clear)
00329 {
00330     bool ret = inherited::update(step_size, clear);
00331     fprop();
00332     return ret;
00333 }
00334 
00335 bool ObjectOptionVariable::update(Vec new_value)
00336 {
00337     bool ret = inherited::update(new_value);
00338     fprop();
00339     return ret;
00340 }
00341 
00342 void ObjectOptionVariable::updateAndClear()
00343 {
00344     inherited::updateAndClear();
00345     fprop();
00346 }
00347 
00348 void ObjectOptionVariable::updateWithWeightDecay(real step_size, real weight_decay,
00349                                                  bool L1, bool clear)
00350 {
00351     inherited::updateWithWeightDecay(step_size, weight_decay, L1, clear);
00352     fprop();
00353 }
00354 
00355 
00356 } // end of namespace PLearn
00357 
00358 
00359 /*
00360   Local Variables:
00361   mode:c++
00362   c-basic-offset:4
00363   c-file-style:"stroustrup"
00364   c-file-offsets:((innamespace . 0)(inline-open . 0))
00365   indent-tabs-mode:nil
00366   fill-column:79
00367   End:
00368 */
00369 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines