PLearn 0.1
|
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 :