16#include <boost/lexical_cast.hpp>
32 m_domains[funIndex] = std::vector<size_t>(1, domainIndex);
53 std::set<size_t> dSet;
55 if (!domain.second.empty()) {
56 dSet.insert(domain.second.begin(), domain.second.end());
60 m_maxIndex = dSet.empty() ? 0 : *dSet.rbegin();
69 for (
size_t i = 0; i < domain.
getNParts(); ++i) {
90 domains.resize(nDomains);
91 for (
size_t i = 0; i < domains.size(); ++i) {
95 domains.assign(it->second.begin(), it->second.end());
114 throw std::invalid_argument(
"Non-CompositeDomain passed to MultiDomainFunction.");
119 throw std::invalid_argument(
"CompositeDomain has too few parts (" +
std::to_string(cd.getNParts()) +
123 if (cd.size() != values.
size()) {
124 throw std::invalid_argument(
"MultiDomainFunction: domain and values have different sizes.");
130 for (
size_t iFun = 0; iFun <
nFunctions(); ++iFun) {
132 std::vector<size_t> domains;
135 for (
auto const &dom : domains) {
153 throw std::invalid_argument(
"Non-CompositeDomain passed to MultiDomainFunction.");
162 throw std::invalid_argument(
"CompositeDomain has too few parts (" +
std::to_string(cd.getNParts()) +
169 for (
size_t iFun = 0; iFun <
nFunctions(); ++iFun) {
171 std::vector<size_t> domains;
174 for (
auto const &dom : domains) {
188 for (
size_t iFun = 0; iFun <
nFunctions(); ++iFun) {
197 for (
size_t iFun = 0; iFun <
nFunctions(); ++iFun) {
204 if (attName !=
"domains") {
205 throw std::invalid_argument(
"MultiDomainFunction does not have attribute " + attName);
208 throw std::out_of_range(
"Function index is out of range.");
212 if (it.size() == 1 && it.front() == funIndex) {
214 }
else if (!it.empty()) {
216 for (
auto i = it.begin() + 1; i != it.end(); ++i) {
221 }
catch (
const std::out_of_range &) {
257 if (attName !=
"domains") {
258 throw std::invalid_argument(
"MultiDomainFunction does not have attribute " + attName);
261 throw std::out_of_range(
"Function index is out of range.");
266 if (
value ==
"All") {
271 }
else if (
value ==
"i") {
274 }
else if (
value.empty()) {
280 std::vector<size_t> indx;
283 if (list.
name() ==
"+") {
284 if (list.
size() != 2 || list.
terms()[1].operator_name() !=
"-") {
285 throw std::runtime_error(
"MultiDomainFunction: attribute \"domains\" "
286 "expects two integers separated by a \"-\"");
290 auto start = boost::lexical_cast<size_t>(list.
terms()[0].str());
291 size_t end = boost::lexical_cast<size_t>(list.
terms()[1].str()) + 1;
293 throw std::runtime_error(
"MultiDomainFunction: attribute \"domains\": wrong range limits.");
295 indx.resize(end - start);
296 for (
size_t i = start; i < end; ++i) {
302 indx.reserve(list.
size());
303 std::transform(list.
begin(), list.
end(), std::back_inserter(indx),
317 std::vector<CompositeFunction_sptr> compositeFunctions(nDomains);
318 for (
size_t iFun = 0; iFun <
nFunctions(); ++iFun) {
320 std::vector<size_t> domains;
323 for (
auto domainIndex : domains) {
328 compositeFunctions[domainIndex] = cf;
332 cf->addFunction(FunctionFactory::Instance().createInitialized(
getFunction(iFun)->
asString()));
335 std::vector<IFunction_sptr> outFunctions(nDomains);
338 for (
size_t i = 0; i < compositeFunctions.size(); ++i) {
339 auto fun = compositeFunctions[i];
340 if (!fun || fun->nFunctions() == 0) {
341 throw std::runtime_error(
"There is no function for domain " +
std::to_string(i));
343 if (fun->nFunctions() > 1) {
344 outFunctions[i] = fun;
346 outFunctions[i] = fun->getFunction(0);
double value
The value of the point.
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Base class for a composite domain.
virtual const FunctionDomain & getDomain(size_t i) const =0
Return i-th domain.
virtual size_t getNParts() const =0
Return the number of parts in the domain.
size_t paramOffset(size_t i) const
std::size_t nFunctions() const override
Number of functions.
Attribute getAttribute(const std::string &name) const override
Return a value of attribute attName.
CompositeFunction()
Default constructor.
IFunction_sptr getFunction(std::size_t i) const override
Returns the pointer to i-th function.
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.
iterator end() const
An iterator pointing to the end of the expressions.
iterator begin() const
An iterator pointing to the start of the expressions.
void toList(const std::string &sep=",")
Make sure the expression is a list of expression separated by sep, eg "term1,term2,...
size_t size() const
Returns the number of argumens.
Base class that represents the domain of a function.
A class to store values calculated by a function.
void addToCalculated(size_t i, double value)
Add a number to a calculated value.
void zeroCalculated()
Set all calculated values to zero.
size_t size() const
Return the number of values.
Attribute is a non-fitting parameter.
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
std::string asString() const
Writes itself into a string.
void calNumericalDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Calculate numerical derivatives.
Represents the Jacobian in IFitFunction::functionDeriv.
virtual void zero()=0
Zero all matrix elements.
A composite function defined on a CompositeDomain.
size_t getMaxIndex() const
Get the largest domain index.
void setLocalAttribute(size_t funIndex, const std::string &attName, const Attribute &) override
Set a value to attribute attName.
Attribute getLocalAttribute(size_t funIndex, const std::string &attName) const override
Return a value of attribute attName.
void countValueOffsets(const CompositeDomain &domain) const
Count value offsets for each member domain in a CompositeDomain.
void countNumberOfDomains()
Counts number of the domains.
void iterationFinished() override
Called at the end of an iteration.
std::vector< size_t > m_valueOffsets
void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override
Derivatives of function with respect to active parameters.
std::map< size_t, std::vector< size_t > > m_domains
Domain index map: finction -> domain.
void getDomainIndices(size_t funIndex, size_t nDomains, std::vector< size_t > &domains) const
Get domain indices for a member function.
size_t getNumberDomains() const override
Get number of domains required by this function.
void iterationStarting() override
Called at the start of each iteration.
void setDomainIndices(size_t funIndex, const std::vector< size_t > &domainIndices)
Associate a function and a list of domains.
void clearDomainIndices()
Clear all domain indices.
void setDomainIndex(size_t funIndex, size_t domainIndex)
Associate a function and a domain.
size_t m_nDomains
Number of domains this MultiDomainFunction operates on.
std::vector< IFunction_sptr > createEquivalentFunctions() const override
Create a list of equivalent functions.
size_t m_maxIndex
Maximum domain index.
void function(const FunctionDomain &domain, FunctionValues &values) const override
Function you want to fit to.
A Jacobian for individual functions.
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
std::string to_string(const wide_integer< Bits, Signed > &n)