21#include <boost/lexical_cast.hpp>
30 Mantid::Kernel::LibraryManager::Instance();
62 std::map<std::string, std::string> parentAttributes;
63 if (e.name() ==
";") {
86std::shared_ptr<MultiDomainFunction>
89 auto multiDomainFunction = std::make_shared<MultiDomainFunction>();
91 if (!singleFunction) {
92 return multiDomainFunction;
95 for (
size_t i = 0; i < domainNumber; ++i) {
96 multiDomainFunction->addFunction(singleFunction->clone());
97 multiDomainFunction->setDomainIndex(i, i);
100 return multiDomainFunction;
111 std::map<std::string, std::string> &parentAttributes)
const {
112 if (expr.
name() ==
"=" && expr.
size() > 1) {
116 if (expr.
name() !=
"," || expr.
size() == 0) {
120 const std::vector<Expression> &terms = expr.
terms();
121 auto term = terms.cbegin();
123 if (term->name() !=
"=")
125 if (term->terms()[0].name() !=
"name" && term->terms()[0].name() !=
"composite") {
126 throw std::invalid_argument(
"Function name must be defined before its parameters");
128 std::string fnName = term->terms()[1].name();
131 for (++term; term != terms.end(); ++term) {
132 if (term->name() !=
"=")
134 std::string parName = term->terms()[0].name();
135 std::string parValue = term->terms()[1].str();
136 if (fun->hasAttribute(parName)) {
138 if (parValue.size() > 1 && parValue[0] ==
'"') {
140 parValue = parValue.substr(1, parValue.size() - 2);
144 fun->setAttribute(parName, att);
145 }
else if (parName.size() >= 10 && parName.substr(0, 10) ==
"constraint") {
148 }
else if (parName ==
"ties") {
149 addTies(fun, (*term)[1].bracketsRemoved());
150 }
else if (!parName.empty() && parName[0] ==
'$') {
152 parentAttributes[parName] = parValue;
156 fun->setParameter(parName, boost::lexical_cast<double>(parValue));
157 }
catch (boost::bad_lexical_cast &) {
158 throw std::runtime_error(std::string(
"Error in value of parameter ")
162 .append(
" cannot be interpreted as a floating point value."));
180 std::map<std::string, std::string> &parentAttributes)
const {
181 if (expr.
name() !=
";")
184 if (expr.
size() == 0) {
188 const std::vector<Expression> &terms = expr.
terms();
189 auto it = terms.cbegin();
193 if (term.
name() ==
"=") {
194 if (term.
terms()[0].name() ==
"composite") {
195 cfun = std::dynamic_pointer_cast<CompositeFunction>(
createFunction(term.
terms()[1].name()));
199 }
else if (term.
terms()[0].name() ==
"name") {
200 cfun = std::dynamic_pointer_cast<CompositeFunction>(
createFunction(
"CompositeFunction"));
206 }
else if (term.
name() ==
",") {
207 auto firstTerm = term.
terms().cbegin();
208 if (firstTerm->name() ==
"=") {
209 if (firstTerm->terms()[0].name() ==
"composite") {
210 cfun = std::dynamic_pointer_cast<CompositeFunction>(
createSimple(term, parentAttributes));
214 }
else if (firstTerm->terms()[0].name() ==
"name") {
215 cfun = std::dynamic_pointer_cast<CompositeFunction>(
createFunction(
"CompositeFunction"));
222 }
else if (term.
name() ==
";") {
223 cfun = std::dynamic_pointer_cast<CompositeFunction>(
createFunction(
"CompositeFunction"));
233 for (; it != terms.end(); ++it) {
236 std::map<std::string, std::string> pAttributes;
237 if (currentTerm.
name() ==
";") {
242 std::string parName = currentTerm[0].
name();
243 if (parName.size() >= 10 && parName.substr(0, 10) ==
"constraint") {
246 }
else if (parName ==
"ties") {
247 addTies(cfun, currentTerm[1].bracketsRemoved());
253 cfun->addFunction(fun);
254 size_t i = cfun->nFunctions() - 1;
255 for (
auto &pAttribute : pAttributes) {
259 if (cfun->hasLocalAttribute(pAttribute.first)) {
260 cfun->setLocalAttributeValue(i, pAttribute.first, pAttribute.second);
262 parentAttributes[pAttribute.first] = pAttribute.second;
273 std::string msg(
"Error in input string to FunctionFactory");
277 throw std::invalid_argument(msg);
290 if (expr.
name() ==
",") {
291 for (
auto it = expr.
begin(); it != expr.
end(); ++it) {
294 auto constraint = (*it);
295 std::string constraint_term = constraint.terms()[0].str();
296 if (constraint_term.compare(
"penalty") == 0) {
300 if ((it + 1) != expr.
end()) {
301 auto next_constraint = *(it + 1);
302 std::string next_term = next_constraint.terms()[0].str();
303 if (next_term.compare(
"penalty") == 0) {
323 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().
createInitialized(fun.get(), expr));
324 c->setPenaltyFactor(c->getDefaultPenaltyFactor());
325 fun->addConstraint(std::move(c));
336 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().
createInitialized(fun.get(), constraint_expr));
337 double penalty_factor = std::stof(penalty_expr.
terms()[1].str(), NULL);
338 c->setPenaltyFactor(penalty_factor);
339 fun->addConstraint(std::move(c));
348 if (expr.
name() ==
"=") {
350 }
else if (expr.
name() ==
",") {
351 fun->addTies(expr.
str());
360 if (expr.
size() > 1) {
364 for (
size_t i = expr.
size() - 1; i != 0;) {
372 auto allNames = getFunctionNames<IFunction1D>();
373 auto ImmutableCompositeFunctions = getFunctionNames<ImmutableCompositeFunction>();
374 allNames.insert(allNames.end(), ImmutableCompositeFunctions.begin(), ImmutableCompositeFunctions.end());
375 allNames.emplace_back(
"ProductFunction");
376 allNames.emplace_back(
"CompositeFunction");
377 allNames.emplace_back(
"Convolution");
378 std::sort(allNames.begin(), allNames.end());
379 std::vector<std::string> names;
380 names.reserve(allNames.size());
381 auto excludes = Kernel::ConfigService::Instance().getString(
"curvefitting.guiExclude");
384 std::copy_if(allNames.cbegin(), allNames.cend(), std::back_inserter(names),
385 [&excludeList](
const auto &
name) { return excludeList.count(name) == 0; });
double value
The value of the point.
Specialised exception for parsing errors.
This class represents an expression made up of names, binary operators and brackets.
const std::vector< Expression > & terms() const
Returns the top level terms of the expression (function arguments).
void parse(const std::string &str)
Parse a string and create an expression.
const std::string & name() const
Returns the name of the expression which is a function or variable name.
const Expression & bracketsRemoved() const
If the expression has 1 argument and empty function name it means it is wrapped in brackets This meth...
iterator end() const
An iterator pointing to the end of the expressions.
iterator begin() const
An iterator pointing to the start of the expressions.
std::string str() const
Returns this expression as a string.
size_t size() const
Returns the number of argumens.
std::shared_ptr< IFunction > createFunction(const std::string &type) const
Creates an instance of a function.
std::shared_ptr< MultiDomainFunction > createInitializedMultiDomainFunction(const std::string &input, size_t domainNumber) const
Creates an instnce of an inizialised multidomain function where each domain has the same function.
std::shared_ptr< CompositeFunction > createComposite(const Expression &expr, std::map< std::string, std::string > &parentAttributes) const
Create a composite function.
void addConstraints(const std::shared_ptr< IFunction > &fun, const Expression &expr) const
Add constraints to the created function.
std::vector< std::string > getFunctionNamesGUI() const
Get function names that can be used by generic fitting GUIs.
std::shared_ptr< IFunction > createSimple(const Expression &expr, std::map< std::string, std::string > &parentAttributes) const
Create a simple function.
void inputError(const std::string &str="") const
Throw an exception.
void unsubscribe(const std::string &className)
void subscribe(const std::string &className, std::unique_ptr< AbstractFactory > pAbstractFactory, Kernel::DynamicFactory< IFunction >::SubscribeAction replace=ErrorIfExists)
void addTies(const std::shared_ptr< IFunction > &fun, const Expression &expr) const
Add ties to the created function.
std::map< std::string, std::vector< std::string > > m_cachedFunctionNames
void addTie(const std::shared_ptr< IFunction > &fun, const Expression &expr) const
Add a tie to the created function.
void addConstraint(const std::shared_ptr< IFunction > &fun, const Expression &expr) const
Add a single constraint to the created function.
FunctionFactoryImpl()
Private Constructor for singleton class.
std::shared_ptr< IFunction > createInitialized(const std::string &input) const
Creates an instance of a function.
Attribute is a non-fitting parameter.
void fromString(const std::string &str)
Set value from a string.
This is an interface to a fitting function - a semi-abstarct class.
The dynamic factory is a base dynamic factory for serving up objects in response to requests from oth...
void subscribe(const std::string &className)
Registers the instantiator for the given class with the DynamicFactory.
void unsubscribe(const std::string &className)
Unregisters the given class and deletes the instantiator for the class.
virtual std::shared_ptr< IFunction > create(const std::string &className) const
Creates a new instance of the class with the given name.
SubscribeAction
Defines replacement behaviour.
Iterator begin()
Iterator referring to first element in the container.
@ TOK_TRIM
remove leading and trailing whitespace from tokens
Iterator end()
Iterator referring to the past-the-end element in the container.
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Mantid::Kernel::StringTokenizer tokenizer
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class