PLearn 0.1
VarArray.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  * $Id: VarArray.cc 9206 2008-07-03 17:21:25Z tihocan $
00038  * This file is part of the PLearn library.
00039  ******************************************************* */
00040 
00041 #include "VarArray.h"
00042 #include "NaryVariable.h"
00043 //#include <plearn/display/DisplayUtils.h>
00044 #include "VarArrayElementVariable.h"
00045 
00046 namespace PLearn {
00047 using namespace std;
00048 
00050 // VarArray //
00052 VarArray::VarArray()
00053     : Array<Var>(0,10) 
00054 {}
00055 
00056 VarArray::VarArray(int n, int n_extra)
00057     : Array<Var>(n,n_extra) 
00058 {}
00059 
00060 VarArray::VarArray(int n, int initial_length, int n_extra)
00061     : Array<Var>(n,n_extra) 
00062 {
00063     iterator array = data();
00064     for (int i=0;i<n;i++)
00065         array[i]=Var(initial_length);
00066 }
00067 
00068 VarArray::VarArray(int n, int initial_length, int initial_width, int n_extra)
00069     : Array<Var>(n,n_extra) 
00070 {
00071     iterator array = data();
00072     for (int i=0;i<n;i++)
00073         array[i]=Var(initial_length,initial_width);
00074 }
00075 
00076 VarArray::VarArray(const Var& v)
00077     : Array<Var>(1,10)
00078 { (*this)[0] = v; }
00079 
00080 VarArray::VarArray(const Var& v1, const Var& v2)
00081     : Array<Var>(2,10)
00082 { 
00083     (*this)[0] = v1; 
00084     (*this)[1] = v2; 
00085 }
00086 
00087 VarArray::VarArray(Variable*  v)
00088     : Array<Var>(1,10)
00089 { (*this)[0] = Var(v); }
00090 
00091 VarArray::VarArray(Variable*  v1, Variable*  v2)
00092     : Array<Var>(2,10)
00093 { 
00094     (*this)[0] = Var(v1); 
00095     (*this)[1] = Var(v2); 
00096 }
00097 
00098 VarArray::VarArray(Variable*  v1, Variable*  v2, Variable* v3):
00099     Array<Var>(3)
00100 { 
00101     (*this)[0] = Var(v1); 
00102     (*this)[1] = Var(v2); 
00103     (*this)[2] = Var(v3); 
00104 }
00105 // This is really EXTERN!  Don't try to define it...
00106 //template<>
00107 //extern void deepCopyField(Var& field, CopiesMap& copies);
00108 #ifdef __INTEL_COMPILER
00109 #pragma warning(disable:1419)  // Get rid of compiler warning.
00110 #endif
00111 extern void varDeepCopyField(Var& field, CopiesMap& copies); // a cause d'une bug du compilateur
00112 #ifdef __INTEL_COMPILER
00113 #pragma warning(default:1419)
00114 #endif
00115 
00117 // makeDeepCopyFromShallowCopy //
00119 void VarArray::makeDeepCopyFromShallowCopy(CopiesMap& copies)
00120 {
00121     for(int i=0; i<size(); i++)
00122         varDeepCopyField((*this)[i], copies);
00123 }
00124 
00126 // copyValuesFrom //
00128 void VarArray::copyValuesFrom(const VarArray& from)
00129 {
00130     if (size()!=from.size())
00131         PLERROR("VarArray::copyValuesFrom(a): a does not have the same size (%d) as this (%d)\n",
00132                 from.size(),size());
00133     for (int i=0;i<size();i++)
00134         (*this)[i]->value << from[i]->value;
00135 }
00136 
00138 // copyFrom //
00140 void VarArray::copyFrom(const Vec& datavec)
00141 {
00142     copyFrom(datavec.data(),datavec.length());
00143 }
00144 
00145 void VarArray::copyFrom(const real* data, int n)
00146 {
00147     iterator array = this->data();
00148     int ncopied=0; // number of elements copied so far
00149     for(int i=0; i<size(); i++)
00150     {
00151         Var& v = array[i];
00152         if (!v.isNull())
00153         {
00154             real* value = v->valuedata;
00155             int vlength = v->nelems();
00156             if(ncopied+vlength>n)
00157                 PLERROR("IN VarArray::copyFrom total length of all Vars in the array exceeds length of argument");
00158             for(int j=0; j<vlength; j++)
00159                 value[j] = *data++;
00160             ncopied += vlength;
00161         }
00162     }
00163     if(ncopied!=n)
00164         PLERROR("IN VarArray::copyFrom total length of all Vars in the array (%d) differs from length of argument (%d)",
00165                 ncopied,n);
00166 }
00167 
00168 void VarArray::makeSharedValue(real* data, int n)
00169 {
00170     iterator array = this->data();
00171     int ncopied=0; // number of elements copied so far
00172     for(int i=0; i<size(); i++)
00173     {
00174         Var& v = array[i];
00175         if (!v.isNull())
00176         {
00177             int vlength = v->nelems();
00178             v->makeSharedValue(data,vlength);
00179             data += vlength;
00180             ncopied += vlength;
00181         }
00182     }
00183     if(ncopied!=n)
00184         PLERROR("IN VarArray::makeSharedValue total length of all Vars in the array (%d) differs from length of argument (%d)",
00185                 ncopied,n);
00186 }
00187 
00188 void VarArray::makeSharedValue(PP<Storage<real> > storage, int offset_) 
00189 {
00190     iterator array = data();
00191     int ncopied=0; // number of elements copied so far
00192     for(int i=0; i<size(); i++)
00193     {
00194         Var& v = array[i];
00195         if (!v.isNull())
00196         {
00197             int vlength = v->nelems();
00198             v->makeSharedValue(storage,offset_+ncopied);
00199             ncopied += vlength;
00200         }
00201     }
00202 }
00203 
00204 void VarArray::makeSharedGradient(Vec& v, int offset_)
00205 {
00206     makeSharedGradient( v.storage, v.offset_+offset_);
00207 }
00208 
00209 void VarArray::makeSharedRValue(Vec& v, int offset_)
00210 {
00211     makeSharedRValue( v.storage, v.offset_+offset_);
00212 }
00213 
00214 void VarArray::makeSharedGradient(PP<Storage<real> > storage, int offset_) 
00215 {
00216     iterator array = data();
00217     int ncopied=0; // number of elements copied so far
00218     for(int i=0; i<size(); i++)
00219     {
00220         Var& v = array[i];
00221         if (!v.isNull())
00222         {
00223             int vlength = v->nelems();
00224             v->makeSharedGradient(storage,offset_+ncopied);
00225             ncopied += vlength;
00226         }
00227     }
00228 }
00229 
00230 void VarArray::makeSharedValue(Vec& v, int offset_) 
00231 { 
00232     if (v.length() < nelems()+offset_)
00233         PLERROR("VarArray::makeSharedValue(Vec,int): vector too short (%d < %d + %d)",
00234                 v.length(),nelems(),offset_);
00235     makeSharedValue(v.storage,offset_); 
00236 }
00237 
00238 void VarArray::makeSharedGradient(real* data, int n)
00239 {
00240     iterator array = this->data();
00241     int ncopied=0; // number of elements copied so far
00242     for(int i=0; i<size(); i++)
00243     {
00244         Var& v = array[i];
00245         if (!v.isNull())
00246         {
00247             int vlength = v->nelems();
00248             v->makeSharedGradient(data,vlength);
00249             data += vlength;
00250             ncopied += vlength;
00251         }
00252     }
00253     if(ncopied!=n)
00254         PLERROR("IN VarArray::makeSharedGradient total length of all Vars in the array (%d) differs from length of argument (%d)",
00255                 ncopied,n);
00256 }
00257 
00258 void VarArray::copyTo(const Vec& datavec) const
00259 {
00260     copyTo(datavec.data(), datavec.length());
00261 }
00262 
00263 void VarArray::accumulateTo(const Vec& datavec) const
00264 {
00265     accumulateTo(datavec.data(), datavec.length());
00266 }
00267 
00268 void VarArray::copyTo(real* data, int n) const
00269 {
00270     iterator array = this->data();
00271     int ncopied=0; // number of elements copied so far
00272     for(int i=0; i<size(); i++)
00273     {
00274         Var& v = array[i];
00275         if (!v.isNull())
00276         {
00277             real* value = v->valuedata;
00278             int vlength = v->nelems();
00279             if(ncopied+vlength>n)
00280                 PLERROR("IN VarArray::copyTo total length of all Vars in the array exceeds length of argument");
00281             for(int j=0; j<vlength; j++)
00282                 *data++ = value[j];
00283             ncopied += vlength;
00284         }
00285     }
00286     if(ncopied!=n)
00287         PLERROR("IN VarArray::copyTo total length of all Vars in the array differs from length of argument");
00288 }
00289 
00290 void VarArray::accumulateTo(real* data, int n) const
00291 {
00292     iterator array = this->data();
00293     int ncopied=0; // number of elements copied so far
00294     for(int i=0; i<size(); i++)
00295     {
00296         Var& v = array[i];
00297         if (!v.isNull())
00298         {
00299             real* value = v->valuedata;
00300             int vlength = v->nelems();
00301             if(ncopied+vlength>n)
00302                 PLERROR("IN VarArray::copyTo total length of all Vars in the array exceeds length of argument");
00303             for(int j=0; j<vlength; j++)
00304                 *data++ += value[j];
00305             ncopied += vlength;
00306         }
00307     }
00308     if(ncopied!=n)
00309         PLERROR("IN VarArray::copyTo total length of all Vars in the array differs from length of argument");
00310 }
00311 
00312 void VarArray::copyGradientFrom(const Vec& datavec)
00313 {
00314     copyGradientFrom(datavec.data(),datavec.length());
00315 }
00316 
00317 void VarArray::copyGradientFrom(const Array<Vec>& datavec)
00318 {
00319     iterator array = this->data();
00320     if (size()!=datavec.size())
00321         PLERROR("VarArray::copyGradientFrom has argument of size %d, expected %d",datavec.size(),size());
00322     for(int i=0; i<size(); i++)
00323     {
00324         Var& v = array[i];
00325         real* data = datavec[i].data();
00326         int n = datavec[i].length();
00327         if (!v.isNull())
00328         {
00329             real* value = v->gradientdata;
00330             int vlength = v->nelems();
00331             if(vlength!=n)
00332                 PLERROR("IN VarArray::copyGradientFrom length of -th Var in the array differs from length of %d-th argument",i);
00333             for(int j=0; j<vlength; j++)
00334                 value[j] = *data++;
00335         }
00336     }
00337 }
00338 
00339 void VarArray::copyGradientTo(const Array<Vec>& datavec)
00340 {
00341     iterator array = this->data();
00342     for(int i=0; i<size(); i++)
00343     {
00344         Var& v = array[i];
00345         real* data = datavec[i].data();
00346         int n = datavec[i].length();
00347         if (!v.isNull())
00348         {
00349             real* value = v->gradientdata;
00350             int vlength = v->nelems();
00351             if(vlength!=n)
00352                 PLERROR("IN VarArray::copyGradientFrom length of -th Var in the array differs from length of %d-th argument",i);
00353             for(int j=0; j<vlength; j++)
00354                 *data++ = value[j];
00355         }
00356     }
00357 }
00358 
00359 void VarArray::accumulateGradientFrom(const Vec& datavec)
00360 {
00361     accumulateGradientFrom(datavec.data(),datavec.length());
00362 }
00363 
00364 void VarArray::copyGradientFrom(const real* data, int n)
00365 {
00366     iterator array = this->data();
00367     int ncopied=0; // number of elements copied so far
00368     for(int i=0; i<size(); i++)
00369     {
00370         Var& v = array[i];
00371         if (!v.isNull())
00372         {
00373             real* value = v->gradientdata;
00374             int vlength = v->nelems();
00375             if(ncopied+vlength>n)
00376                 PLERROR("IN VarArray::copyGradientFrom total length of all Vars in the array exceeds length of argument");
00377             for(int j=0; j<vlength; j++)
00378                 value[j] = *data++;
00379             ncopied += vlength;
00380         }
00381     }
00382     if(ncopied!=n)
00383         PLERROR("IN VarArray::copyGradientFrom total length of all Vars in the array differs from length of argument");
00384 }
00385 
00386 void VarArray::accumulateGradientFrom(const real* data, int n)
00387 {
00388     iterator array = this->data();
00389     int ncopied=0; // number of elements copied so far
00390     for(int i=0; i<size(); i++)
00391     {
00392         Var& v = array[i];
00393         if (!v.isNull())
00394         {
00395             real* value = v->gradientdata;
00396             int vlength = v->nelems();
00397             if(ncopied+vlength>n)
00398                 PLERROR("IN VarArray::accumulateGradientFrom total length of all Vars in the array exceeds length of argument");
00399             for(int j=0; j<vlength; j++)
00400                 value[j] += *data++;
00401             ncopied += vlength;
00402         }
00403     }
00404     if(ncopied!=n)
00405         PLERROR("IN VarArray::accumulateGradientFrom total length of all Vars in the array differs from length of argument");
00406 }
00407 
00408 void VarArray::copyGradientTo(const Vec& datavec)
00409 {
00410     copyGradientTo(datavec.data(), datavec.length());
00411 }
00412 
00413 void VarArray::copyGradientTo(real* data, int n)
00414 {
00415     iterator array = this->data();
00416     int ncopied=0; // number of elements copied so far
00417     for(int i=0; i<size(); i++)
00418     {
00419         Var& v = array[i];
00420         if (!v.isNull())
00421         {
00422             real* value = v->gradientdata;
00423             int vlength = v->nelems();
00424             if(ncopied+vlength>n)
00425                 PLERROR("IN VarArray::copyGradientTo total length of all Vars in the array exceeds length of argument");
00426             for(int j=0; j<vlength; j++)
00427                 *data++ = value[j];
00428             ncopied += vlength;
00429         }
00430     }
00431     if(ncopied!=n)
00432         PLERROR("IN VarArray::copyGradientTo total length of all Vars in the array differs from length of argument");
00433 }
00434 
00435 void VarArray::accumulateGradientTo(const Vec& datavec)
00436 {
00437     accumulateGradientTo(datavec.data(), datavec.length());
00438 }
00439 
00440 void VarArray::accumulateGradientTo(real* data, int n)
00441 {
00442     iterator array = this->data();
00443     int ncopied=0; // number of elements copied so far
00444     for(int i=0; i<size(); i++)
00445     {
00446         Var& v = array[i];
00447         if (!v.isNull())
00448         {
00449             real* value = v->gradientdata;
00450             int vlength = v->nelems();
00451             if(ncopied+vlength>n)
00452                 PLERROR("IN VarArray::accumulateGradientTo total length of all Vars in the array exceeds length of argument");
00453             for(int j=0; j<vlength; j++)
00454                 *data++ += value[j];
00455             ncopied += vlength;
00456         }
00457     }
00458     if(ncopied!=n)
00459         PLERROR("IN VarArray::accumulateGradientTo total length of all Vars in the array differs from length of argument");
00460 }
00461 
00462 void VarArray::copyMinValueTo(const Vec& datavec)
00463 {
00464     copyMinValueTo(datavec.data(), datavec.length());
00465 }
00466 
00467 void VarArray::copyMinValueTo(real* data, int n)
00468 {
00469     iterator array = this->data();
00470     int ncopied=0; // number of elements copied so far
00471     for(int i=0; i<size(); i++)
00472     {
00473         Var& v = array[i];
00474         if (!v.isNull())
00475         {
00476             real value = v->min_value;
00477             int vlength = v->nelems();
00478             if(ncopied+vlength>n)
00479                 PLERROR("IN VarArray::copyMinValueTo total length of all Vars in the array exceeds length of argument");
00480             for(int j=0; j<vlength; j++)
00481                 *data++ = value;
00482             ncopied += vlength;
00483         }
00484     }
00485     if(ncopied!=n)
00486         PLERROR("IN VarArray::copyMinValueTo total length of all Vars in the array differs from length of argument");
00487 }
00488 
00489 void VarArray::copyMaxValueTo(const Vec& datavec)
00490 {
00491     copyMaxValueTo(datavec.data(), datavec.length());
00492 }
00493 
00494 void VarArray::copyMaxValueTo(real* data, int n)
00495 {
00496     iterator array = this->data();
00497     int ncopied=0; // number of elements copied so far
00498     for(int i=0; i<size(); i++)
00499     {
00500         Var& v = array[i];
00501         if (!v.isNull())
00502         {
00503             real value = v->max_value;
00504             int vlength = v->nelems();
00505             if(ncopied+vlength>n)
00506                 PLERROR("IN VarArray::copyMaxValueTo total length of all Vars in the array exceeds length of argument");
00507             for(int j=0; j<vlength; j++)
00508                 *data++ = value;
00509             ncopied += vlength;
00510         }
00511     }
00512     if(ncopied!=n)
00513         PLERROR("IN VarArray::copyMaxValueTo total length of all Vars in the array differs from length of argument");
00514 }
00515 
00516 void VarArray::makeSharedRValue(PP<Storage<real> > storage, int offset_) 
00517 {
00518     iterator array = data();
00519     int ncopied=0; // number of elements copied so far
00520     for(int i=0; i<size(); i++)
00521     {
00522         Var& v = array[i];
00523         if (!v.isNull())
00524         {
00525             v->resizeRValue();
00526             int vlength = v->nelems();
00527             v->makeSharedRValue(storage,offset_+ncopied);
00528             ncopied += vlength;
00529         }
00530     }
00531 }
00532 
00533 void VarArray::copyRValueTo(real* data, int n)
00534 {
00535     iterator array = this->data();
00536     int ncopied=0; // number of elements copied so far
00537     for(int i=0; i<size(); i++)
00538     {
00539         Var& v = array[i];
00540         if (!v.isNull())
00541         {
00542             real* value = v->rvaluedata;
00543             if (!value)
00544                 PLERROR("VarArray::copyRValueTo: empty Var in the array (number %d)",i);
00545             int vlength = v->nelems();
00546             if(ncopied+vlength>n)
00547                 PLERROR("IN VarArray::copyRValueTo total length of all Vars in the array exceeds length of argument");
00548             for(int j=0; j<vlength; j++)
00549                 *data++ = value[j];
00550             ncopied += vlength;
00551         }
00552     }
00553     if(ncopied!=n)
00554         PLERROR("IN VarArray::copyRValueTo total length of all Vars in the array differs from length of argument");
00555 }
00556 
00557 void VarArray::copyRValueFrom(const real* data, int n)
00558 {
00559     iterator array = this->data();
00560     int ncopied=0; // number of elements copied so far
00561     for(int i=0; i<size(); i++)
00562     {
00563         Var& v = array[i];
00564         if (!v.isNull())
00565         {
00566             v->resizeRValue();
00567             real* value = v->rvaluedata;
00568             int vlength = v->nelems();
00569             if(ncopied+vlength>n)
00570                 PLERROR("IN VarArray::copyRValueFrom total length of all Vars in the array exceeds length of argument");
00571             for(int j=0; j<vlength; j++)
00572                 value[j] = *data++;
00573             ncopied += vlength;
00574         }
00575     }
00576     if(ncopied!=n)
00577         PLERROR("IN VarArray::copyRValueFrom total length of all Vars in the array differs from length of argument");
00578 }
00579 
00580 void VarArray::copyRValueTo(const Vec& datavec)
00581 {
00582     copyRValueTo(datavec.data(), datavec.length());
00583 }
00584 
00585 void VarArray::copyRValueFrom(const Vec& datavec)
00586 {
00587     copyRValueFrom(datavec.data(),datavec.length());
00588 }
00589 
00590 int VarArray::nelems() const
00591 {
00592     iterator array = data();
00593     int totallength = 0;
00594     for(int i=0; i<size(); i++)
00595         if (!array[i].isNull())
00596             totallength += array[i]->nelems();
00597     return totallength;
00598 }
00599 
00600 void VarArray::resizeRValue()
00601 {
00602     iterator array = data();
00603     for(int i=0; i<size(); i++)
00604         if (!array[i].isNull())
00605             array[i]->resizeRValue();
00606 }
00607 
00608 int VarArray::sumOfLengths() const
00609 {
00610     iterator array = data();
00611     int totallength = 0;
00612     for(int i=0; i<size(); i++)
00613         if (!array[i].isNull())
00614             totallength += array[i]->length();
00615     return totallength;
00616 }
00617 
00618 int VarArray::sumOfWidths() const
00619 {
00620     iterator array = data();
00621     int totalwidth = 0;
00622     for(int i=0; i<size(); i++)
00623         if (!array[i].isNull())
00624             totalwidth += array[i]->width();
00625     return totalwidth;
00626 }
00627 
00628 int VarArray::maxWidth() const
00629 {
00630     iterator array = data();
00631     int maxwidth = 0;
00632     for(int i=0; i<size(); i++)
00633         if (!array[i].isNull())
00634         {
00635             int w = array[i]->width();
00636             if (w>maxwidth)
00637                 maxwidth=w;
00638         }
00639     return maxwidth;
00640 }
00641 
00642 int VarArray::maxLength() const
00643 {
00644     iterator array = data();
00645     int maxlength = 0;
00646     for(int i=0; i<size(); i++)
00647         if (!array[i].isNull())
00648         {
00649             int l = array[i]->length();
00650             if (l>maxlength)
00651                 maxlength=l;
00652         }
00653     return maxlength;
00654 }
00655 
00656 VarArray VarArray::nonNull() const
00657 {
00658     VarArray results(0, size());
00659 
00660     iterator array = data();
00661     for(int i=0; i<size(); i++)
00662         if (!array[i].isNull())
00663             results.append(array[i]);
00664 
00665     return results;
00666 }
00667 VarArray& VarArray::subVarArray(int start,int len) const
00668 {
00669     int max_position=start+len-1;
00670     if (max_position>size())               
00671         PLERROR("Error in :subVarArray(int start,int len), start+len>=nelems");
00672     VarArray* results=new VarArray(0, len);
00673   
00674     iterator array = data();
00675     for(int i=start; i<start+len; i++)
00676         if (!array[i].isNull())
00677             results->append(array[i]);
00678   
00679     return *results;
00680 } 
00681 void VarArray::copyFrom(int start,int len,const VarArray& from)
00682 {
00683     int max_position=start+len-1;
00684     if (max_position>size())
00685         PLERROR("VarArray is to short");
00686     iterator array = data();
00687     for(int i=0; i<len; i++)
00688         if (!from[i].isNull())
00689             array[i+start]=from[i];
00690 }
00691 void VarArray::setMark() const
00692 {
00693     iterator array = data();
00694     for(int i=0; i<size(); i++)
00695         if (!array[i].isNull())
00696             array[i]->setMark();
00697 }
00698 
00699 void VarArray::clearMark() const
00700 {
00701     iterator array = data();
00702     for(int i=0; i<size(); i++)
00703         if (!array[i].isNull())
00704             array[i]->clearMark();
00705 }
00706 
00707 void VarArray::markPath() const
00708 {
00709     iterator array = data();
00710     for(int i=0; i<size(); i++)
00711         if (!array[i].isNull()){
00712             array[i]->markPath();
00713             //cout<<"mark :"<<i<<" "<<array[i]->getName()<<endl;
00714         }
00715 }
00716 
00717 void VarArray::buildPath(VarArray& path) const
00718 {
00719     iterator array = data();
00720     for(int i=0; i<size(); i++)
00721         if (!array[i].isNull())
00722             array[i]->buildPath(path);
00723 }
00724 
00725 void VarArray::fprop()
00726 {
00727     iterator array = data();
00728     for(int i=0; i<size(); i++)
00729     {
00730         if (!array[i].isNull())
00731             array[i]->fprop();
00732     }
00733 }
00734 
00735 void VarArray::sizeprop()
00736 {
00737     iterator array = data();
00738     for(int i=0; i<size(); i++)
00739         if (!array[i].isNull())
00740             array[i]->sizeprop();
00741 }
00742 
00743 void VarArray::sizefprop()
00744 {
00745     iterator array = data();
00746     for(int i=0; i<size(); i++)
00747         if (!array[i].isNull())
00748             array[i]->sizefprop();
00749 }
00750 
00751 void VarArray::bprop()
00752 {
00753     iterator array = data();
00754     for(int i=size()-1; i>=0; i--)
00755         if (!array[i].isNull())
00756             array[i]->bprop();
00757 }
00758 
00759 void VarArray::bbprop()
00760 {
00761     iterator array = data();
00762     for(int i=size()-1; i>=0; i--)
00763         if (!array[i].isNull())
00764             array[i]->bbprop();
00765 }
00766 
00767 void VarArray::rfprop()
00768 {
00769     iterator array = data();
00770     for(int i=0; i<size(); i++)
00771         if (!array[i].isNull())
00772             array[i]->rfprop();
00773 }
00774 
00775 // This one is to be a little smarter, when handling SumOfs and the like...
00776 // Now work properly if VarArray has size 0
00777 void VarArray::fbprop()
00778 {
00779     iterator array = data();
00780     for(int i=0; i<size()-1; i++)
00781         if (!array[i].isNull())
00782             array[i]->fprop();
00783 
00784     if (size() > 0) {
00785         last()->fbprop();
00786 
00787 #ifdef BOUNDCHECK
00788         if (last()->gradient.hasMissing())
00789             PLERROR("VarArray::fbprop has NaN gradient");
00790 #endif    
00791         for(int i=size()-2; i>=0; i--)
00792             if (!array[i].isNull())
00793             {
00794 #ifdef BOUNDCHECK
00795                 if (array[i]->gradient.hasMissing())
00796                     PLERROR("VarArray::fbprop has NaN gradient");
00797 #endif    
00798                 array[i]->bprop();
00799             }
00800     }
00801 }
00802 
00803 void VarArray::sizefbprop()
00804 {
00805     iterator array = data();
00806     for(int i=0; i<size()-1; i++)
00807         if (!array[i].isNull())
00808             array[i]->sizefprop();
00809 
00810     if (size() > 0) {
00811         {
00812             last()->sizeprop();
00813             last()->fbprop();
00814         }
00815 
00816 #ifdef BOUNDCHECK
00817         if (last()->gradient.hasMissing())
00818             PLERROR("VarArray::fbprop has NaN gradient");
00819 #endif    
00820         for(int i=size()-2; i>=0; i--)
00821             if (!array[i].isNull())
00822             {
00823 #ifdef BOUNDCHECK
00824                 if (array[i]->gradient.hasMissing())
00825                     PLERROR("VarArray::fbprop has NaN gradient");
00826 #endif    
00827                 array[i]->bprop();
00828             }
00829     }
00830 }
00831 
00832 void VarArray::fbbprop()
00833 {
00834     iterator array = data();
00835     for(int i=0; i<size()-1; i++)
00836         if (!array[i].isNull())
00837             array[i]->fprop();
00838 
00839     if (size() > 0) {
00840         last()->fbbprop();
00841 
00842         for(int i=size()-2; i>=0; i--)
00843             if (!array[i].isNull())
00844             {
00845                 array[i]->bprop();
00846                 array[i]->bbprop();
00847             }
00848     }
00849 }
00850 
00851 
00852 void VarArray::symbolicBprop()
00853 {
00854     iterator array = data();
00855     for(int i=size()-1; i>=0; i--)
00856         if (!array[i].isNull())
00857             array[i]->symbolicBprop();
00858 }
00859 
00860 VarArray VarArray::symbolicGradient()
00861 {
00862     iterator array = data();
00863     VarArray symbolic_gradients(size());
00864     for(int i=0; i<size(); i++)
00865         if (!array[i].isNull())
00866             symbolic_gradients[i] = array[i]->g;  
00867     return symbolic_gradients;
00868 }
00869 
00870 void VarArray::clearSymbolicGradient()
00871 {
00872     iterator array = data();
00873     for(int i=0; i<size(); i++)
00874         if (!array[i].isNull())
00875             array[i]->clearSymbolicGradient();  
00876 }
00877  
00878 void VarArray::fillGradient(real value)
00879 {
00880     iterator array = data();
00881     for(int i=0; i<size(); i++)
00882         if (!array[i].isNull())
00883             array[i]->fillGradient(value);
00884 }
00885 
00886 void VarArray::clearGradient()
00887 {
00888     iterator array = data();
00889     for(int i=0; i<size(); i++)
00890         if (!array[i].isNull())
00891             array[i]->clearGradient();
00892 }
00893 
00894 void VarArray::clearDiagHessian()
00895 {
00896     iterator array = data();
00897     for(int i=0; i<size(); i++)
00898         if (!array[i].isNull())
00899             array[i]->clearDiagHessian();
00900 }
00901 
00902 
00903 void VarArray::setDontBpropHere(bool val)
00904 {
00905     iterator array = data();
00906     for(int i=0; i<size(); i++)
00907         if (!array[i].isNull())
00908             array[i]->setDontBpropHere(val);
00909 }
00910 
00911 bool VarArray::update(real step_size, Vec direction, real coeff, real b)
00912 {
00913     bool hit = false;
00914     int pos=0;
00915     iterator array = data();
00916     for(int i=0; i<size(); pos+=array[i++]->nelems())
00917         if (!array[i].isNull())
00918             hit = hit || 
00919                 array[i]->update(step_size,direction.subVec(pos,array[i]->nelems()), coeff, b);
00920     return hit;
00921 }
00922 
00923 bool VarArray::update(Vec step_sizes, Vec direction, Vec coeffs)
00924 {
00925     bool hit = false;
00926     int pos = 0;
00927     iterator array = data();
00928     for (int i=0; i<size(); pos+=array[i++]->nelems()) {
00929         if (!array[i].isNull()) {
00930             hit = hit ||
00931                 array[i]->update(
00932                     step_sizes.subVec(pos, array[i]->nelems()), 
00933                     direction.subVec(pos, array[i]->nelems()),
00934                     coeffs[i]);
00935         }
00936     }
00937     return hit;
00938 }
00939 
00940 bool VarArray::update(Vec step_sizes, Vec direction, real coeff, real b)
00941 {
00942     bool hit = false;
00943     int pos = 0;
00944     iterator array = data();
00945     for (int i=0; i<size(); pos+=array[i++]->nelems()) {
00946         if (!array[i].isNull()) {
00947             hit = hit ||
00948                 array[i]->update(
00949                     step_sizes.subVec(pos, array[i]->nelems()), 
00950                     direction.subVec(pos, array[i]->nelems()),
00951                     coeff, b);
00952         }
00953     }
00954     return hit;
00955 }
00956 
00957 real VarArray::maxUpdate(Vec direction)
00958 {
00959     real max_step_size = FLT_MAX;
00960     int pos=0;
00961     iterator array = data();
00962     for(int i=0; i<size(); pos+=array[i++]->nelems())
00963         if (!array[i].isNull())
00964             max_step_size = MIN(max_step_size,
00965                                 array[i]->maxUpdate(direction.subVec(pos,array[i]->nelems())));
00966     return max_step_size;
00967 }
00968 
00969 bool VarArray::update(real step_size, bool clear)
00970 {
00971     bool hit = false;
00972     iterator array = data();
00973     for(int i=0; i<size(); i++)
00974         if (!array[i].isNull())
00975             hit = hit || array[i]->update(step_size,clear);
00976     return hit;
00977 }
00978 
00979 void VarArray::updateWithWeightDecay(real step_size, real weight_decay, bool L1, bool clear)
00980 {
00981     iterator array = data();
00982     for(int i=0; i<size(); i++)
00983         if (!array[i].isNull())
00984             array[i]->updateWithWeightDecay(step_size,weight_decay,L1,clear);
00985     return;
00986 }
00987 
00988 bool VarArray::update(Vec new_value)
00989 {
00990     bool hit = false;
00991     int pos=0;
00992     iterator array = data();
00993     for(int i=0; i<size(); pos+=array[i++]->nelems())
00994         if (!array[i].isNull())
00995             hit = hit || 
00996                 array[i]->update(new_value.subVec(pos,array[i]->nelems()));
00997     return hit;
00998 }
00999 
01000 void VarArray::read(istream& in)
01001 {
01002     iterator array = data();
01003     for(int i=0; i<size(); i++)
01004         if (!array[i].isNull())
01005             array[i]->read(in);
01006 }
01007 
01008 void VarArray::write(ostream& out) const
01009 {
01010     iterator array = data();
01011     for(int i=0; i<size(); i++)
01012         if (!array[i].isNull())
01013             array[i]->write(out);
01014 }
01015 
01016 Var VarArray::operator[](Var index)
01017 {
01018     return new VarArrayElementVariable(*this, index);
01019 }
01020 
01021 VarArray VarArray::sources() const
01022 {
01023     VarArray a;
01024     iterator array = data();
01025     for(int i=0; i<size(); i++)
01026         if (!array[i].isNull())
01027             a &= array[i]->sources();
01028     return a;
01029 }
01030 
01031 VarArray VarArray::ancestors() const
01032 {
01033     VarArray a;
01034     iterator array = data();
01035     for(int i=0; i<size(); i++)
01036         if (!array[i].isNull())
01037             a &= array[i]->ancestors();
01038     return a;
01039 }
01040 
01041 void VarArray::unmarkAncestors() const
01042 {
01043     iterator array = data();
01044     for(int i=0; i<size(); i++)
01045         if (!array[i].isNull())
01046             array[i]->unmarkAncestors();
01047 }
01048 
01049 VarArray VarArray::parents() const
01050 {
01051     setMark();
01052     VarArray all_parents;
01053     VarArray parents_i; 
01054     iterator array = data();
01055     for(int i=0; i<size(); i++)
01056         if (!array[i].isNull())
01057         {
01058             parents_i = array[i]->parents();
01059             if(parents_i.size()>0)
01060             {
01061                 parents_i.setMark();
01062                 all_parents.append(parents_i);
01063             }
01064         }
01065     clearMark();
01066     all_parents.clearMark();
01067     return all_parents;
01068 }
01069 void VarArray::printNames()const
01070 {
01071     for(int i=0;i<this->size();i++)
01072         cout<<i<<" : "<<(*this)[i]->getName()<<endl;
01073 }
01074 
01077 // from inputs to outputs
01078 VarArray propagationPath(const VarArray& inputs, const VarArray& outputs)
01079 {
01080     if(outputs.size()==0)
01081         return VarArray(0,0);
01082 
01083     VarArray proppath; 
01084     inputs.setMark(); // sets the mark for all inputs
01085     outputs.markPath(); // sets the mark along all paths going from inputs to outputs
01086     inputs.clearMark(); // since we don't want the inputs in the update path
01087     outputs.buildPath(proppath); // appends to proppath every marked item that leads to one of the outputs
01088     // and clears the marks at the same time.
01089     return proppath;
01090 }
01091 // from inputs to outputs passing by parameters_to_optimize
01092 // IMPORTANT this is not working properly //FP
01093 /*
01094   VarArray propagationPath(const VarArray& inputs, const VarArray& parameters_to_optimize,const VarArray& outputs)
01095   {
01096   //VarArray test=propagationPath(inputs,outputs);
01097   //cout<<"parameters_to_optimize :"<<endl<<parameters_to_optimize<<endl; 
01098   //cout<<"propagationPath(inputs,parameters_to_optimize)"<<endl;
01099   VarArray path1=propagationPath(inputs,parameters_to_optimize);
01100   //cout<<"propagationPath(parameters_to_optimize,outputs)"<<endl;
01101   VarArray path2=propagationPath(parameters_to_optimize,outputs);
01102   //cout<<"end of propagationPath(parameters_to_optimize,outputs)"<<endl;
01103   //cout<<"path2"<<endl<<path2<<endl;
01104   //displayVarGraph(inputs);
01105   //displayVarGraph(parameters_to_optimize);
01106   
01107   //displayVarGraph(test,true);
01108   //displayVarGraph(path1,true);
01109   //displayVarGraph(path2,true);
01110   return path1&path2;
01111   }*/
01112 
01113 // from all sources to outputs
01114 VarArray propagationPath(const VarArray& outputs)
01115 {
01116     if(outputs.size()==0)
01117         return VarArray(0,0);
01118     VarArray all_sources = outputs.sources();
01119     outputs.unmarkAncestors();
01120     return propagationPath(all_sources,outputs);
01121 }
01122 
01123 // from all sources to all direct non-inputs parents of the path inputs-->outputs
01124 VarArray propagationPathToParentsOfPath(const VarArray& inputs, const VarArray& outputs)
01125 {
01126     VarArray parents = nonInputParentsOfPath(inputs, outputs);
01127     // WARNING: with this way of proceeding, any SourceVariable that 
01128     // is a direct parent is currently included in parents, and will
01129     // thus be included in the propagation path computed below.
01130     // Calling fprop on a SourceVariable should not harm, but we usually
01131     // avoided this in previous code (because it is useless). Now the
01132     // question of SampleSourceVariables remains to be solved... (see TODO.txt)
01133     // For now we keep it like this. But maybe later we should find a way
01134     // to exclude the unnecessary source variables (and include the maybe necessary
01135     // SampleSourceVariables) in the returned path... [Pascal]
01136     if(parents.size()==0)
01137         return VarArray(0,0);
01138     return propagationPath(parents);
01139 }
01140 
01141 
01142 VarArray nonInputParentsOfPath(VarArray inputs, VarArray outputs)
01143 {
01144     //cout<<"start nonInputParentsOfPath(...)"<<endl;
01145     VarArray proppath = propagationPath(inputs, outputs);
01146     inputs.setMark();
01147     VarArray non_input_parents = proppath.parents();
01148     inputs.clearMark();
01149     //cout<<"stop nonInputParentsOfPath(...)"<<endl;
01150     return non_input_parents;
01151 }
01152 
01153 // returns all sources that influence the given vars
01154 VarArray allSources(const VarArray& v)
01155 {
01156     VarArray result;
01157     v.unmarkAncestors();
01158     result = v.sources();
01159     v.unmarkAncestors();
01160     return result;
01161 }
01162 
01163 // returns all variables of a that are not in b
01164 VarArray operator-(const VarArray& a, const VarArray& b)
01165 {
01166     VarArray result;
01167     int i,j;
01168     for(i=0; i<a.size(); i++)
01169     {
01170         Var v = a[i];
01171         for(j=0; j<b.size(); j++)
01172             if(b[j]==v)
01173                 break;
01174         if(j>=b.size()) // v not found in b
01175             result.append(v);
01176     }
01177     return result;
01178 }
01179 
01180 // returns all sources that influence outputs except those that influence it only through inputs
01181 VarArray nonInputSources(const VarArray& inputs, const VarArray& outputs)
01182 {
01183     VarArray result;
01184     outputs.unmarkAncestors();
01185     inputs.setMark();
01186     result = outputs.sources();
01187     outputs.unmarkAncestors();
01188     return result;
01189 }
01190 
01191 void operator<<(VarArray& ar, const Array<Vec>& values)
01192 {
01193     int n = ar.size();
01194     if(values.size()!=n)
01195         PLERROR("In operator<<(VarArray&, const Array<Vec>&) sizes of arrays differ (VarArray:%d Array<Vec>:%d)",ar.size(),values.size());
01196     for(int k=0; k<n; k++)
01197     {
01198         Vec& ar_v = ar[k]->value;
01199         Vec& v = values[k];
01200         if(ar_v.size() != v.size())
01201             PLERROR("In operator<<(VarArray&, const Array<Vec>&) sizes of var array and vector differ.  "
01202                     "(VarArray length:%d, in Array<Vec>, Vec length:%d)",ar_v.size(),v.size());
01203         ar_v << v;
01204     }
01205 }
01206 
01207 void operator>>(VarArray& ar, const Array<Vec>& values)
01208 {
01209     int n = ar.size();
01210     if(values.size()!=n)
01211         PLERROR("In operator<<(VarArray&, const Array<Vec>&) sizes of arrays differ (VarArray:%d Array<Vec>:%d)",ar.size(),values.size());
01212     for(int k=0; k<n; k++)
01213     {
01214         Vec& ar_v = ar[k]->value;
01215         Vec& v = values[k];
01216         if(ar_v.size() != v.size())
01217             PLERROR("In operator<<(VarArray&, const Array<Vec>&) sizes of var array and vector differ.  "
01218                     "(VarArray length:%d, in Array<Vec>, Vec length:%d)",ar_v.size(),v.size());
01219         ar_v >> v;
01220     }
01221 }
01222 
01223 void printInfo(VarArray& a) { a.printInfo(); }
01224 
01225 void printInfo(VarArray inputs, const Var& output,bool show_gradients)
01226 {
01227     inputs.setMark();
01228     output->markPath();
01229     VarArray proppath;
01230     output->buildPath(proppath);
01231     if (show_gradients)
01232     {
01233         // Warning: we should probably clear the gradients along the proppath before doing this
01234         proppath.fbprop();
01235     }
01236     else
01237         proppath.fprop();
01238     proppath.printInfo(show_gradients);
01239 }
01240 
01241 } // end of namespace PLearn
01242 
01243 
01244 /*
01245   Local Variables:
01246   mode:c++
01247   c-basic-offset:4
01248   c-file-style:"stroustrup"
01249   c-file-offsets:((innamespace . 0)(inline-open . 0))
01250   indent-tabs-mode:nil
01251   fill-column:79
01252   End:
01253 */
01254 // 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