PLearn 0.1
Variable.h
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 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 
00037  
00038 
00039 /* *******************************************************      
00040  * $Id: Variable.h 9177 2008-06-26 17:50:25Z tihocan $
00041  * This file is part of the PLearn library.
00042  ******************************************************* */
00043 
00044 #ifndef Variable_INC
00045 #define Variable_INC
00046 
00047 #include <plearn/base/Object.h>
00048 #include <plearn/math/TMat.h>
00049 
00050 namespace PLearn {
00051 using namespace std;
00052 
00053 class Variable;
00054 class VarArray;
00055 class RandomVariable;
00056 class RandomVar;
00057 
00058 class Var: public PP<Variable>
00059 {
00060     friend class RandomVariable;
00061     friend class RandomVar;
00062 
00063 public:
00064     Var();
00065     Var(Variable* v);
00066     Var(Variable* v, const char* name);
00067     Var(const Var& other);
00068     Var(const Var& other, const char* name);
00069     Var(const Var &other, const string &name);
00070     explicit Var(int the_length, int width_=1);
00071     Var(int the_length, int the_width, const char* name);
00072     Var(int the_length, int the_width, const string &name);
00073     Var(int the_length, const char* name);
00074     Var(int the_length, const string &name);
00075     explicit Var(const Vec& vec, bool vertical=true);
00076     explicit Var(const Mat& mat);
00077 
00078     int length() const;
00079     int width() const;
00080 
00081     Var subVec(int start, int len, bool transpose=false) const;
00082     Var subMat(int i, int j, int sublength, int subwidth, bool transpose=false) const;
00083     Var row(int i, bool transpose=false) const;
00084     Var column(int j, bool transpose=false) const;
00085     Var operator()(int i) const;
00086     Var operator()(int i, int j) const;
00087 
00089     Var operator[](int i) const;
00090     Var operator[](Var i) const;
00091   
00093     Var operator()(Var index) const;
00094 
00096     Var operator()(Var i, Var j) const;
00097 
00098     void operator=(real f);
00099     void operator=(const Vec& v);
00100     void operator=(const Mat& m);
00101 };
00102 
00103 class Variable: public Object
00104 {
00105 
00106 private:
00107 
00108     typedef Object inherited;
00109 
00110 public:
00111 
00113     Variable() : varnum(++nvars), marked(false), varname(), allows_partial_update(false),
00114                  gradient_status(0), valuedata(0), gradientdata(0), min_value(-FLT_MAX),
00115                  max_value(FLT_MAX), dont_bprop_here(false) {}
00116 
00117 protected:
00118     static void declareOptions(OptionList & ol);
00119 
00121     static void declareMethods(RemoteMethodMap& rmm);
00122   
00123     friend class Var;
00124     friend class RandomVariable;
00125     friend class ProductRandomVariable;
00126     friend class Function;
00127 
00128     friend class UnaryVariable;
00129     friend class BinaryVariable;
00130     friend class NaryVariable;
00131 
00132 public:
00133     static int nvars; 
00134     int varnum; 
00135 
00136 protected:
00137     bool marked; 
00138     string varname; 
00139 
00140     bool allows_partial_update; 
00141     int gradient_status; 
00142     TVec<int> rows_to_update; 
00143 
00144 public:
00145     Vec value;
00146     Vec gradient;
00147     Mat matValue;
00148     Mat matGradient;
00149     Vec rValue;
00150     Mat matRValue;
00151     Mat matDiagHessian; 
00152 
00153     real* valuedata; 
00154     real* gradientdata; 
00155     real min_value, max_value; 
00156     Var g; 
00157     Vec diaghessian; 
00158     real* diaghessiandata; 
00159     real* rvaluedata;
00160     bool dont_bprop_here; 
00161   
00162 public:
00163     Variable(int thelength, int thewidth, bool call_build_ = true);
00164     Variable(const Mat& m, bool call_build_ = true);  
00165 
00166     int length() const { return matValue.length(); }
00167     int width() const { return matValue.width(); }
00168     int size() const { return matValue.size(); } // length*width
00169     int nelems() const { return size(); }
00170 
00177     virtual void recomputeSize(int& l, int& w) const;
00178 
00182     void resize(int l, int w);
00183   
00188     void sizeprop();
00189 
00191     virtual void setParents(const VarArray& parents);
00192 
00194     Variable(const Variable& v);
00195 
00196 private:
00197     void build_();
00198 public:
00199     virtual void build();
00200 
00201     bool isScalar() const { return length()==1 && width()==1; }
00202     bool isVec() const { return length()==1 || width()==1; }
00203     bool isColumnVec() const { return width()==1; }
00204     bool isRowVec() const { return length()==1; }
00205 
00206     PLEARN_DECLARE_ABSTRACT_OBJECT(Variable);
00207 
00208     virtual void makeDeepCopyFromShallowCopy(CopiesMap& copies);
00209 
00211     virtual void fprop() =0;
00213 
00215     inline void sizefprop()
00216     { sizeprop(); fprop(); }
00217 
00218     virtual void bprop() =0;
00224     virtual void bbprop();
00226     virtual void fbprop();
00228     virtual void fbbprop();
00230     virtual void symbolicBprop();
00231 
00232     virtual void rfprop();
00233 
00234     virtual void copyValueInto(Vec v) { v << value; }
00235     virtual void copyGradientInto(Vec g) { g << gradient; }
00236 
00237     // virtual void newwrite(PStream& out) const;
00238 
00241     string getName() const;
00243     void setName(const string& the_name); 
00244     bool nameIsSet() { return varname.size()>0; }
00245 
00251     Mat defineValueLocation(const Mat& m);
00252 
00258     Mat defineGradientLocation(const Mat& m);
00259 
00260     virtual void printInfo(bool print_gradient=false) = 0;
00261     virtual void printInfos(bool print_gradient=false);
00262 
00263     Var subVec(int start, int len, bool transpose=false);
00264     Var subMat(int i, int j, int sublength, int subwidth, bool transpose=false);
00265     Var row(int i, bool transpose=false) { return subMat(i,0,1,width(),transpose); }
00266     Var column(int j, bool transpose=false) { return subMat(0,j,length(),1,transpose); }
00267 
00268     void setDontBpropHere(bool val) { dont_bprop_here = val; }
00269     void setKeepPositive() { min_value = 0; }
00270     void setMinValue(real minv=-FLT_MAX) { min_value = minv; }
00271     void setMaxValue(real maxv=FLT_MAX) { max_value = maxv; }
00272     void setBoxConstraint(real minv, real maxv) { min_value = minv; max_value = maxv; }
00273 
00274     void setMark() { marked = true; }
00275     void clearMark() { marked = false; }
00276     bool isMarked() { return marked; }
00277 
00278     void fillGradient(real value) { gradient.fill(value); }
00279     void fillValue(real val) { value.fill(val); }
00280 
00283     void setValueSubMat(const Mat& submat, int istart, int jstart);
00284     
00285     void clearRowsToUpdate()
00286     {
00287         rows_to_update.resize(0);
00288         gradient_status=0;
00289     }
00290     void clearGradient() 
00291     { 
00292         if(!allows_partial_update) 
00293             gradient.clear(); 
00294         else
00295         {
00296             for (int r=0;r<rows_to_update.length();r++)
00297             {
00298                 int row = rows_to_update[r];
00299                 matGradient.row(row).clear();
00300             }
00301             rows_to_update.resize(0);
00302             gradient_status=0;
00303         }
00304     }
00305     void clearDiagHessian(); 
00306     void clearSymbolicGradient() { g = Var(); }
00307 
00315     virtual bool update(real step_size, Vec direction_vec,
00316                         real coeff = 1.0, real b = 0.0);
00317 
00324     virtual bool update(Vec step_sizes, Vec direction_vec,
00325                         real coeff = 1.0, real b = 0.0);
00326 
00333     virtual bool update(real step_size, bool clear=false);
00334 
00342     virtual bool update(Vec new_value);
00343 
00346     virtual void updateAndClear();
00347 
00356     virtual void updateWithWeightDecay(real step_size, real weight_decay,
00357                                        bool L1, bool clear=true);
00358 
00360     void allowPartialUpdates()
00361     {
00362         allows_partial_update=true; 
00363         rows_to_update.resize(length()); // make sure that there are always enough elements
00364         rows_to_update.resize(0);
00365         gradient_status=0;
00366     }
00367 
00369     void disallowPartialUpdates()
00370     {
00371         allows_partial_update = false;
00372         gradient_status=2;
00373     }
00374 
00376     void updateRow(int row)
00377     {
00378         if (gradient_status!=2 && allows_partial_update && !rows_to_update.contains(row))
00379         {
00380             rows_to_update.append(row);
00381             if (gradient_status==0) gradient_status=1;
00382         }
00383     }
00384 
00391     real maxUpdate(Vec direction);
00392 
00398     virtual bool markPath() =0;
00399 
00402     virtual void buildPath(VarArray& proppath) =0;
00403 
00404     virtual void oldread(istream& in);
00405     virtual void write(ostream& out) const;
00406 
00407   
00408   
00409 
00410     void copyFrom(const Vec& v)    { value << v; }
00411     void copyTo(Vec& v)    { v << value; }
00412     void copyGradientFrom(const Vec& v)    { gradient << v; }
00413     void copyGradientTo(Vec& v) { v << gradient; }
00414     void makeSharedValue(real* x, int n); 
00415     void makeSharedGradient(real* x, int n); 
00416 
00417     void makeSharedValue(PP<Storage<real> > storage, int offset_=0); 
00418     void makeSharedGradient(PP<Storage<real> > storage, int offset_=0); 
00419     void makeSharedValue(Vec& v, int offset_=0);
00420     void makeSharedGradient(Vec& v, int offset_=0);
00421 
00422     void copyRValueFrom(const Vec& v) { resizeRValue(); rValue << v; }
00423     void copyRValueTo(Vec& v) { resizeRValue(); v << rValue; }
00424     void makeSharedRValue(real* x, int n); 
00425     void makeSharedRValue(PP<Storage<real> > storage, int offset_=0);
00426     void makeSharedRValue(Vec& v, int offset_=0);
00427 
00428     // make this var point to the same things as v, using default operator=
00429     void makePointTo(Variable* v) { 
00430         value = v->value;
00431         valuedata = v->valuedata;
00432         matValue = v->matValue;
00433         gradient = v->gradient;
00434         matGradient = v->matGradient;
00435         gradientdata = v->gradientdata;
00436         rows_to_update = v->rows_to_update;
00437         rValue = v->rValue;
00438         matRValue = v->matRValue;
00439         matDiagHessian = v->matDiagHessian;
00440         diaghessian = v->diaghessian;
00441         diaghessiandata = v->diaghessiandata;
00442         rvaluedata = v->rvaluedata;
00443     }
00444 
00445     virtual bool isConstant() { return false; }
00446 
00453     virtual void fprop_from_all_sources();
00454 
00457     virtual VarArray sources() = 0;
00458 
00461     virtual VarArray random_sources() = 0;
00462 
00464     virtual VarArray ancestors() = 0;
00466     virtual void unmarkAncestors() = 0;
00467 
00470     virtual VarArray parents() = 0;
00471 
00473     virtual void accg(Var v);
00474 
00477     virtual void verifyGradient(real step=0.001);
00478 
00480     virtual void resizeDiagHessian();
00481 
00482     virtual void resizeRValue();
00483 };
00484 
00485 DECLARE_OBJECT_PTR(Variable);
00486 DECLARE_OBJECT_PP(Var, Variable);
00487 
00488 
00489 void varDeepCopyField(Var& field, CopiesMap& copies);
00490 
00491 
00492 inline Var Var::row(int i, bool transpose) const
00493 {
00494     return subMat(i, 0, 1, width(), transpose);
00495 }
00496     
00497 inline Var Var::column(int j, bool transpose) const
00498 {
00499     return subMat(0, j, length(), 1, transpose);
00500 }
00501 
00502 inline Var Var::operator()(int i) const
00503 {
00504     return row(i, false);
00505 }
00506 
00507 inline Var Var::operator()(int i, int j) const
00508 {
00509     return subMat(i, j, 1, 1);
00510 }
00511     
00512 } // end of namespace PLearn
00513 
00514 #endif
00515 
00516 
00517 /*
00518   Local Variables:
00519   mode:c++
00520   c-basic-offset:4
00521   c-file-style:"stroustrup"
00522   c-file-offsets:((innamespace . 0)(inline-open . 0))
00523   indent-tabs-mode:nil
00524   fill-column:79
00525   End:
00526 */
00527 // 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