00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037  
00038 
00039 
00040 
00041 
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 
00060 
00061 
namespace PLearn {
00062 
using namespace std;
00063 
00064 
00065 
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 
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 
00218 
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   
00279   
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 
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 
00406 
00407 
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     
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     
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     
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     
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     
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               
00509               
00510             }
00511           }
00512           
00513           
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             
00534             
00535           }
00536       }
00537     }
00538   
else
00539     
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               
00554             }
00555           }
00556           
00557           
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 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
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     
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     
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 
00651 
00652 
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     
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) 
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) 
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   
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 } 
00830