Newer
Older
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/Exception.h"
Roman Tolchenov
committed
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/ParameterTie.h"
#include "MantidAPI/IConstraint.h"
#include "MantidAPI/FunctionFactory.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)
///Destructor
CompositeFunction::~CompositeFunction()
{
}
/// 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 empty just return function name
if (nFunctions() == 0)
{
return "name=" + name();
}
if (name() != "CompositeFunction")
{
ostr << "composite=" <<name() << ";";
}
Roman Tolchenov
committed
{
IFunction_sptr fun = getFunction(i);
bool isComp = boost::dynamic_pointer_cast<CompositeFunction>(fun) != 0;
Roman Tolchenov
committed
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)
{
IFunction_sptr fun = getFunction(functionIndex(i));
std::string tmp = tie->asString(fun.get());
Roman Tolchenov
committed
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();
}
/** Function you want to fit to.
* @param domain :: The buffer for writing the calculated values. Must be big enough to accept dataSize() values
*/
void CompositeFunction::function(const FunctionDomain& domain, FunctionValues& values)const
{
FunctionValues tmp(domain);
for(size_t iFun = 0; iFun < nFunctions(); ++iFun)
{
m_functions[ iFun ]->function(domain,tmp);
values += tmp;
}
}
/**
* Derivatives of function with respect to active parameters
* @param domain :: Function domain to get the arguments from.
* @param jacobian :: A Jacobian to store the derivatives.
*/
void CompositeFunction::functionDeriv(const FunctionDomain& domain, Jacobian& jacobian)
{
if ( m_useNumericDerivatives )
{
calNumericalDeriv(domain, jacobian);
}
else
for(size_t iFun = 0; iFun < nFunctions(); ++iFun)
{
PartialJacobian J(&jacobian,paramOffset(iFun));
getFunction(iFun)->functionDeriv(domain,J);
}
}
}
/** 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 description :: The new description
Anders Markvardsen
committed
*/
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();
}
/**
* Get the fitting error for a parameter
* @param i :: The index of a parameter
* @return :: the error
*/
double CompositeFunction::getError(size_t i) const
{
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->getError(i - m_paramOffsets[iFun]);
}
/**
* Set the fitting error for a parameter
* @param i :: The index of a parameter
* @param err :: The error value to set
*/
void CompositeFunction::setError(size_t i, double err)
{
size_t iFun = functionIndex(i);
m_functions[ iFun ]->setError(i - m_paramOffsets[iFun], err);
}
/// 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
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->activeParameter(i - m_paramOffsets[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)
size_t iFun = functionIndex(i);
m_functions[ iFun ]->setActiveParameter(i - m_paramOffsets[iFun],value);
}
/// Returns the name of active parameter i
Roman Tolchenov
committed
std::string CompositeFunction::nameOfActive(size_t i)const
size_t iFun = functionIndex(i);
std::ostringstream ostr;
ostr << 'f' << iFun << '.' << m_functions[ iFun ]->nameOfActive(i - m_paramOffsets[iFun]);
Anders Markvardsen
committed
return ostr.str();
}
/// Returns the description of active parameter i
std::string CompositeFunction::descriptionOfActive(size_t i)const
{
size_t iFun = functionIndex(i);
Anders Markvardsen
committed
std::ostringstream ostr;
ostr << m_functions[ iFun ]->descriptionOfActive(i - m_paramOffsets[iFun]);
return ostr.str();
/**
* query to see in the function is active
* @param i :: The index of a declared parameter
* @return true if parameter i is active
*/
bool CompositeFunction::isActive(size_t i)const
{
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->isActive(i - m_paramOffsets[iFun]);
}
* 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
bool CompositeFunction::isFixed(size_t i)const
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->isFixed(i - m_paramOffsets[iFun]);
Janik Zikovsky
committed
* @param i :: A declared parameter index to be removed from active
void CompositeFunction::fix(size_t i)
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
//std::vector<size_t>::iterator ia = std::find(m_IFunctionActive.begin(),m_IFunctionActive.end(),iFun);
//if (ia == m_IFunctionActive.end())
//{// isFixed(i) should have returned true
// throw std::runtime_error("Inconsistency in CompositeFunction when fixing parameter "+
// boost::lexical_cast<std::string>(i));
//}
//m_IFunctionActive.erase(ia);
m_functions[ iFun ]->fix(i - m_paramOffsets[iFun]);
//m_nActive--;
//for(size_t j=iFun+1;j<nFunctions();j++)
// m_activeOffsets[j] -= 1;
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
*/
void CompositeFunction::unfix(size_t i)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
size_t iFun = functionIndex(i);
Roman Tolchenov
committed
//m_IFunctionActive.insert(m_IFunctionActive.begin() + m_activeOffsets[iFun],iFun);
m_functions[ iFun ]->unfix(i - m_paramOffsets[iFun]);
Roman Tolchenov
committed
//m_nActive++;
//for(size_t j=iFun+1;j<nFunctions();j++)
// m_activeOffsets[j] += 1;
Roman Tolchenov
committed
}
/** Makes sure that the function is consistent.
*/
void CompositeFunction::checkFunction()
{
m_nParams = 0;
//m_nActive = 0;
//m_activeOffsets.clear();
m_IFunction.clear();
//m_IFunctionActive.clear();
std::vector<IFunction_sptr> functions(m_functions.begin(),m_functions.end());
for(std::vector<IFunction_sptr>::size_type i=0;i<functions.size();i++)
IFunction_sptr f = functions[i];
CompositeFunction_sptr cf = boost::dynamic_pointer_cast<CompositeFunction>(f);
if (cf) cf->checkFunction();
Janik Zikovsky
committed
* @param f :: A pointer to the added function
* @return The function index
size_t CompositeFunction::addFunction(IFunction_sptr f)
m_IFunction.insert(m_IFunction.end(),f->nParams(), m_functions.size());
//m_IFunctionActive.insert(m_IFunctionActive.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_nActive = f->nActive();
}
else
{
m_paramOffsets.push_back(m_nParams);
//m_activeOffsets.push_back(m_nActive);
//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
*/
void CompositeFunction::removeFunction(size_t i)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if ( i >= nFunctions() )
Roman Tolchenov
committed
throw std::out_of_range("Function index out of range.");
IFunction_sptr fun = getFunction(i);
Roman Tolchenov
committed
//size_t dna = fun->nActive();
Roman Tolchenov
committed
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);
if (tie && tie->findParametersOf(fun.get()))
Roman Tolchenov
committed
{
removeTie(j);
}
else
{
j++;
}
}
// Shift down the function indeces for parameters
for(std::vector<size_t>::iterator it=m_IFunction.begin();it!=m_IFunction.end();)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
Roman Tolchenov
committed
if (*it == i)
{
it = m_IFunction.erase(it);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
else
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if (*it > i)
{
*it -= 1;
}
Roman Tolchenov
committed
}
}
// Shift down the function indeces for active parameters
//for(std::vector<size_t>::iterator it=m_IFunctionActive.begin();it!=m_IFunctionActive.end();)
//{
// if (*it == i)
// {
// it = m_IFunctionActive.erase(it);
// }
// else
// {
// if (*it > i)
// {
// *it -= 1;
// }
// ++it;
// }
//}
//m_nActive -= dna;
//// Shift the active offsets down by the number of i-th function's active params
//for(size_t j=i+1;j<nFunctions();j++)
//{
// m_activeOffsets[j] -= dna;
//}
//m_activeOffsets.erase(m_activeOffsets.begin()+i);
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_paramOffsets.erase(m_paramOffsets.begin()+i);
m_functions.erase(m_functions.begin()+i);
}
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
*/
void CompositeFunction::replaceFunctionPtr(const IFunction_sptr f_old,IFunction_sptr f_new)
Roman Tolchenov
committed
{
std::vector<IFunction_sptr>::const_iterator it =
Roman Tolchenov
committed
std::find(m_functions.begin(),m_functions.end(),f_old);
if (it == m_functions.end()) return;
std::vector<IFunction_sptr>::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
*/
void CompositeFunction::replaceFunction(size_t i,IFunction_sptr f)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
if ( i >= nFunctions() )
Roman Tolchenov
committed
throw std::out_of_range("Function index out of range.");
IFunction_sptr fun = getFunction(i);
//size_t na_old = fun->nActive();
Roman Tolchenov
committed
size_t np_old = fun->nParams();
Roman Tolchenov
committed
//size_t na_new = f->nActive();
Roman Tolchenov
committed
size_t np_new = f->nParams();
Roman Tolchenov
committed
// Modify function indeces: The new function may have different number of parameters
{
std::vector<size_t>::iterator itFun = std::find(m_IFunction.begin(),m_IFunction.end(),i);
if(itFun != m_IFunction.end()) // functions must have at least 1 parameter
Roman Tolchenov
committed
{
if (np_old > np_new)
{
m_IFunction.erase(itFun,itFun + np_old - np_new);
}
else if (np_old < np_new)
{
m_IFunction.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
{
itFun = std::find_if(m_IFunction.begin(),m_IFunction.end(),std::bind2nd(std::greater<size_t>(),i));
m_IFunction.insert(itFun,np_new,i);
Roman Tolchenov
committed
}
Roman Tolchenov
committed
}
// Modify function indeces: The new function may have different number of active parameters
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
//{
// std::vector<size_t>::iterator itFun = std::find(m_IFunctionActive.begin(),m_IFunctionActive.end(),i);
// if (itFun != m_IFunctionActive.end())
// {
// if (na_old > na_new)
// {
// m_IFunctionActive.erase(itFun,itFun + na_old - na_new);
// }
// else if (na_old < na_new)
// {
// m_IFunctionActive.insert(itFun,na_new - na_old,i);
// }
// }
// else if (na_new > 0)
// {
// itFun = std::find_if(m_IFunctionActive.begin(),m_IFunctionActive.end(),std::bind2nd(std::greater<size_t>(),i));
// m_IFunctionActive.insert(itFun,na_new,i);
// }
//}
//size_t dna = na_new - na_old;
//m_nActive += dna;
//// Recalc the active offsets
//for(size_t j=i+1;j<nFunctions();j++)
//{
// m_activeOffsets[j] += dna;
//}
Roman Tolchenov
committed
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;
}
Janik Zikovsky
committed
* @param i :: The index of the function
* @return function at the requested index
IFunction_sptr CompositeFunction::getFunction(std::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
size_t CompositeFunction::functionIndex(std::size_t i)const
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_IFunction[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++;
//}
Roman Tolchenov
committed
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
* @param description :: Parameter documentation
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
{
IFunction_sptr fun = getFunction(iFun);
Roman Tolchenov
committed
size_t iLocalIndex = fun->getParameterIndex(ref);
if (iLocalIndex < fun->nParams())
Roman Tolchenov
committed
{
return m_paramOffsets[iFun] + iLocalIndex;
}
}
Roman Tolchenov
committed
return nParams();
* Returns the shrared pointer to the function conataining a parameter
Janik Zikovsky
committed
* @param ref :: The reference
* @return A function containing parameter pointed to by ref
*/
IFunction_sptr CompositeFunction::getContainingFunction(const ParameterReference& ref)const
IFunction_sptr fun = getFunction(iFun);
if (fun->getParameterIndex(ref) < fun->nParams())
return fun;
}
}
return IFunction_sptr();
}
/**
* Enable/disable numeric derivative calculation.
* @param yes :: Set to true to use numeric derivative calculation.
*/
void CompositeFunction::useNumericDerivatives( bool yes ) const
{
m_useNumericDerivatives = yes;
}
} // namespace API
} // namespace Mantid