Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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

Generated on Tue Aug 17 16:10:02 2004 for PLearn by doxygen 1.3.7