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

Variable.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 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 00038 00039 /* ******************************************************* 00040 * $Id: Variable.cc,v 1.18 2004/06/01 13:15:57 tihocan Exp $ 00041 * This file is part of the PLearn library. 00042 ******************************************************* */ 00043 00046 #include "Var.h" 00047 #include "VarArray.h" 00048 #include "Func.h" 00049 00050 #include "VarElementVariable.h" 00051 #include "VarRowVariable.h" 00052 #include "SubMatVariable.h" 00053 #include "SubMatTransposeVariable.h" 00054 #include "SourceVariable.h" 00055 #include "PlusScalarVariable.h" 00056 #include "TimesConstantVariable.h" 00057 #include "Var_operators.h" 00058 00059 //#include "Var_utils.h" 00060 00061 namespace PLearn { 00062 using namespace std; 00063 00064 // To be able to use varDeepCopyField. 00065 // extern void varDeepCopyField(Var& field, CopiesMap& copies); 00066 00069 Var::Var() :PP<Variable>(0) {} 00070 Var::Var(Variable* v) :PP<Variable>(v) {} 00071 Var::Var(Variable* v, const char* name) :PP<Variable>(v) { ptr->setName(name); } 00072 Var::Var(const Var& other) :PP<Variable>(other) {} 00073 Var::Var(const Var& other, const char* name) :PP<Variable>(other) { ptr->setName(name); } 00074 00075 Var::Var(int the_length, const char* name) 00076 :PP<Variable>(new SourceVariable(the_length,1)) 00077 { ptr->setName(name); } 00078 00079 Var::Var(int the_length, int the_width) 00080 :PP<Variable>(new SourceVariable(the_length,the_width)) {} 00081 00082 Var::Var(int the_length, int the_width, const char* name) 00083 :PP<Variable>(new SourceVariable(the_length,the_width)) { ptr->setName(name); } 00084 00085 Var::Var(const Vec& v, bool vertical) 00086 :PP<Variable>(new SourceVariable(v,vertical)) 00087 {} 00088 00089 Var::Var(const Mat& m) 00090 :PP<Variable>(new SourceVariable(m)) 00091 {} 00092 00093 int Var::length() const 00094 { return (*this)->length(); } 00095 00096 int Var::width() const 00097 { return (*this)->width(); } 00098 00099 Var Var::operator[](int i) const 00100 { 00101 if(width()==1) 00102 return operator()(i,0); 00103 else if(length()==1) 00104 return operator()(0,i); 00105 PLERROR("You shouldnt use operator[](int i) to access a matrix variable, consider using operator() instead"); 00106 return Var(); 00107 } 00108 00109 Var Var::operator[](Var index) const 00110 { 00111 if(width()!=1) 00112 PLERROR("You shouldnt use operator[](Var index) to get the row of a matrix var but operator()(Var index)"); 00113 return new VarElementVariable(*this,index); 00114 } 00115 00116 Var Var::subMat(int i, int j, int sublength, int subwidth, bool do_transpose) const 00117 { 00118 if(do_transpose) 00119 return new SubMatTransposeVariable(*this, i, j, sublength, subwidth); 00120 else 00121 return new SubMatVariable(*this, i, j, sublength, subwidth); 00122 } 00123 00124 Var Var::subVec(int start, int len, bool transpose) const 00125 { 00126 if(width()==1) 00127 return subMat(start,0,len,1,transpose); 00128 else if(length()==1) 00129 return subMat(0,start,1,len,transpose); 00130 00131 PLERROR("In Variable::subVec variable is not a vec (single column or single row)"); 00132 return Var(); 00133 } 00134 00135 Var Var::operator()(Var index) const 00136 { return new VarRowVariable(*this,index); } 00137 00138 Var Var::operator()(Var i, Var j) const 00139 { return new VarElementVariable(*this, new PlusScalarVariable(j, new TimesConstantVariable(i,(real)width()))); } 00140 00141 void Var::operator=(real f) 00142 { 00143 if (!isNull()) 00144 (*this)->value.fill(f); 00145 else 00146 PLERROR("Var::operator= called on null Var"); 00147 } 00148 00149 void Var::operator=(const Vec& v) 00150 { 00151 if (!isNull()) 00152 (*this)->value << v; 00153 else 00154 PLERROR("Var::operator= called on null Var"); 00155 } 00156 00157 void Var::operator=(const Mat& m) 00158 { 00159 if (!isNull()) 00160 (*this)->matValue << m; 00161 else 00162 PLERROR("Var::operator= called on null Var"); 00163 } 00164 00165 int Variable::nvars = 0; 00166 00167 Variable::Variable(int thelength, int thewidth) 00168 :varnum(++nvars), marked(false), varname(""), 00169 allows_partial_update(false), gradient_status(0), 00170 matValue(thelength,thewidth), matGradient(thelength,thewidth), 00171 min_value(-FLT_MAX), max_value(FLT_MAX), diaghessiandata(0), rvaluedata(0), 00172 dont_bprop_here(false) 00173 { 00174 value = matValue.toVec(); 00175 gradient = matGradient.toVec(); 00176 valuedata = value.data(); 00177 gradientdata = gradient.data(); 00178 } 00179 00180 Variable::Variable(const Mat& m) 00181 :varnum(++nvars), marked(false), varname(""), 00182 allows_partial_update(false), gradient_status(0), 00183 matValue(m), matGradient(m.length(),m.width()), 00184 min_value(-FLT_MAX), max_value(FLT_MAX), diaghessiandata(0), rvaluedata(0), 00185 dont_bprop_here(false) 00186 { 00187 if(!m.isCompact()) 00188 PLERROR("To be able to construct a Var that views the same data as a Mat m, the Mat must be compact (width()==mod()). Maybe you can use m.copy() instead of m?"); 00189 value = matValue.toVec(); 00190 gradient = matGradient.toVec(); 00191 valuedata = value.data(); 00192 gradientdata = gradient.data(); 00193 } 00194 00195 // shallow copy (same as default copy constructor, except varnum is set to ++nvars. 00196 Variable::Variable(const Variable& v) 00197 :varnum(++nvars), marked(false), varname(v.getName()), 00198 allows_partial_update(v.allows_partial_update), gradient_status(v.gradient_status), 00199 value(v.value), gradient(v.gradient), 00200 matValue(v.matValue),matGradient(v.matGradient), 00201 valuedata(v.valuedata), gradientdata(v.gradientdata), 00202 min_value(v.min_value),max_value(v.max_value), 00203 g(v.g), diaghessian(v.diaghessian), diaghessiandata(v.diaghessiandata), 00204 rvaluedata(v.rvaluedata), dont_bprop_here(v.dont_bprop_here) 00205 {} 00206 00207 00208 void Variable::declareOptions(OptionList& ol) 00209 { 00210 declareOption(ol, "varname", &Variable::varname, OptionBase::buildoption, 00211 "An (optional) name for the variable\n"); 00212 00213 declareOption(ol, "value", &Variable::matValue, OptionBase::learntoption, 00214 "Current value of the variable\n"); 00215 00216 /* 00217 declareOption(ol, "gradient", &Variable::matGradient, OptionBase::learntoption, 00218 "Current gradient of the variable\n"); 00219 */ 00220 00221 inherited::declareOptions(ol); 00222 } 00223 00224 void Variable::build_() 00225 { 00226 int l, w; 00227 recomputeSize(l, w); 00228 if (l && w) 00229 resize(l,w); 00230 } 00231 00232 void Variable::build() 00233 { 00234 inherited::build(); 00235 build_(); 00236 } 00237 00238 00239 void Variable::recomputeSize(int& l, int& w) const 00240 { l = length(); w = width(); } 00241 00242 void Variable::resize(int l, int w) 00243 { 00244 value = Vec(); 00245 matValue.resize(l,w); 00246 value = matValue.toVec(); 00247 valuedata = value.data(); 00248 00249 gradient = Vec(); 00250 matGradient.resize(l,w); 00251 gradient = matGradient.toVec(); 00252 gradientdata = gradient.data(); 00253 } 00254 00255 void Variable::sizeprop() 00256 { 00257 int l,w; 00258 recomputeSize(l,w); 00259 resize(l,w); 00260 } 00261 00262 void Variable::setParents(const VarArray& parents) 00263 { PLERROR("In Variable::setParents setParents() function not implemented for %s", classname().c_str()); } 00264 00265 Mat Variable::defineGradientLocation(const Mat& m) 00266 { 00267 if(!m.isCompact()) 00268 PLERROR("In Variable::setGradientMatrix, Variables require compact matrices"); 00269 Mat oldm = matGradient; 00270 matGradient = m; 00271 gradient = m.toVec(); 00272 gradientdata = gradient.data(); 00273 return oldm; 00274 } 00275 00276 void Variable::print(ostream& out) const 00277 { 00278 // This is just to strip "Variable" out of the class name (as they all 00279 // end in "Variable") 00280 string cn=info(); 00281 int len = (int)cn.length(); 00282 if (len >= 9 && cn.substr(len-8,8) == "Variable") 00283 out << cn.substr(0,len-8) << endl; 00284 else 00285 out << cn << endl; 00286 } 00287 00288 PLEARN_IMPLEMENT_ABSTRACT_OBJECT(Variable, "ONE LINE DESCR", "NO HELP"); 00289 00290 void Variable::makeDeepCopyFromShallowCopy(map<const void*, void*>& copies) 00291 { 00292 Object::makeDeepCopyFromShallowCopy(copies); 00293 deepCopyField(value, copies); 00294 deepCopyField(gradient, copies); 00295 deepCopyField(matValue, copies); 00296 deepCopyField(matGradient, copies); 00297 valuedata = value.data(); 00298 gradientdata = gradient.data(); 00299 varDeepCopyField(g, copies); 00300 } 00301 00302 void Variable::clearDiagHessian() 00303 { 00304 if(!diaghessian) 00305 resizeDiagHessian(); 00306 diaghessian.clear(); 00307 } 00308 00309 00310 void Variable::fbprop() 00311 { 00312 fprop(); 00313 bprop(); 00314 } 00315 00316 void Variable::fbbprop() 00317 { 00318 fprop(); 00319 bprop(); 00320 bbprop(); 00321 } 00322 00323 void Variable::bbprop() 00324 { PLERROR("bbprop not implemented for this variable (%s)",classname().c_str()); } 00325 00326 void Variable::symbolicBprop() 00327 { PLERROR("symbolicBprop not implemented for this variable (%s)",classname().c_str()); } 00328 00329 void Variable::rfprop() 00330 { PLERROR("rfprop not implmented for this variable (%s)",classname().c_str()); } 00331 00332 void Variable::setName(const string& the_name) 00333 { varname = the_name; } 00334 00335 string Variable::getName() const 00336 { 00337 if (varname.size() == 0) 00338 return "#" + tostring(varnum); 00339 00340 return varname; 00341 } 00342 00343 void Variable::oldread(istream& in) 00344 { PLearn::read(in, value); } 00345 00346 void Variable::write(ostream& out) const 00347 { PLearn::write(out, value); } 00348 00349 00350 Var Variable::subVec(int start, int len, bool transpose) 00351 { 00352 if(isColumnVec()) 00353 return subMat(start,0,len,1,transpose); 00354 else if(isRowVec()) 00355 return subMat(0,start,1,len,transpose); 00356 00357 PLERROR("In Variable::subVec variable is not a vec (single column or single row)"); 00358 return Var(); 00359 } 00360 00361 Var Variable::subMat(int i, int j, int sublength, int subwidth, bool do_transpose) 00362 { 00363 if(do_transpose) 00364 return new SubMatTransposeVariable(this, i, j, sublength, subwidth); 00365 else 00366 return new SubMatVariable(this, i, j, sublength, subwidth); 00367 } 00368 00369 void Variable::fprop_from_all_sources() 00370 { 00371 VarArray all_sources = sources(); 00372 unmarkAncestors(); 00373 VarArray prop_path = propagationPath(all_sources,Var(this)); 00374 prop_path.fprop(); 00375 } 00376 00377 void Variable::printInfos(bool print_gradient) 00378 { 00379 VarArray ancetres = ancestors(); 00380 unmarkAncestors(); 00381 ancetres.printInfo(print_gradient); 00382 } 00383 00384 void Variable::accg(Var vg) 00385 { 00386 if(g || (vg.length()==length() && vg.width()==width())) 00387 g += vg; 00388 else // g does not exist 00389 { 00390 g = Var(length(),width()); 00391 g += vg; 00392 } 00393 } 00394 00395 void Variable::verifyGradient(real step) 00396 { 00397 VarArray inputs = sources(); 00398 unmarkAncestors(); 00399 Func f(inputs,Var(this)); 00400 Vec p(inputs.nelems()); 00401 inputs >> p; 00402 f->verifyGradient(p,step); 00403 } 00404 00405 // set value = value + (step_size*coeff + b) * direction 00406 // with step_size possibly scaled down s.t. box constraints are satisfied 00407 // return true if box constraints have been hit with the update 00408 00409 bool Variable::update(real step_size, Vec direction_vec, real coeff, real b) 00410 { 00411 static bool hit; 00412 static real full_coeff; 00413 if(allows_partial_update) 00414 PLWARNING("Warning in Variable::update(real,Vec): will update every elements of the Variable"); 00415 hit = false; 00416 full_coeff = step_size * coeff + b; 00417 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00418 // constrained update 00419 { 00420 real* direction = direction_vec.data(); 00421 for(int i=0; i<nelems(); i++) 00422 { 00423 valuedata[i] += (full_coeff) * direction[i]; 00424 if(valuedata[i]<min_value) 00425 { 00426 valuedata[i]=min_value; 00427 hit = true; 00428 } 00429 else if(valuedata[i]>max_value) 00430 { 00431 valuedata[i]=max_value; 00432 hit = true; 00433 } 00434 } 00435 } 00436 else 00437 // unconstrained update 00438 { 00439 real* direction = direction_vec.data(); 00440 for(int i=0; i<nelems(); i++) 00441 { 00442 valuedata[i] += (full_coeff) * direction[i]; 00443 } 00444 } 00445 return hit; 00446 } 00447 00448 bool Variable::update(Vec step_sizes, Vec direction_vec, real coeff, real b) 00449 { 00450 if(allows_partial_update) 00451 PLWARNING("Warning in Variable::update(Vec,Vec): will update every elements of the Variable"); 00452 bool hit=false; 00453 real* direction = direction_vec.data(); 00454 real* step = step_sizes.data(); 00455 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00456 // constrained update 00457 { 00458 for(int i=0; i<nelems(); i++) 00459 { 00460 valuedata[i] += (step[i] * coeff + b) * direction[i]; 00461 if(valuedata[i]<min_value) 00462 { 00463 valuedata[i]=min_value; 00464 hit = true; 00465 } 00466 else if(valuedata[i]>max_value) 00467 { 00468 valuedata[i]=max_value; 00469 hit = true; 00470 } 00471 } 00472 } 00473 else 00474 // unconstrained update 00475 for(int i=0; i<nelems(); i++) 00476 valuedata[i] += (step[i] * coeff + b) * direction[i]; 00477 return hit; 00478 } 00479 00480 bool Variable::update(real step_size) 00481 { 00482 bool hit=false; 00483 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00484 // constrained update 00485 { 00486 if (allows_partial_update && gradient_status!=2) 00487 { 00488 if (gradient_status!=0) 00489 { 00490 for (int r=0;r<rows_to_update.length();r++) 00491 { 00492 int row = rows_to_update[r]; 00493 real* direction = matGradient[row]; 00494 real* params = matValue[row]; 00495 for(int i=0; i<width(); i++) 00496 { 00497 params[i] += step_size*direction[i]; 00498 if(params[i]<min_value) 00499 { 00500 params[i]=min_value; 00501 hit = true; 00502 } 00503 else if(params[i]>max_value) 00504 { 00505 params[i]=max_value; 00506 hit = true; 00507 } 00508 //if (allows_partial_update) 00509 // direction[i]=0; 00510 } 00511 } 00512 //rows_to_update.resize(0); 00513 //gradient_status=0; 00514 } 00515 } 00516 else for (int row=0;row<length();row++) 00517 { 00518 real* direction = matGradient[row]; 00519 real* params = matValue[row]; 00520 for(int i=0; i<width(); i++) 00521 { 00522 params[i] += step_size*direction[i]; 00523 if(params[i]<min_value) 00524 { 00525 params[i]=min_value; 00526 hit = true; 00527 } 00528 else if(params[i]>max_value) 00529 { 00530 params[i]=max_value; 00531 hit = true; 00532 } 00533 //if (allows_partial_update) 00534 // direction[i]=0; 00535 } 00536 } 00537 } 00538 else 00539 // unconstrained update 00540 { 00541 if (allows_partial_update && gradient_status!=2) 00542 { 00543 if (gradient_status!=0) 00544 { 00545 for (int r=0;r<rows_to_update.length();r++) 00546 { 00547 int row = rows_to_update[r]; 00548 real* direction = matGradient[row]; 00549 real* params = matValue[row]; 00550 for(int i=0; i<width(); i++) 00551 { 00552 params[i] += step_size*direction[i]; 00553 //direction[i] = 0; 00554 } 00555 } 00556 //rows_to_update.resize(0); 00557 //gradient_status=0; 00558 } 00559 } 00560 else for (int row=0;row<length();row++) 00561 { 00562 real* direction = matGradient[row]; 00563 real* params = matValue[row]; 00564 for(int i=0; i<width(); i++) 00565 params[i] += step_size*direction[i]; 00566 } 00567 } 00568 return hit; 00569 } 00570 00571 00572 // set value = value + step_size * gradient 00573 // with step_size possibly scaled down s.t. box constraints are satisfied 00574 // return true if box constraints have been hit with the update 00575 00576 /* 00577 bool Variable::update(real step_size) 00578 { 00579 bool hit=false; 00580 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00581 // constrained update 00582 { 00583 real* direction = gradient.data(); 00584 for(int i=0; i<nelems(); i++) 00585 { 00586 valuedata[i] += step_size*direction[i]; 00587 if(valuedata[i]<min_value) 00588 { 00589 valuedata[i]=min_value; 00590 hit = true; 00591 } 00592 else if(valuedata[i]>max_value) 00593 { 00594 valuedata[i]=max_value; 00595 hit = true; 00596 } 00597 } 00598 } 00599 else 00600 // unconstrained update 00601 { 00602 real* direction = gradient.data(); 00603 for(int i=0; i<nelems(); i++) 00604 valuedata[i] += step_size*direction[i]; 00605 } 00606 00607 return hit; 00608 } 00609 */ 00610 00611 00612 // set value = new_value 00613 // projected down in each direction independently in the 00614 // subspace in which the box constraints are satisfied. 00615 // return true if box constraints have been hit with the update 00616 bool Variable::update(Vec new_value) 00617 { 00618 if(allows_partial_update) 00619 PLWARNING("Warning in Variable::update(Vec): will update every elements of the Variable"); 00620 bool hit=false; 00621 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00622 // constrained update 00623 { 00624 real* new_v = new_value.data(); 00625 for(int i=0; i<nelems(); i++) 00626 { 00627 valuedata[i] = new_v[i]; 00628 if(valuedata[i]<min_value) 00629 { 00630 valuedata[i]=min_value; 00631 hit = true; 00632 } 00633 else if(valuedata[i]>max_value) 00634 { 00635 valuedata[i]=max_value; 00636 hit = true; 00637 } 00638 } 00639 } 00640 else 00641 // unconstrained update 00642 { 00643 real* new_v = new_value.data(); 00644 for(int i=0; i<nelems(); i++) 00645 valuedata[i] = new_v[i]; 00646 } 00647 return hit; 00648 } 00649 00650 // Using the box constraints on the values, return 00651 // the maximum allowable step_size in the given direction 00652 // i.e., argmax_{step_size} {new = value + step_size * direction, new in box} 00653 real Variable::maxUpdate(Vec direction) 00654 { 00655 real max_step_size=FLT_MAX; 00656 if(min_value>-FLT_MAX || max_value<FLT_MAX) 00657 // constrained update 00658 { 00659 real* dir = direction.data(); 00660 for(int i=0; i<nelems(); i++) 00661 { 00662 real v = valuedata[i]; 00663 if (v<min_value || v>max_value) 00664 PLERROR("Variable::maxUpdate:current value %f already out of bounds (%f,%f)!", 00665 v,min_value,max_value); 00666 if (dir[i]>0) // want to increase value: check max_value 00667 { 00668 if (max_value<FLT_MAX) 00669 { 00670 real maxstep = (max_value - v)/dir[i]; 00671 if (maxstep < max_step_size) max_step_size = maxstep; 00672 } 00673 } 00674 else if (dir[i]<0) // want to decrease value: check min_value 00675 { 00676 if (min_value > -FLT_MAX) 00677 { 00678 real maxstep = (min_value - v)/dir[i]; 00679 if (maxstep < max_step_size) max_step_size = maxstep; 00680 } 00681 } 00682 } 00683 } 00684 // else unconstrained 00685 00686 return max_step_size; 00687 } 00688 00689 void Variable::makeSharedValue(real* x, int n) 00690 { 00691 if (n!=nelems()) PLERROR("Variable::makeSharedValue, n(%d) inconsistent with nelems(%d)", 00692 n,nelems()); 00693 real* v=value.data(); 00694 valuedata=x; 00695 if (x!=v) 00696 for (int j=0;j<n;j++) 00697 x[j]=v[j]; 00698 value.storage = new Storage<real>(n,x); 00699 value.offset_ = 0; 00700 matValue.storage = value.storage; 00701 matValue.offset_ = 0; 00702 matValue.mod_ = matValue.width(); 00703 } 00704 00705 void Variable::makeSharedValue(PP<Storage<real> > storage, int offset_) 00706 { 00707 int n=nelems(); 00708 if (storage->length()<offset_+n) 00709 PLERROR("Variable::makeSharedValue, storage(%d) too small({d+%d)", 00710 storage->length(),offset_,nelems()); 00711 real* v=value.data(); 00712 real* x=valuedata=storage->data+offset_; 00713 if (x!=v) 00714 for (int j=0;j<n;j++) 00715 x[j]=v[j]; 00716 value.storage = storage; 00717 value.offset_ = offset_; 00718 matValue.storage = storage; 00719 matValue.offset_ = offset_; 00720 matValue.mod_ = matValue.width(); 00721 } 00722 00723 void Variable::makeSharedGradient(Vec& v, int offset_) 00724 { 00725 makeSharedGradient(v.storage,v.offset_+offset_); 00726 } 00727 00728 void Variable::makeSharedGradient(PP<Storage<real> > storage, int offset_) 00729 { 00730 int n=nelems(); 00731 if (storage->length()<offset_+n) 00732 PLERROR("Variable::makeSharedGradient, storage(%d) too small({d+%d)", 00733 storage->length(),offset_,nelems()); 00734 real* v=gradient.data(); 00735 real* x=gradientdata=storage->data+offset_; 00736 if (x!=v) 00737 for (int j=0;j<n;j++) 00738 x[j]=v[j]; 00739 gradient.storage = storage; 00740 gradient.offset_ = offset_; 00741 matGradient.storage = storage; 00742 matGradient.offset_ = offset_; 00743 matGradient.mod_ = matGradient.width(); 00744 } 00745 00746 00747 void Variable::makeSharedGradient(real* x, int n) 00748 { 00749 if (n!=nelems()) PLERROR("Variable::makeSharedGradient, n(%d) inconsistent with nelems(%d)", 00750 n,nelems()); 00751 real* v=gradient.data(); 00752 gradientdata=x; 00753 if (x!=v) 00754 for (int j=0;j<n;j++) 00755 x[j]=v[j]; 00756 gradient.storage = new Storage<real>(n,x); 00757 gradient.offset_ = 0; 00758 matGradient.storage = gradient.storage; 00759 matGradient.offset_ = 0; 00760 matGradient.mod_ = matGradient.width(); 00761 } 00762 00763 void Variable::makeSharedValue(Vec& v, int offset_) 00764 { 00765 makeSharedValue(v.storage,v.offset_+offset_); 00766 } 00767 00768 void Variable::makeSharedRValue(PP<Storage<real> > storage, int offset_) 00769 { 00770 resizeRValue(); 00771 int n=nelems(); 00772 if (storage->length()<offset_+n) 00773 PLERROR("Variable::makeSharedRValue, storage(%d) too small({d+%d)", 00774 storage->length(),offset_,nelems()); 00775 real* v=rValue.data(); 00776 real* x=rvaluedata=storage->data+offset_; 00777 if (x!=v) 00778 for (int j=0;j<n;j++) 00779 x[j]=v[j]; 00780 rValue.storage = storage; 00781 rValue.offset_ = offset_; 00782 matRValue.storage = storage; 00783 matRValue.offset_ = offset_; 00784 matRValue.mod_ = matRValue.width(); 00785 } 00786 00787 00788 void Variable::makeSharedRValue(real* x, int n) 00789 { 00790 if (n!=nelems()) PLERROR("Variable::makeSharedRValue, n(%d) inconsistent with nelems(%d)", 00791 n,nelems()); 00792 resizeRValue(); 00793 real* v=rValue.data(); 00794 rvaluedata=x; 00795 if (x!=v) 00796 for (int j=0;j<n;j++) 00797 x[j]=v[j]; 00798 rValue.storage = new Storage<real>(n,x); 00799 rValue.offset_ = 0; 00800 matRValue.storage = rValue.storage; 00801 matRValue.offset_ = 0; 00802 matRValue.mod_ = matRValue.width(); 00803 } 00804 00805 void Variable::makeSharedRValue(Vec& v, int offset_) 00806 { 00807 makeSharedRValue(v.storage,v.offset_+offset_); 00808 } 00809 00810 void Variable::resizeDiagHessian() 00811 { 00812 matDiagHessian.resize(length(),width()); 00813 diaghessian = matDiagHessian.toVec(); 00814 diaghessiandata = diaghessian.data(); 00815 } 00816 00817 void Variable::resizeRValue() 00818 { 00819 if (!rvaluedata) 00820 { 00821 matRValue.resize(length(),width()); 00822 rValue = matRValue.toVec(); 00823 rvaluedata = rValue.data(); 00824 } 00825 } 00826 00827 00828 00829 } // end of namespace PLearn 00830

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