Commit ec4d0c10 authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Changed IFunction interface to add "explicitly set" flag. re #1126

parent 22b1dbf7
......@@ -67,12 +67,12 @@ public:
/// Derivatives to be used in covariance matrix calculation.
void calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData);
/// Address of i-th parameter
double& parameter(int);
/// Address of i-th parameter
double parameter(int i)const;
/// Get parameter by name.
double& getParameter(const std::string& name);
/// Set i-th parameter
void setParameter(int, const double& value, bool explicitlySet = true);
/// Get i-th parameter
double getParameter(int i)const;
/// Set parameter by name.
void setParameter(const std::string& name, const double& value, bool explicitlySet = true);
/// Get parameter by name.
double getParameter(const std::string& name)const;
/// Total number of parameters
......@@ -83,6 +83,8 @@ public:
int parameterIndex(const double* p)const;
/// Returns the name of parameter i
std::string parameterName(int i)const;
/// Checks if a parameter has been set explicitly
bool isExplicitlySet(int i)const;
/// Number of active (in terms of fitting) parameters
int nActive()const;
......@@ -147,6 +149,8 @@ protected:
virtual void declareParameter(const std::string& name,double initValue = 0);
/// Add a new tie
virtual void addTie(ParameterTie* tie);
/// Get the address of the parameter
virtual double* getParameterAddress(int i);
private:
......
......@@ -69,12 +69,12 @@ public:
/// This method returns same as functionDeriv() plus any penalty if constraints are violated
void functionDerivWithConstraint(Jacobian* out, const double* xValues, const int& nData);
/// Address of i-th parameter
virtual double& parameter(int);
/// Address of i-th parameter
virtual double parameter(int i)const;
/// Get parameter by name.
virtual double& getParameter(const std::string& name);
/// Set i-th parameter
virtual void setParameter(int, const double& value, bool explicitlySet = true);
/// Get i-th parameter
virtual double getParameter(int i)const;
/// Set parameter by name.
virtual void setParameter(const std::string& name, const double& value, bool explicitlySet = true);
/// Get parameter by name.
virtual double getParameter(const std::string& name)const;
/// Total number of parameters
......@@ -85,6 +85,8 @@ public:
virtual int parameterIndex(const double* p)const;
/// Returns the name of parameter i
virtual std::string parameterName(int i)const;
/// Checks if a parameter has been set explicitly
virtual bool isExplicitlySet(int i)const;
/// Number of active (in terms of fitting) parameters
virtual int nActive()const{return m_indexMap.size();}
......@@ -127,6 +129,8 @@ protected:
virtual bool removeTie(int i);
/// Get the tie of i-th parameter
virtual ParameterTie* getTie(int i)const;
/// Get the address of the parameter
virtual double* getParameterAddress(int i);
/// Nonvirtual member which removes all declared parameters
void clearAllParameters();
......@@ -142,6 +146,8 @@ private:
std::vector<ParameterTie*> m_ties;
/// Holds the constraints added to function
std::vector<IConstraint*> m_constraints;
/// Flags of explicitly set parameters
std::vector<bool> m_explicitlySet;
};
} // namespace API
......
......@@ -122,12 +122,12 @@ public:
/// are different form the declared ones.
virtual void calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData);
/// Address of i-th parameter
virtual double& parameter(int) = 0;
/// Address of i-th parameter
virtual double parameter(int i)const = 0;
/// Get parameter by name.
virtual double& getParameter(const std::string& name) = 0;
/// Set i-th parameter
virtual void setParameter(int, const double& value, bool explicitlySet = true) = 0;
/// Get i-th parameter
virtual double getParameter(int i)const = 0;
/// Set parameter by name.
virtual void setParameter(const std::string& name, const double& value, bool explicitlySet = true) = 0;
/// Get parameter by name.
virtual double getParameter(const std::string& name)const = 0;
/// Total number of parameters
......@@ -138,6 +138,8 @@ public:
virtual int parameterIndex(const double* p)const = 0;
/// Returns the name of parameter i
virtual std::string parameterName(int i)const = 0;
/// Checks if a parameter has been set explicitly
virtual bool isExplicitlySet(int i)const = 0;
/// Number of active (in terms of fitting) parameters
virtual int nActive()const = 0;
......@@ -206,7 +208,10 @@ protected:
virtual bool removeTie(int i) = 0;
/// Get the tie of i-th parameter
virtual ParameterTie* getTie(int i)const = 0;
/// Get the address of the parameter
virtual double* getParameterAddress(int i) = 0;
friend class ParameterTie;
friend class CompositeFunction;
/// Shared pointer to the workspace
......
......@@ -163,22 +163,33 @@ void CompositeFunction::calJacobianForCovariance(Jacobian* out, const double* xV
}
/// Address of i-th parameter
double& CompositeFunction::parameter(int i)
/** Sets a new value to the i-th parameter.
* @param i The parameter index
* @param value The new value
* @param explicitlySet A boolean falgging the parameter as explicitly set (by user)
*/
void CompositeFunction::setParameter(int i, const double& value, bool explicitlySet)
{
int iFun = functionIndex(i);
return m_functions[ iFun ]->parameter(i - m_paramOffsets[iFun]);
m_functions[ iFun ]->setParameter(i - m_paramOffsets[iFun],value,explicitlySet);
}
/// Address of i-th parameter
double CompositeFunction::parameter(int i)const
/** Get the i-th parameter.
* @param i The parameter index
*/
double CompositeFunction::getParameter(int i)const
{
int iFun = functionIndex(i);
return m_functions[ iFun ]->parameter(i - m_paramOffsets[iFun]);
return m_functions[ iFun ]->getParameter(i - m_paramOffsets[iFun]);
}
/// Get parameter by name.
double& CompositeFunction::getParameter(const std::string& name)
/**
* Sets a new value to a parameter by name.
* @param name The name of the parameter.
* @param value The new value
* @param explicitlySet A boolean falgging the parameter as explicitly set (by user)
*/
void CompositeFunction::setParameter(const std::string& name, const double& value, bool explicitlySet)
{
std::string pname;
int index;
......@@ -187,11 +198,14 @@ double& CompositeFunction::getParameter(const std::string& name)
throw std::invalid_argument("CompositeFunction::getParameter: parameter name must contain function index");
else
{
return getFunction(index)->getParameter(pname);
getFunction(index)->setParameter(pname,value,explicitlySet);
}
}
/// Get parameter by name.
/**
* Parameters by name.
* @param name The name of the parameter.
*/
double CompositeFunction::getParameter(const std::string& name)const
{
std::string pname;
......@@ -427,7 +441,7 @@ void CompositeFunction::removeFunction(int i, bool del)
std::vector<const double*> pars;
for(int j=0;j<fun->nParams();j++)
{
pars.push_back(&fun->parameter(j));
pars.push_back(fun->getParameterAddress(j));
}
for(int j=0;j<nParams();)
......@@ -747,6 +761,22 @@ void CompositeFunction::setParametersToSatisfyConstraints()
}
}
/// Get the address of the parameter
double* CompositeFunction::getParameterAddress(int i)
{
int iFun = functionIndex(i);
return m_functions[ iFun ]->getParameterAddress(i - m_paramOffsets[iFun]);
}
/**
* @param i The parameter index
*/
bool CompositeFunction::isExplicitlySet(int i)const
{
int iFun = functionIndex(i);
return m_functions[ iFun ]->isExplicitlySet(i - m_paramOffsets[iFun]);
}
} // namespace API
} // namespace Mantid
......@@ -62,31 +62,43 @@ void Function::setParametersToSatisfyConstraints()
}
}
/** Reference to the i-th parameter.
/** Sets a new value to the i-th parameter.
* @param i The parameter index
* @param value The new value
* @param explicitlySet A boolean falgging the parameter as explicitly set (by user)
*/
double& Function::parameter(int i)
void Function::setParameter(int i, const double& value, bool explicitlySet)
{
if (i >= nParams())
{
throw std::out_of_range("Function parameter index out of range.");
return m_parameters[i];
}
m_parameters[i] = value;
if (explicitlySet)
{
m_explicitlySet[i] = true;
}
}
/** Reference to the i-th parameter.
/** Get the i-th parameter.
* @param i The parameter index
*/
double Function::parameter(int i)const
double Function::getParameter(int i)const
{
if (i >= nParams())
{
throw std::out_of_range("Function parameter index out of range.");
}
return m_parameters[i];
}
/**
* Parameters by name.
* Sets a new value to a parameter by name.
* @param name The name of the parameter.
* @param value The new value
* @param explicitlySet A boolean falgging the parameter as explicitly set (by user)
*/
double& Function::getParameter(const std::string& name)
void Function::setParameter(const std::string& name, const double& value, bool explicitlySet)
{
std::string ucName(name);
//std::transform(name.begin(), name.end(), ucName.begin(), toupper);
......@@ -98,7 +110,7 @@ double& Function::getParameter(const std::string& name)
msg << "Function parameter ("<<ucName<<") does not exist.";
throw std::invalid_argument(msg.str());
}
return m_parameters[it - m_parameterNames.begin()];
return setParameter(it - m_parameterNames.begin(),value,explicitlySet);
}
/**
......@@ -185,6 +197,7 @@ void Function::declareParameter(const std::string& name,double initValue )
m_indexMap.push_back(nParams());
m_parameterNames.push_back(ucName);
m_parameters.push_back(initValue);
m_explicitlySet.push_back(false);
}
/** This method calls function() and add any penalty to its output if constraints are violated.
......@@ -379,7 +392,7 @@ bool Function::removeTie(int i)
{
throw std::out_of_range("Function parameter index out of range.");
}
double* par = &parameter(i);
double* par = &m_parameters[i];
std::vector<ParameterTie*>::iterator it = std::find_if(m_ties.begin(),m_ties.end(),TieEqual(par));
if (it != m_ties.end())
{
......@@ -442,5 +455,25 @@ void Function::clearAllParameters()
m_indexMap.clear();
}
/// Get the address of the parameter
double* Function::getParameterAddress(int i)
{
if (i >= nParams())
{
throw std::out_of_range("Function parameter index out of range.");
}
return &m_parameters[i];
}
/// Checks if a parameter has been set explicitly
bool Function::isExplicitlySet(int i)const
{
if (i >= nParams())
{
throw std::out_of_range("Function parameter index out of range.");
}
return m_explicitlySet[i];
}
} // namespace API
} // namespace Mantid
......@@ -120,7 +120,7 @@ namespace Mantid
}
parValue.erase(i);
}
fun->getParameter(parName) = atof(parValue.c_str());
fun->setParameter(parName,atof(parValue.c_str()));
}
}
if (isComposite)
......
......@@ -63,13 +63,13 @@ void IFunction::updateActive(const double* in)
void IFunction::setActiveParameter(int i,double value)
{
int j = indexOfActive(i);
parameter(j) = value;
setParameter(j,value,false);
}
double IFunction::activeParameter(int i)const
{
int j = indexOfActive(i);
return parameter(j);
return getParameter(j);
}
/** Create a new tie. IFunctions can have their own types of ties.
......@@ -140,7 +140,7 @@ std::string IFunction::asString()const
}
for(int i=0;i<nParams();i++)
{
ostr<<','<<parameterName(i)<<'='<<parameter(i);
ostr<<','<<parameterName(i)<<'='<<getParameter(i);
}
return ostr.str();
}
......
......@@ -19,7 +19,7 @@ namespace API
"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
m_parser->SetVarFactory(AddVariable, this);
m_par = &funct->getParameter(parName);
m_par = funct->getParameterAddress(funct->parameterIndex(parName));
}
/// Destructor
......@@ -35,7 +35,7 @@ namespace API
double* ParameterTie::AddVariable(const char *varName, void *palg)
{
ParameterTie& tie = *(ParameterTie*)palg;
return &(tie.m_function->getParameter(std::string(varName)));
return tie.m_function->getParameterAddress(tie.m_function->parameterIndex(std::string(varName)));
}
/**
......
......@@ -55,18 +55,18 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
TS_ASSERT_EQUALS(f.nParams(),4);
TS_ASSERT_EQUALS(f.nActive(),4);
TS_ASSERT_EQUALS(f.parameter(0),1.0);
TS_ASSERT_EQUALS(f.parameter(1),1.1);
TS_ASSERT_EQUALS(f.parameter(2),1.2);
TS_ASSERT_EQUALS(f.parameter(3),1.3);
TS_ASSERT_EQUALS(f.getParameter(0),1.0);
TS_ASSERT_EQUALS(f.getParameter(1),1.1);
TS_ASSERT_EQUALS(f.getParameter(2),1.2);
TS_ASSERT_EQUALS(f.getParameter(3),1.3);
TS_ASSERT_EQUALS(f.parameterName(0),"c0");
TS_ASSERT_EQUALS(f.parameterName(1),"c1");
......@@ -118,10 +118,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.removeActive(1);
f.removeActive(3);
......@@ -154,10 +154,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.removeActive(1);
f.removeActive(3);
......@@ -195,10 +195,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.removeActive(1);
f.removeActive(3);
......@@ -212,10 +212,10 @@ public:
TS_ASSERT_EQUALS(f.activeParameter(0),2.0);
TS_ASSERT_EQUALS(f.activeParameter(1),2.1);
TS_ASSERT_EQUALS(f.parameter(0),2.0);
TS_ASSERT_EQUALS(f.parameter(1),1.1);
TS_ASSERT_EQUALS(f.parameter(2),2.1);
TS_ASSERT_EQUALS(f.parameter(3),1.3);
TS_ASSERT_EQUALS(f.getParameter(0),2.0);
TS_ASSERT_EQUALS(f.getParameter(1),1.1);
TS_ASSERT_EQUALS(f.getParameter(2),2.1);
TS_ASSERT_EQUALS(f.getParameter(3),1.3);
TS_ASSERT_EQUALS(f.getParameter("c0"),2.0);
TS_ASSERT_EQUALS(f.getParameter("c1"),1.1);
......@@ -228,10 +228,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.tie("c1","0");
f.tie("c3","0");
......@@ -266,10 +266,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.tie("c1","c0+4");
f.tie("c3","c2/2");
......@@ -290,10 +290,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.tie("c1","c0+4");
f.tie("c3","c2/2");
......@@ -309,7 +309,7 @@ public:
TS_ASSERT_EQUALS(f.getParameter("c3"),0.6);
f.removeTie("c3");
f.getParameter("c3") = 3.3;
f.setParameter("c3",3.3);
f.applyTies();
......@@ -336,10 +336,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.tie("c1","c0+4");
f.tie("c3","c2/2");
......@@ -355,8 +355,8 @@ public:
TS_ASSERT_EQUALS(f.getParameter("c3"),0.6);
f.clearTies();
f.getParameter("c1") = 3.1;
f.getParameter("c3") = 3.3;
f.setParameter("c1",3.1);
f.setParameter("c3",3.3);
f.applyTies();
......@@ -383,10 +383,10 @@ public:
{
IFT_Funct f;
f.getParameter("c0") = 1.0;
f.getParameter("c1") = 1.1;
f.getParameter("c2") = 1.2;
f.getParameter("c3") = 1.3;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
f.setParameter("c2",1.2);
f.setParameter("c3",1.3);
f.tie("c1","c0+4");
f.tie("c3","c2/2");
......@@ -405,6 +405,18 @@ public:
}
void testExplicitlySet()
{
IFT_Funct f;
f.setParameter("c0",1.0);
f.setParameter("c1",1.1);
TS_ASSERT(f.isExplicitlySet(0));
TS_ASSERT(f.isExplicitlySet(1));
TS_ASSERT(!f.isExplicitlySet(2));
TS_ASSERT(!f.isExplicitlySet(3));
}
private:
void interrupt()
{
......
......@@ -49,31 +49,31 @@ public:
double centre()const
{
return parameter(0);
return getParameter(0);
}
double height()const
{
return parameter(1);
return getParameter(1);
}
double width()const
{
return parameter(2);
return getParameter(2);
}
void setCentre(const double c)
{
parameter(0) = c;
setParameter(0,c);
}
void setHeight(const double h)
{
parameter(1) = h;
setParameter(1,h);
}