11#include <boost/algorithm/string.hpp>
12#include <boost/lexical_cast.hpp>
19 QString functionIndex;
20 QString initialParamName = QString::fromStdString(paramName);
21 QString parameterName = QString::fromStdString(paramName);
22 int j = initialParamName.lastIndexOf(
'.');
25 functionIndex = initialParamName.mid(0, j);
26 parameterName = initialParamName.mid(j);
28 return std::make_pair(functionIndex.toStdString(), parameterName.toStdString());
32 if (prefix.empty() || !fun) {
35 auto compFun = std::dynamic_pointer_cast<CompositeFunction>(fun);
37 throw std::runtime_error(
"Function " + fun->name() +
" is not composite");
39 auto const functionPrefix(QString::fromStdString(prefix));
40 auto j = functionPrefix.indexOf(
'.');
42 throw std::runtime_error(
"Error in fit function prefix: " + prefix +
"\nIt must end with a dot (.)");
44 if (j < 2 || functionPrefix[0] !=
'f') {
45 throw std::runtime_error(
"Error in fit function prefix: " + prefix +
46 "\nIt must start with an 'f' followed by an integer.");
48 auto funIndex = functionPrefix.mid(1, j - 1).toInt();
49 return getFunctionWithPrefix(functionPrefix.mid(j + 1).toStdString(), compFun->getFunction(funIndex));
54 return std::make_pair(
"", -1);
55 auto const functionPrefix(QString::fromStdString(prefix));
56 auto j = functionPrefix.lastIndexOf(
'.', -2);
57 auto parentPrefix = functionPrefix.left(j > 0 ? j + 1 : 0);
58 auto funIndex = functionPrefix.mid(j + 2, functionPrefix.size() - j - 3).toInt();
59 return std::make_pair(parentPrefix.toStdString(), funIndex);
62std::pair<std::string, std::pair<std::string, std::string>>
splitConstraintString(std::string
const &constraint) {
63 std::pair<std::string, std::pair<std::string, std::string>>
error;
64 if (constraint.empty())
66 std::string lowerBoundStr;
67 std::string upperBoundStr;
68 std::string paramName;
70 expr.
parse(constraint);
71 if (expr.
name() !=
"==") {
74 if (expr.
size() == 3) {
77 boost::lexical_cast<double>(expr[0].str());
78 boost::lexical_cast<double>(expr[2].str());
79 if (expr[1].operator_name() ==
"<" && expr[2].operator_name() ==
"<") {
80 lowerBoundStr = expr[0].
str();
81 upperBoundStr = expr[2].
str();
83 lowerBoundStr = expr[2].
str();
84 upperBoundStr = expr[0].
str();
86 paramName = expr[1].
str();
90 }
else if (expr.
size() == 2) {
94 boost::lexical_cast<double>(expr[1].
name());
101 upperBoundStr = expr[1].
str();
103 lowerBoundStr = expr[1].
str();
105 paramName = expr[0].
str();
108 boost::lexical_cast<double>(expr[0].
name());
113 lowerBoundStr = expr[0].
str();
115 upperBoundStr = expr[0].
str();
117 paramName = expr[1].
str();
120 return std::make_pair(paramName, std::make_pair(lowerBoundStr, upperBoundStr));
124 return !str.empty() && str.find_first_not_of(
"0123456789.-") == std::string::npos;
127std::vector<std::string>
splitStringBy(std::string
const &str, std::string
const &delimiter) {
128 std::vector<std::string> subStrings;
129 boost::split(subStrings, str, boost::is_any_of(delimiter));
130 subStrings.erase(std::remove_if(subStrings.begin(), subStrings.end(),
131 [](std::string
const &subString) { return subString.empty(); }),
138 if (
index < subStrings.size()) {
140 if (functionIndex.size() == 1 &&
isNumber(functionIndex[0]))
141 return std::stoull(functionIndex[0]);
144 throw std::invalid_argument(
"No function index was found.");
std::map< DeltaEMode::Type, std::string > index
This class represents an expression made up of names, binary operators and brackets.
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.
std::string str() const
Returns this expression as a string.
const std::string & operator_name() const
Returns the expression's binary operator on its left.
size_t size() const
Returns the number of argumens.
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class