file: ../SURF/parameter.cc
#include "parameter.h"
#include <assert.h>
parameter* parameter::detector=NULL;
bool parameter::detecting=false;
bool parameter::deleting=false;
parameter::parameter(const string& newname,const double& newval):dependents(0)
{//postcondition: val is valid and everything is setup.
valmake=NULL;
determined=false;
nme=newname;
setvalue(newval);
}
parameter::parameter():dependents(0)
{//postcondition: sensible defaults.
valmake=NULL;
determined=false;
setvalue(0);
}
parameter::parameter(const string& newname,
double (*newmake)()):dependents(0)
{//postcondition: a dependent parameter is setup and all dependencies are
//detected
valmake=NULL;
determined=false;
nme=newname(0,newname.length());
setmake(newmake);
}
void parameter::setmake(double (*newmake)())
{//precondition: this is valid
//postcondition: all dependencies of make are removed and all dependencies
//of newmake are put in
if (valmake!=NULL){ //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
deleting=true;
detector=this;
valmake();
detector=NULL;
deleting=false;
}
valmake=newmake;
if (newmake==NULL) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
determined=false;
else {
determined=true;
detecting=true;
detector=this;
setvalue(valmake());
detector=NULL;
detecting=false;
}
}
void parameter::setvalue(const double& newval)
{//postcondition: val=newval and all values dependent on val have value_good
// set to false
val=newval;
value_good=true;
int i;
if (!determined) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
for(i=dependents.low();i<=dependents.high();i++)
dependents[i]->value_good=false;
}
void parameter::setdependents(array<parameter *>& newdep)
{//duh.
dependents=newdep;
}
int parameter::location(const parameter *target)
{//returns index of item == target in dependents
if (dependents.high()>=dependents.low()){ //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
int i;
for (i=dependents.low();i<=dependents.high();i++)
if(target==dependents[i]) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
return i;
}
return dependents.low()-1;
}
parameter::operator double()
{//Detects dependencies on free parameters if deleting || detecting //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
//returns a valid val.
int i;
if (deleting && !determined){
int temp=location(detector);
assert(temp>(dependents.low()-1) && temp <= dependents.high());
array<parameter *> tarray(dependents.high());
for (i=tarray.low();i<=tarray.high();i++){
if (i<temp) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
tarray[i]=dependents[i];
else if (i>temp) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
tarray[i]=dependents[i+1];
}
dependents=tarray;
}
if (detecting && !determined){
if ((dependents.low()-1)==location(detector)){ //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
array<parameter *> temp(dependents.high()+2);//make an array one larger
for (i=dependents.low();i<=dependents.high();i++)
temp[i]=dependents[i];
temp[temp.high()]=detector;
dependents=temp;
temp=array<parameter*>(detector->dependents.high()+2);
for (i=detector->dependents.low();i<=detector->dependents.high();i++)
temp[i]=detector->dependents[i];
temp[temp.high()]=this;
detector->dependents=temp;
}
}
if(determined && (!value_good || detecting || deleting)){
setvalue(valmake());
}
return val;
}
parameter& parameter::operator=(const parameter& from)
{//The copy constructor must be used very carefully.
//It's use invalidates the object which it is copying.
//aka: Conservation of Parameters.
if (this!=&from){ //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
nme=from.nme(0,from.nme.length());
determined=from.determined;
val=from.val;
value_good=from.value_good;
valmake=from.valmake;
dependents=from.dependents;
//This is the piece of code which forces conservation of parameters
int i,temp;
for (i=dependents.low();i<=dependents.high();i++){
dependents[i]->dependents[temp=dependents[i]->location(&from)]=this;
assert(temp>dependents[i]->dependents.low()-1);
}
}
return *this;
}
void parameter::print()
{
cout << nme << " value=" << val << " determined =";
if (determined) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
cout << "true";
else
cout << "false";
cout << " value_good=" << value_good;
int i;
if (determined) //OVERLOAD CALL: if: parameter.cc(?), parameter.cc(?)
cout << " dependent on = ";
else
cout << " dependents ";
for (i=dependents.low();i<=dependents.high();i++)
cout << dependents[i]->nme << " ";
cout << endl;
}
C++ to HTML Conversion by ctoohtml