Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/Exception.h"
Roman Tolchenov
committed
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidAPI/IConstraint.h"
Peterson, Peter
committed
#include <boost/lexical_cast.hpp>
#include <boost/shared_array.hpp>
#include <sstream>
#include <iostream>
Roman Tolchenov
committed
#include <algorithm>
namespace Mantid
{
namespace API
{
//DECLARE_FUNCTION(CompositeFunction)
/// Copy contructor
CompositeFunction::CompositeFunction(const CompositeFunction& f)
:m_nActive(f.m_nParams),m_nParams(f.m_nParams),m_iConstraintFunction(0)
{
m_functions.assign(f.m_functions.begin(),f.m_functions.end());
m_activeOffsets.assign(f.m_activeOffsets.begin(),f.m_activeOffsets.end());
m_paramOffsets.assign(f.m_paramOffsets.begin(),f.m_paramOffsets.end());
}
///Assignment operator
CompositeFunction& CompositeFunction::operator=(const CompositeFunction& f)
{
m_nActive = f.m_nActive;
m_nParams = f.m_nParams;
m_functions.assign(f.m_functions.begin(),f.m_functions.end());
m_activeOffsets.assign(f.m_activeOffsets.begin(),f.m_activeOffsets.end());
m_paramOffsets.assign(f.m_paramOffsets.begin(),f.m_paramOffsets.end());
m_iConstraintFunction = f.m_iConstraintFunction;
return *this;
}
///Destructor
CompositeFunction::~CompositeFunction()
{
if (m_functions[i]) delete m_functions[i];
}
/// Function initialization. Declare function parameters in this method.
void CompositeFunction::init()
{
}
Roman Tolchenov
committed
/**
* Writes itself into a string. Functions derived from CompositeFunction must
* override this method with something like this:
* std::string NewFunction::asString()const
* {
* ostr << "composite=" << this->name() << ';';
* // write NewFunction's own attributes and parameters
* ostr << CompositeFunction::asString();
* // write NewFunction's own ties and constraints
* // ostr << ";constraints=(" << ... <<")";
* }
* @return the string representation of the composite function
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
std::string CompositeFunction::asString()const
{
std::ostringstream ostr;
if (name() != "CompositeFunctionMW")
{
ostr << "composite=" <<name() << ";";
}
Roman Tolchenov
committed
{
IFitFunction* fun = getFunction(i);
Roman Tolchenov
committed
bool isComp = dynamic_cast<CompositeFunction*>(fun) != 0;
if (isComp) ostr << '(';
Roman Tolchenov
committed
ostr << fun->asString();
Roman Tolchenov
committed
if (isComp) ostr << ')';
Roman Tolchenov
committed
if (i < nFunctions() - 1)
{
ostr << ';';
}
}
std::string ties;
Roman Tolchenov
committed
for(size_t i=0;i<nParams();i++)
Roman Tolchenov
committed
{
const ParameterTie* tie = getTie(i);
if (tie)
{
IFitFunction* fun = getFunction(functionIndex(i));
Roman Tolchenov
committed
std::string tmp = tie->asString(fun);
if (tmp.empty())
{
tmp = tie->asString(this);
if (!tmp.empty())
{
if (!ties.empty())
{
ties += ",";
}
ties += tmp;
}
}
}
}
if (!ties.empty())
{
ostr << ";ties=(" << ties << ")";
Roman Tolchenov
committed
}
return ostr.str();
}
/** Sets a new value to the i-th parameter.
Janik Zikovsky
committed
* @param i :: The parameter index
* @param value :: The new value
* @param explicitlySet :: A boolean falgging the parameter as explicitly set (by user)
Roman Tolchenov
committed
void CompositeFunction::setParameter(size_t i, const double& value, bool explicitlySet)
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
m_functions[ iFun ]->setParameter(i - m_paramOffsets[iFun],value,explicitlySet);
Anders Markvardsen
committed
/** Sets a new description to the i-th parameter.
* @param i :: The parameter index
* @param description :: The new description
*/
void CompositeFunction::setParameterDescription(size_t i, const std::string& description)
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Anders Markvardsen
committed
m_functions[ iFun ]->setParameterDescription(i - m_paramOffsets[iFun],description);
}
/** Get the i-th parameter.
Janik Zikovsky
committed
* @param i :: The parameter index
* @return value of the requested parameter
Roman Tolchenov
committed
double CompositeFunction::getParameter(size_t i)const
return m_functions[ iFun ]->getParameter(i - m_paramOffsets[iFun]);
/**
* Sets a new value to a parameter by name.
Janik Zikovsky
committed
* @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)
Peterson, Peter
committed
std::string pname;
Roman Tolchenov
committed
size_t index;
Peterson, Peter
committed
parseName(name,index,pname);
Roman Tolchenov
committed
getFunction(index)->setParameter(pname,value,explicitlySet);
Anders Markvardsen
committed
/**
* Sets a new description to a parameter by name.
* @param name :: The name of the parameter.
* @param value :: The new description
*/
void CompositeFunction::setParameterDescription(const std::string& name, const std::string& description)
{
std::string pname;
Roman Tolchenov
committed
size_t index;
Anders Markvardsen
committed
parseName(name,index,pname);
Roman Tolchenov
committed
getFunction(index)->setParameterDescription(pname,description);
Anders Markvardsen
committed
}
/**
* Parameters by name.
Janik Zikovsky
committed
* @param name :: The name of the parameter.
* @return value of the requested named parameter
double CompositeFunction::getParameter(const std::string& name)const
{
Peterson, Peter
committed
std::string pname;
Roman Tolchenov
committed
size_t index;
Peterson, Peter
committed
parseName(name,index,pname);
Roman Tolchenov
committed
return getFunction(index)->getParameter(pname);
}
/// Total number of parameters
Roman Tolchenov
committed
size_t CompositeFunction::nParams()const
Janik Zikovsky
committed
* @param name :: The name of a parameter
* @return index of the requested named parameter
Roman Tolchenov
committed
size_t CompositeFunction::parameterIndex(const std::string& name)const
Peterson, Peter
committed
std::string pname;
Roman Tolchenov
committed
size_t index;
Peterson, Peter
committed
parseName(name,index,pname);
Russell Taylor
committed
return getFunction(index)->parameterIndex(pname) + m_paramOffsets[index];
Janik Zikovsky
committed
/// @param i :: The index
Roman Tolchenov
committed
std::string CompositeFunction::parameterName(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
std::ostringstream ostr;
ostr << 'f' << iFun << '.' << m_functions[ iFun ]->parameterName(i - m_paramOffsets[iFun]);
return ostr.str();
Anders Markvardsen
committed
/// Returns the description of parameter
/// @param i :: The index
/// @return The description of the parameter
std::string CompositeFunction::parameterDescription(size_t i)const
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Anders Markvardsen
committed
std::ostringstream ostr;
ostr << m_functions[ iFun ]->parameterDescription(i - m_paramOffsets[iFun]);
return ostr.str();
}
/// Number of active (in terms of fitting) parameters
Roman Tolchenov
committed
size_t CompositeFunction::nActive()const
{
return m_nActive;
}
/// Value of i-th active parameter. Override this method to make fitted parameters different from the declared
Roman Tolchenov
committed
double CompositeFunction::activeParameter(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndexActive(i);
return m_functions[ iFun ]->activeParameter(i - m_activeOffsets[iFun]);
}
/// Set new value of i-th active parameter. Override this method to make fitted parameters different from the declared
Roman Tolchenov
committed
void CompositeFunction::setActiveParameter(size_t i, double value)
Roman Tolchenov
committed
size_t iFun = functionIndexActive(i);
m_functions[ iFun ]->setActiveParameter(i - m_activeOffsets[iFun],value);
}
/// Update parameters after a fitting iteration
void CompositeFunction::updateActive(const double* in)
{
for(size_t iFun = 0; iFun < m_functions.size(); iFun++)
{
m_functions[ iFun ]->updateActive(in + m_activeOffsets[ iFun ]);
}
}
/// Returns "global" index of active parameter i
Roman Tolchenov
committed
size_t CompositeFunction::indexOfActive(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndexActive(i);
return m_paramOffsets[ iFun ] + m_functions[ iFun ]->indexOfActive(i - m_activeOffsets[iFun]);
}
/// Returns the name of active parameter i
Roman Tolchenov
committed
std::string CompositeFunction::nameOfActive(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndexActive(i);
std::ostringstream ostr;
ostr << 'f' << iFun << '.' << m_functions[ iFun ]->nameOfActive(i - m_activeOffsets[iFun]);
Anders Markvardsen
committed
return ostr.str();
}
/// Returns the description of active parameter i
std::string CompositeFunction::descriptionOfActive(size_t i)const
{
Roman Tolchenov
committed
size_t iFun = functionIndexActive(i);
Anders Markvardsen
committed
std::ostringstream ostr;
ostr << m_functions[ iFun ]->descriptionOfActive(i - m_activeOffsets[iFun]);
return ostr.str();
* query to see in the function is active
Janik Zikovsky
committed
* @param i :: The index of a declared parameter
* @return true if parameter i is active
Roman Tolchenov
committed
bool CompositeFunction::isActive(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->isActive(i - m_paramOffsets[iFun]);
}
/**
Janik Zikovsky
committed
* @param i :: A declared parameter index to be removed from active
Roman Tolchenov
committed
void CompositeFunction::removeActive(size_t i)
Roman Tolchenov
committed
if (!isActive(i)) return;
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
size_t ia = m_activeOffsets[iFun] + m_functions[iFun]->activeIndex(i - m_paramOffsets[iFun]);
m_IFitFunctionActive.erase(m_IFitFunctionActive.begin()+ia);
m_functions[ iFun ]->removeActive(i - m_paramOffsets[iFun]);
Roman Tolchenov
committed
m_nActive--;
Roman Tolchenov
committed
/** Makes a parameter active again. It doesn't change the parameter's tie.
Janik Zikovsky
committed
* @param i :: A declared parameter index to be restored to active
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
void CompositeFunction::restoreActive(size_t i)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
size_t ia = m_activeOffsets[iFun] + m_functions[iFun]->activeIndex(i - m_paramOffsets[iFun]);
Roman Tolchenov
committed
Roman Tolchenov
committed
std::vector<size_t>::iterator itFun =
std::find_if(m_IFitFunctionActive.begin(),m_IFitFunctionActive.end(),std::bind2nd(std::greater<size_t>(),i));
Roman Tolchenov
committed
m_IFitFunctionActive.insert(itFun,1,ia);
Roman Tolchenov
committed
m_functions[ iFun ]->restoreActive(i - m_paramOffsets[iFun]);
m_nActive++;
Roman Tolchenov
committed
m_activeOffsets[j] += 1;
}
Janik Zikovsky
committed
* @param i :: The index of a declared parameter
Roman Tolchenov
committed
* @return The index of declared parameter i in the list of active parameters
Roman Tolchenov
committed
size_t CompositeFunction::activeIndex(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
size_t j = m_functions[iFun]->activeIndex(i - m_paramOffsets[iFun]);
Roman Tolchenov
committed
return m_activeOffsets[iFun] + j;
/** Makes sure that the function is consistent.
*/
void CompositeFunction::checkFunction()
{
m_nParams = 0;
m_nActive = 0;
m_paramOffsets.clear();
m_activeOffsets.clear();
m_IFitFunction.clear();
m_IFitFunctionActive.clear();
std::vector<IFitFunction*> functions(m_functions.begin(),m_functions.end());
for(std::vector<IFitFunction*>::size_type i=0;i<functions.size();i++)
IFitFunction* f = functions[i];
CompositeFunction* cf = dynamic_cast<CompositeFunction*>(f);
if (cf) cf->checkFunction();
Janik Zikovsky
committed
* @param f :: A pointer to the added function
* @return The function index
Roman Tolchenov
committed
size_t CompositeFunction::addFunction(IFitFunction* f)
Roman Tolchenov
committed
m_IFitFunction.insert(m_IFitFunction.end(),f->nParams(), m_functions.size());
m_IFitFunctionActive.insert(m_IFitFunctionActive.end(),f->nActive(),m_functions.size());
m_functions.push_back(f);
//?f->init();
if (m_paramOffsets.size() == 0)
{
m_paramOffsets.push_back(0);
m_activeOffsets.push_back(0);
m_nParams = f->nParams();
m_nActive = f->nActive();
}
else
{
m_paramOffsets.push_back(m_nParams);
m_activeOffsets.push_back(m_nActive);
m_nParams += f->nParams();
m_nActive += f->nActive();
}
Roman Tolchenov
committed
return m_functions.size() - 1;
Roman Tolchenov
committed
/** Remove a function
Janik Zikovsky
committed
* @param i :: The index of the function to remove
* @param del :: The deletion flag. If true the function will be deleted otherwise - simply detached
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
void CompositeFunction::removeFunction(size_t i, bool del)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if ( i >= nFunctions() )
Roman Tolchenov
committed
throw std::out_of_range("Function index out of range.");
IFitFunction* fun = getFunction(i);
Roman Tolchenov
committed
Roman Tolchenov
committed
size_t dna = fun->nActive();
size_t dnp = fun->nParams();
Roman Tolchenov
committed
Roman Tolchenov
committed
for(size_t j=0;j<nParams();)
Roman Tolchenov
committed
{
ParameterTie* tie = getTie(j);
Roman Tolchenov
committed
if (tie && tie->findParametersOf(fun))
Roman Tolchenov
committed
{
removeTie(j);
}
else
{
j++;
}
}
// Shift down the function indeces for parameters
Roman Tolchenov
committed
for(std::vector<size_t>::iterator it=m_IFitFunction.begin();it!=m_IFitFunction.end();)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
Roman Tolchenov
committed
if (*it == i)
{
it = m_IFitFunction.erase(it);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
else
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if (*it > i)
{
*it -= 1;
}
it++;
Roman Tolchenov
committed
}
}
// Shift down the function indeces for active parameters
Roman Tolchenov
committed
for(std::vector<size_t>::iterator it=m_IFitFunctionActive.begin();it!=m_IFitFunctionActive.end();)
Roman Tolchenov
committed
{
if (*it == i)
{
it = m_IFitFunctionActive.erase(it);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
else
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if (*it > i)
{
*it -= 1;
}
it++;
Roman Tolchenov
committed
}
}
m_nActive -= dna;
// Shift the active offsets down by the number of i-th function's active params
Roman Tolchenov
committed
for(size_t j=i+1;j<nFunctions();j++)
Roman Tolchenov
committed
{
m_activeOffsets[j] -= dna;
}
m_activeOffsets.erase(m_activeOffsets.begin()+i);
m_nParams -= dnp;
// Shift the parameter offsets down by the total number of i-th function's params
Roman Tolchenov
committed
for(size_t j=i+1;j<nFunctions();j++)
Roman Tolchenov
committed
{
m_paramOffsets[j] -= dnp;
}
m_paramOffsets.erase(m_paramOffsets.begin()+i);
m_functions.erase(m_functions.begin()+i);
Roman Tolchenov
committed
if (del)
{
delete fun;
}
Roman Tolchenov
committed
}
Roman Tolchenov
committed
/** Replace a function with a new one. The old function is deleted.
* The new function must have already its workspace set.
Janik Zikovsky
committed
* @param f_old :: The pointer to the function to replace. If it's not
Roman Tolchenov
committed
* a member of this composite function nothing happens
Janik Zikovsky
committed
* @param f_new :: A pointer to the new function
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
void CompositeFunction::replaceFunctionPtr(const IFitFunction* f_old,IFitFunction* f_new)
Roman Tolchenov
committed
{
std::vector<IFitFunction*>::const_iterator it =
Roman Tolchenov
committed
std::find(m_functions.begin(),m_functions.end(),f_old);
if (it == m_functions.end()) return;
std::vector<IFitFunction*>::difference_type iFun = it - m_functions.begin();
Roman Tolchenov
committed
replaceFunction(iFun,f_new);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
/** Replace a function with a new one. The old function is deleted.
Janik Zikovsky
committed
* @param i :: The index of the function to replace
* @param f :: A pointer to the new function
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
void CompositeFunction::replaceFunction(size_t i,IFitFunction* f)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if ( i >= nFunctions() )
Roman Tolchenov
committed
throw std::out_of_range("Function index out of range.");
IFitFunction* fun = getFunction(i);
Roman Tolchenov
committed
size_t na_old = fun->nActive();
size_t np_old = fun->nParams();
Roman Tolchenov
committed
Roman Tolchenov
committed
size_t na_new = f->nActive();
size_t np_new = f->nParams();
Roman Tolchenov
committed
// Modify function indeces: The new function may have different number of parameters
{
Roman Tolchenov
committed
std::vector<size_t>::iterator itFun = std::find(m_IFitFunction.begin(),m_IFitFunction.end(),i);
if(itFun != m_IFitFunction.end()) // functions must have at least 1 parameter
Roman Tolchenov
committed
{
if (np_old > np_new)
{
m_IFitFunction.erase(itFun,itFun + np_old - np_new);
}
else if (np_old < np_new)
{
m_IFitFunction.insert(itFun,np_new - np_old,i);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
else if (np_new > 0) // it could happen if the old function is an empty CompositeFunction
{
Roman Tolchenov
committed
itFun = std::find_if(m_IFitFunction.begin(),m_IFitFunction.end(),std::bind2nd(std::greater<size_t>(),i));
m_IFitFunction.insert(itFun,np_new,i);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
}
// Modify function indeces: The new function may have different number of active parameters
{
Roman Tolchenov
committed
std::vector<size_t>::iterator itFun = std::find(m_IFitFunctionActive.begin(),m_IFitFunctionActive.end(),i);
if (itFun != m_IFitFunctionActive.end())
Roman Tolchenov
committed
{
if (na_old > na_new)
{
m_IFitFunctionActive.erase(itFun,itFun + na_old - na_new);
Roman Tolchenov
committed
}
else if (na_old < na_new)
{
m_IFitFunctionActive.insert(itFun,na_new - na_old,i);
Roman Tolchenov
committed
}
}
else if (na_new > 0)
{
Roman Tolchenov
committed
itFun = std::find_if(m_IFitFunctionActive.begin(),m_IFitFunctionActive.end(),std::bind2nd(std::greater<size_t>(),i));
m_IFitFunctionActive.insert(itFun,na_new,i);
Roman Tolchenov
committed
}
}
Roman Tolchenov
committed
size_t dna = na_new - na_old;
Roman Tolchenov
committed
m_nActive += dna;
// Recalc the active offsets
Roman Tolchenov
committed
for(size_t j=i+1;j<nFunctions();j++)
Roman Tolchenov
committed
{
m_activeOffsets[j] += dna;
}
Roman Tolchenov
committed
size_t dnp = np_new - np_old;
Roman Tolchenov
committed
m_nParams += dnp;
// Shift the parameter offsets down by the total number of i-th function's params
Roman Tolchenov
committed
for(size_t j=i+1;j<nFunctions();j++)
Roman Tolchenov
committed
{
m_paramOffsets[j] += dnp;
}
m_functions[i] = f;
delete fun;
}
Janik Zikovsky
committed
* @param i :: The index of the function
* @return function at the requested index
IFitFunction* CompositeFunction::getFunction(size_t i)const
Roman Tolchenov
committed
{
throw std::out_of_range("Function index out of range.");
Roman Tolchenov
committed
}
/**
* Get the index of the function to which parameter i belongs
Janik Zikovsky
committed
* @param i :: The parameter index
* @return function index of the requested parameter
Roman Tolchenov
committed
if( i >= nParams() )
Roman Tolchenov
committed
{
throw std::out_of_range("Function parameter index out of range.");
Roman Tolchenov
committed
}
return m_IFitFunction[i];
}
/**
* Get the index of the function to which parameter i belongs
Janik Zikovsky
committed
* @param i :: The active parameter index
* @return active function index of the requested parameter
size_t CompositeFunction::functionIndexActive(size_t i)const
Roman Tolchenov
committed
if( i >= nParams() )
throw std::out_of_range("Function parameter index out of range.");
return m_IFitFunctionActive[i];
Janik Zikovsky
committed
* @param varName :: The variable name which may contain function index ( [f<index.>]name )
Roman Tolchenov
committed
* @param index :: Receives function index or throws std::invalid_argument
Janik Zikovsky
committed
* @param name :: Receives the parameter name
Roman Tolchenov
committed
void CompositeFunction::parseName(const std::string& varName,size_t& index, std::string& name)
Peterson, Peter
committed
size_t i = varName.find('.');
if (i == std::string::npos)
{
Roman Tolchenov
committed
throw std::invalid_argument("Parameter " + varName + " not found.");
Peterson, Peter
committed
}
else
{
if (varName[0] != 'f')
throw std::invalid_argument("External function parameter name must start with 'f'");
Roman Tolchenov
committed
std::string sindex = varName.substr(1,i - 1);
Peterson, Peter
committed
index = boost::lexical_cast<int>(sindex);
if (i == varName.size() - 1)
throw std::invalid_argument("Name cannot be empty");
name = varName.substr(i+1);
}
Roman Tolchenov
committed
/** Returns the index of parameter i as it declared in its function
Janik Zikovsky
committed
* @param i :: The parameter index
Roman Tolchenov
committed
* @return The local index of the parameter
*/
Roman Tolchenov
committed
size_t CompositeFunction::parameterLocalIndex(size_t i)const
Roman Tolchenov
committed
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Roman Tolchenov
committed
return i - m_paramOffsets[iFun];
}
/** Returns the name of parameter i as it declared in its function
Janik Zikovsky
committed
* @param i :: The parameter index
* @return The pure parameter name (without the function identifier f#.)
*/
Roman Tolchenov
committed
std::string CompositeFunction::parameterLocalName(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->parameterName(i - m_paramOffsets[iFun]);
}
Roman Tolchenov
committed
/**
Roman Tolchenov
committed
* Apply the ties.
Roman Tolchenov
committed
*/
void CompositeFunction::applyTies()
{
Roman Tolchenov
committed
{
getFunction(i)->applyTies();
}
}
/**
* Clear the ties.
*/
void CompositeFunction::clearTies()
{
Roman Tolchenov
committed
{
getFunction(i)->clearTies();
}
}
/** Removes i-th parameter's tie if it is tied or does nothing.
Janik Zikovsky
committed
* @param i :: The index of the tied parameter.
Roman Tolchenov
committed
* @return True if successfull
*/
Roman Tolchenov
committed
bool CompositeFunction::removeTie(size_t i)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Roman Tolchenov
committed
bool res = m_functions[ iFun ]->removeTie(i - m_paramOffsets[iFun]);
if (res)
{
m_nActive++;
}
return res;
}
/** Get the tie of i-th parameter
Janik Zikovsky
committed
* @param i :: The parameter index
* @return A pointer to the tie.
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
ParameterTie* CompositeFunction::getTie(size_t i)const
Roman Tolchenov
committed
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Roman Tolchenov
committed
return m_functions[ iFun ]->getTie(i - m_paramOffsets[iFun]);
}
/**
* Attaches a tie to this function. The attached tie is owned by the function.
Janik Zikovsky
committed
* @param tie :: A pointer to a new tie
Roman Tolchenov
committed
*/
void CompositeFunction::addTie(ParameterTie* tie)
{
Roman Tolchenov
committed
size_t i = getParameterIndex(*tie);
size_t iFun = functionIndex(i);
Roman Tolchenov
committed
m_functions[iFun]->addTie(tie);
}
/**
* Declare a new parameter. To used in the implementation'c constructor.
Janik Zikovsky
committed
* @param name :: The parameter name.
* @param initValue :: The initial value for the parameter
Roman Tolchenov
committed
*/
void CompositeFunction::declareParameter(const std::string& name, double initValue, const std::string& description)
Roman Tolchenov
committed
{
(void) name; //Avoid compiler warning
(void) initValue; //Avoid compiler warning
(void) description; //Avoid compiler warning
Roman Tolchenov
committed
throw Kernel::Exception::NotImplementedError("CompositeFunction cannot not have its own parameters.");
}
/** Add a constraint
Janik Zikovsky
committed
* @param ic :: Pointer to a constraint.
Roman Tolchenov
committed
*/
void CompositeFunction::addConstraint(IConstraint* ic)
{
Roman Tolchenov
committed
size_t i = getParameterIndex(*ic);
size_t iFun = functionIndex(i);
getFunction(iFun)->addConstraint(ic);
Roman Tolchenov
committed
}
Anders Markvardsen
committed
void CompositeFunction::setParametersToSatisfyConstraints()
{
Anders Markvardsen
committed
{
getFunction(i)->setParametersToSatisfyConstraints();
}
}
Janik Zikovsky
committed
/// @param i :: the index
Roman Tolchenov
committed
IConstraint* CompositeFunction::getConstraint(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->getConstraint(i - m_paramOffsets[iFun]);
/** Remove a constraint
Janik Zikovsky
committed
* @param parName :: The name of a parameter which constarint to remove.
*/
void CompositeFunction::removeConstraint(const std::string& parName)
{
Roman Tolchenov
committed
size_t iPar = parameterIndex(parName);
size_t iFun = functionIndex(iPar);
getFunction(iFun)->removeConstraint(parameterLocalName(iPar));
}
/** Checks if a constraint has been explicitly set
Janik Zikovsky
committed
* @param i :: The parameter index
* @return true if the function is explicitly set
Roman Tolchenov
committed
bool CompositeFunction::isExplicitlySet(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->isExplicitlySet(i - m_paramOffsets[iFun]);
}
Roman Tolchenov
committed
* Returns the index of parameter if the ref points to one of the member function
Janik Zikovsky
committed
* @param ref :: A reference to a parameter
Roman Tolchenov
committed
* @return Parameter index or number of nParams() if parameter not found
Roman Tolchenov
committed
size_t CompositeFunction::getParameterIndex(const ParameterReference& ref)const
Roman Tolchenov
committed
if (ref.getFunction() == this && ref.getIndex() < nParams())
Roman Tolchenov
committed
return ref.getIndex();
Roman Tolchenov
committed
{
Roman Tolchenov
committed
IFitFunction* fun = getFunction(iFun);
size_t iLocalIndex = fun->getParameterIndex(ref);
if (iLocalIndex < fun->nParams())
Roman Tolchenov
committed
{
return m_paramOffsets[iFun] + iLocalIndex;
}
}
Roman Tolchenov
committed
return nParams();
Janik Zikovsky
committed
* @param ref :: The reference
* @return A function containing parameter pointed to by ref
*/
IFitFunction* CompositeFunction::getContainingFunction(const ParameterReference& ref)const
Roman Tolchenov
committed
if (ref.getFunction() == this && ref.getIndex() < nParams())
{
return ref.getFunction();
}
Roman Tolchenov
committed
IFitFunction* fun = getFunction(iFun)->getContainingFunction(ref);
if (fun)
{
return getFunction(iFun);
}
}
return NULL;
}
Janik Zikovsky
committed
* @param fun :: The searched function
* @return A function containing the argument function fun
*/
IFitFunction* CompositeFunction::getContainingFunction(const IFitFunction* fun)
{
if (fun == this)
{
return this;
}
Roman Tolchenov
committed
IFitFunction* f = getFunction(iFun)->getContainingFunction(fun);
if (f)
{
return getFunction(iFun);
}
}
return NULL;
}
} // namespace API
} // namespace Mantid