Mantid
Loading...
Searching...
No Matches
CompositeFunction.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
15#include "MantidKernel/Logger.h"
17
18#include <algorithm>
19#include <boost/lexical_cast.hpp>
20#include <memory>
21#include <numeric>
22#include <sstream>
23#include <utility>
24
25namespace Mantid::API {
26
27namespace {
29Kernel::Logger g_log("CompositeFunction");
30constexpr char *ATTNUMDERIV = "NumDeriv";
31constexpr int NUMDEFAULTATTRIBUTES = 1;
41template <typename T>
42void replaceVariableIndexRange(std::vector<T> &variableFunctionIndexList, const size_t oldSize, const size_t newSize,
43 const T functionIndex) {
44 auto itFun = std::find(variableFunctionIndexList.begin(), variableFunctionIndexList.end(), functionIndex);
45 if (itFun != variableFunctionIndexList.end()) {
46 if (oldSize > newSize) {
47 variableFunctionIndexList.erase(itFun, itFun + oldSize - newSize);
48 } else if (oldSize < newSize) {
49 variableFunctionIndexList.insert(itFun, newSize - oldSize, functionIndex);
50 }
51 } else if (newSize > 0) {
52 using std::placeholders::_1;
53 itFun = std::find_if(variableFunctionIndexList.begin(), variableFunctionIndexList.end(),
54 std::bind(std::greater<size_t>(), _1, functionIndex));
55 variableFunctionIndexList.insert(itFun, newSize, functionIndex);
56 }
57}
58
59} // namespace
60
61using std::size_t;
62
63DECLARE_FUNCTION(CompositeFunction)
64
65
66CompositeFunction::CompositeFunction() : IFunction(), m_nParams(0), m_nAttributes(0), m_iConstraintFunction(false) {
67 createDefaultGlobalAttributes();
68}
69
72 declareAttribute(ATTNUMDERIV, Attribute(false));
73 m_nAttributes = NUMDEFAULTATTRIBUTES;
74}
75
78
95std::string CompositeFunction::writeToString(const std::string &parentLocalAttributesStr) const {
96 std::ostringstream ostr;
97
98 // if empty just return function name
99 if (nFunctions() == 0) {
100 return "name=" + name();
101 }
102
103 if (name() != "CompositeFunction" || nGlobalAttributes() > NUMDEFAULTATTRIBUTES ||
104 getAttribute(ATTNUMDERIV).asBool() || !parentLocalAttributesStr.empty()) {
105 ostr << "composite=" << name();
106 std::vector<std::string> attr = m_globalAttributeNames;
107 for (const auto &attName : attr) {
108 std::string attValue = this->getAttribute(attName).value();
109 if (!attValue.empty()) {
110 ostr << ',' << attName << '=' << attValue;
111 }
112 }
113 ostr << parentLocalAttributesStr << ';';
114 }
115 const auto localAttr = this->getLocalAttributeNames();
116 for (size_t i = 0; i < nFunctions(); i++) {
118 bool isComp = std::dynamic_pointer_cast<CompositeFunction>(fun) != nullptr;
119 if (isComp)
120 ostr << '(';
121 std::ostringstream localAttributesStr;
122 for (const auto &localAttName : localAttr) {
123 const std::string localAttValue = this->getLocalAttribute(i, localAttName).value();
124 if (!localAttValue.empty()) {
125 // local attribute names are prefixed by dollar sign
126 localAttributesStr << ',' << '$' << localAttName << '=' << localAttValue;
127 }
128 }
129 ostr << fun->writeToString(localAttributesStr.str());
130 if (isComp)
131 ostr << ')';
132 if (i < nFunctions() - 1) {
133 ostr << ';';
134 }
135 }
136
137 // collect non-default constraints
138 std::string constraints = writeConstraints();
139 // print constraints
140 if (!constraints.empty()) {
141 ostr << ";constraints=(" << constraints << ")";
142 }
143
144 // collect the non-default ties
145 std::string ties = writeTies();
146 // print the ties
147 if (!ties.empty()) {
148 ostr << ";ties=(" << ties << ")";
149 }
150
151 return ostr.str();
152}
153
157void CompositeFunction::setWorkspace(std::shared_ptr<const Workspace> ws) {
158 // Pass it on to each member
159 auto iend = m_functions.end();
160 for (auto it = m_functions.begin(); it != iend; ++it) {
161 (*it)->setWorkspace(ws);
162 }
163}
164
171void CompositeFunction::setMatrixWorkspace(std::shared_ptr<const MatrixWorkspace> workspace, size_t wi, double startX,
172 double endX) {
173 for (size_t iFun = 0; iFun < nFunctions(); ++iFun) {
174 m_functions[iFun]->setMatrixWorkspace(workspace, wi, startX, endX);
175 }
176}
177
182 std::for_each(m_functions.begin(), m_functions.end(),
183 [&stepSizeMethod](const auto &function) { function->setStepSizeMethod(stepSizeMethod); });
184}
185
192 FunctionValues tmp(domain);
193 values.zeroCalculated();
194 for (size_t iFun = 0; iFun < nFunctions(); ++iFun) {
195 m_functions[iFun]->function(domain, tmp);
196 values += tmp;
197 }
198}
199
206 if (getAttribute(ATTNUMDERIV).asBool()) {
207 calNumericalDeriv(domain, jacobian);
208 } else {
209 for (size_t iFun = 0; iFun < nFunctions(); ++iFun) {
210 PartialJacobian J(&jacobian, paramOffset(iFun));
211 getFunction(iFun)->functionDeriv(domain, J);
212 }
213 }
214}
215
222void CompositeFunction::setParameter(size_t i, const double &value, bool explicitlySet) {
223 size_t iFun = functionIndex(i);
224 m_functions[iFun]->setParameter(i - m_paramOffsets[iFun], value, explicitlySet);
225}
226
231void CompositeFunction::setParameterDescription(size_t i, const std::string &description) {
232 size_t iFun = functionIndex(i);
233 m_functions[iFun]->setParameterDescription(i - m_paramOffsets[iFun], description);
234}
235
240double CompositeFunction::getParameter(size_t i) const {
241 size_t iFun = functionIndex(i);
242 return m_functions[iFun]->getParameter(i - m_paramOffsets[iFun]);
243}
244
250double CompositeFunction::getParameter(size_t i, size_t j) const { return m_functions[i]->getParameter(j); }
251
257bool CompositeFunction::hasParameter(const std::string &name) const {
258 try {
259 const auto [parameterName, index] = parseName(name);
260 return index < m_functions.size() ? m_functions[index]->hasParameter(parameterName) : false;
261 } catch (std::invalid_argument &) {
262 return false;
263 }
264}
265
271bool CompositeFunction::hasAttribute(const std::string &name) const {
272 try {
273 if (std::find(m_globalAttributeNames.begin(), m_globalAttributeNames.end(), name) != m_globalAttributeNames.end()) {
274 return true;
275 }
276 const auto [attributeName, index] = parseName(name);
277 return index < m_functions.size() ? m_functions[index]->hasAttribute(attributeName) : false;
278 } catch (std::invalid_argument &) {
279 return false;
280 }
281}
282
290void CompositeFunction::setParameter(const std::string &name, const double &value, bool explicitlySet) {
291 const auto [parameterName, index] = parseName(name);
292 getFunction(index)->setParameter(parameterName, value, explicitlySet);
293}
294
300void CompositeFunction::setParameterDescription(const std::string &name, const std::string &description) {
301 const auto [parameterName, index] = parseName(name);
302 getFunction(index)->setParameterDescription(parameterName, description);
303}
304
310double CompositeFunction::getParameter(const std::string &name) const {
311 const auto [parameterName, index] = parseName(name);
312 return getFunction(index)->getParameter(parameterName);
313}
314
320 try {
321 if (std::find(m_globalAttributeNames.begin(), m_globalAttributeNames.end(), name) != m_globalAttributeNames.end()) {
323 }
324 const auto [attributeName, index] = parseName(name);
325 return m_functions[index]->getAttribute(attributeName);
326 } catch (std::invalid_argument &) {
327 throw std::invalid_argument("ParamFunctionAttributeHolder::getAttribute - Unknown attribute '" + name + "'");
328 }
329}
330
337 if (std::find(m_globalAttributeNames.begin(), m_globalAttributeNames.end(), name) != m_globalAttributeNames.end()) {
339 }
340 const auto [attributeName, index] = parseName(name);
341 return m_functions[index]->setAttribute(attributeName, value);
342}
343
345size_t CompositeFunction::nParams() const { return m_nParams; }
346
347// Total number of attributes
349 return std::accumulate(
350 m_functions.cbegin(), m_functions.cend(), nGlobalAttributes(),
351 [](const size_t accumulator, const auto &function) -> size_t { return accumulator + function->nAttributes(); });
352}
358size_t CompositeFunction::parameterIndex(const std::string &name) const {
359 const auto [parameterName, index] = parseName(name);
360 return getFunction(index)->parameterIndex(parameterName) + m_paramOffsets[index];
361}
362
366std::string CompositeFunction::parameterName(size_t i) const {
367 const size_t iFun = functionIndex(i);
368 std::ostringstream ostr;
369 ostr << 'f' << iFun << '.' << m_functions[iFun]->parameterName(i - m_paramOffsets[iFun]);
370 return ostr.str();
371}
372
377std::string CompositeFunction::parameterName(size_t i, size_t j) const {
378 std::ostringstream ostr;
379 ostr << 'f' << i << '.' << m_functions[i]->parameterName(j);
380 return ostr.str();
381}
382
386std::string CompositeFunction::attributeName(size_t index) const {
387 if (index < nGlobalAttributes())
389
390 // Offset the index by the number of global attributes
391 const size_t offsetIndex = index - nGlobalAttributes();
392 size_t functionIndex = attributeFunctionIndex(offsetIndex);
393 std::ostringstream ostr;
394 ostr << 'f' << functionIndex << '.' << m_functions[functionIndex]->attributeName(getAttributeOffset(offsetIndex));
395 return ostr.str();
396}
397
401std::string CompositeFunction::parameterDescription(size_t i) const {
402 const size_t iFun = functionIndex(i);
403 std::ostringstream ostr;
404 ostr << m_functions[iFun]->parameterDescription(i - m_paramOffsets[iFun]);
405 return ostr.str();
406}
412double CompositeFunction::getError(size_t i) const {
413 size_t iFun = functionIndex(i);
414 return m_functions[iFun]->getError(i - m_paramOffsets[iFun]);
415}
422double CompositeFunction::getError(size_t i, size_t j) const { return m_functions[i]->getError(j); }
423
429double CompositeFunction::getError(const std::string &name) const {
430 const auto [parameterName, index] = parseName(name);
431 return getFunction(index)->getError(parameterName);
432}
433
439void CompositeFunction::setError(size_t i, double err) {
440 size_t iFun = functionIndex(i);
441 m_functions[iFun]->setError(i - m_paramOffsets[iFun], err);
442}
443
449void CompositeFunction::setError(const std::string &name, double err) {
451 getFunction(index)->setError(parameterName, err);
452}
453
457 size_t iFun = functionIndex(i);
458 return m_functions[iFun]->activeParameter(i - m_paramOffsets[iFun]);
459}
460
464 size_t iFun = functionIndex(i);
465 m_functions[iFun]->setActiveParameter(i - m_paramOffsets[iFun], value);
466}
467
469std::string CompositeFunction::nameOfActive(size_t i) const {
470 size_t iFun = functionIndex(i);
471 std::ostringstream ostr;
472 ostr << 'f' << iFun << '.' << m_functions[iFun]->nameOfActive(i - m_paramOffsets[iFun]);
473 return ostr.str();
474}
475
477std::string CompositeFunction::descriptionOfActive(size_t i) const {
478 size_t iFun = functionIndex(i);
479 std::ostringstream ostr;
480 ostr << m_functions[iFun]->descriptionOfActive(i - m_paramOffsets[iFun]);
481 return ostr.str();
482}
483
486 size_t iFun = functionIndex(i);
487 m_functions[iFun]->setParameterStatus(i - m_paramOffsets[iFun], status);
488}
489
492 size_t iFun = functionIndex(i);
493 return m_functions[iFun]->getParameterStatus(i - m_paramOffsets[iFun]);
494}
495
499 m_nParams = 0;
501 m_paramOffsets.clear();
502 m_IFunction.clear();
503 m_attributeIndex.clear();
504
505 std::vector<IFunction_sptr> functions(m_functions.begin(), m_functions.end());
506 m_functions.clear();
507
508 for (auto &f : functions) {
509 CompositeFunction_sptr cf = std::dynamic_pointer_cast<CompositeFunction>(f);
510 if (cf)
511 cf->checkFunction();
512 addFunction(f);
513 }
514}
515
520 m_nParams = 0;
522 m_paramOffsets.clear();
523 m_IFunction.clear();
524 m_functions.clear();
525 m_attributeIndex.clear();
526}
527
533 m_IFunction.insert(m_IFunction.end(), f->nParams(), m_functions.size());
534 m_attributeIndex.insert(m_attributeIndex.end(), f->nAttributes(), m_functions.size());
535 m_functions.emplace_back(f);
536 if (m_paramOffsets.empty()) {
537 m_paramOffsets.emplace_back(0);
538 m_nParams = f->nParams();
539 m_nAttributes = f->nAttributes() + nGlobalAttributes();
540 } else {
541 m_paramOffsets.emplace_back(m_nParams);
542 m_nParams += f->nParams();
543 m_nAttributes += f->nAttributes();
544 }
545 return m_functions.size() - 1;
546}
547
552 if (i >= nFunctions()) {
553 throw std::out_of_range("Function index (" + std::to_string(i) + ") out of range (" + std::to_string(nFunctions()) +
554 ").");
555 }
556
557 const IFunction_sptr fun = getFunction(i);
558 // Remove ties which are no longer valid
559 for (size_t j = 0; j < nParams();) {
560 ParameterTie *tie = getTie(j);
561 if (tie && tie->findParametersOf(fun.get())) {
562 removeTie(j);
563 } else {
564 j++;
565 }
566 }
567
568 // Shift down the function indices for parameters and attributes
569 auto shiftDown = [&](auto &functionIndex) {
570 if (functionIndex == i) {
571 return true;
572 } else if (functionIndex > i) {
573 functionIndex -= 1;
574 return false;
575 } else {
576 return false;
577 }
578 };
579
580 m_IFunction.erase(std::remove_if(m_IFunction.begin(), m_IFunction.end(), shiftDown), m_IFunction.end());
581 m_attributeIndex.erase(std::remove_if(m_attributeIndex.begin(), m_attributeIndex.end(), shiftDown),
582 m_attributeIndex.end());
583
584 // Reduction in parameters and attributes
585 m_nParams -= fun->nParams();
586 m_nAttributes -= fun->nAttributes();
587
588 // Shift the parameter offsets down by the total number of i-th function's
589 // params
590 for (size_t j = i + 1; j < nFunctions(); j++) {
591 m_paramOffsets[j] -= fun->nParams();
592 }
593 m_paramOffsets.erase(m_paramOffsets.begin() + i);
594
595 m_functions.erase(m_functions.begin() + i);
596}
597
605 std::vector<IFunction_sptr>::const_iterator it = std::find(m_functions.begin(), m_functions.end(), f_old);
606 if (it == m_functions.end())
607 return;
608 std::vector<IFunction_sptr>::difference_type iFun = it - m_functions.begin();
609 replaceFunction(iFun, f_new);
610}
611
616void CompositeFunction::replaceFunction(size_t functionIndex, const IFunction_sptr &f) {
617 if (functionIndex >= nFunctions()) {
618 throw std::out_of_range("Function index (" + std::to_string(functionIndex) + ") out of range (" +
619 std::to_string(nFunctions()) + ").");
620 }
621
623 const size_t np_old = fun->nParams();
624 const size_t np_new = f->nParams();
625 const size_t at_old = fun->nAttributes();
626 const size_t at_new = f->nAttributes();
627
628 // Modify function parameter and attribute indices:
629 replaceVariableIndexRange(m_IFunction, np_old, np_new, functionIndex);
630 replaceVariableIndexRange(m_attributeIndex, at_old, at_new, functionIndex);
631
632 // Decrement attribute and parameter counts
633 const size_t dnp = np_new - np_old;
634 const size_t dna = at_new - at_old;
635 m_nParams += dnp;
636 m_nAttributes += dna;
637
638 // Shift the parameter offsets down by the total number of i-th function's
639 // params
640 for (size_t j = functionIndex + 1; j < nFunctions(); j++) {
641 m_paramOffsets[j] += dnp;
642 }
644}
645
651bool CompositeFunction::hasFunction(const std::string &functionName) const {
652 return std::any_of(m_functions.cbegin(), m_functions.cend(), [&functionName](const IFunction_const_sptr &function) {
653 return function->name() == functionName;
654 });
655}
656
662 if (i >= nFunctions()) {
663 throw std::out_of_range("Function index (" + std::to_string(i) + ") out of range (" + std::to_string(nFunctions()) +
664 ").");
665 }
666 return m_functions[i];
667}
668
675std::size_t CompositeFunction::functionIndex(const std::string &functionName) const {
676 const auto iter =
677 std::find_if(m_functions.cbegin(), m_functions.cend(),
678 [&functionName](const IFunction_const_sptr &function) { return function->name() == functionName; });
679
680 if (iter != m_functions.cend())
681 return std::distance(m_functions.cbegin(), iter);
682
683 throw std::invalid_argument("A function with name '" + functionName + "' does not exist in this composite function.");
684}
685
691size_t CompositeFunction::functionIndex(std::size_t i) const {
692 if (i >= nParams()) {
693 throw std::out_of_range("Function parameter index (" + std::to_string(i) + ") out of range (" +
694 std::to_string(nParams()) + ").");
695 }
696 return m_IFunction[i];
697}
703size_t CompositeFunction::attributeFunctionIndex(std::size_t i) const {
704 if (i >= nAttributes()) {
705 throw std::out_of_range("Function attribute index (" + std::to_string(i) + ") out of range (" +
706 std::to_string(nAttributes()) + ").");
707 }
708 return m_attributeIndex[i];
709}
710
716std::pair<std::string, size_t> CompositeFunction::parseName(const std::string &varName) {
717 const size_t i = varName.find('.');
718 if (i == std::string::npos) {
719 throw std::invalid_argument("Variable " + varName + " not found.");
720 } else {
721 if (varName[0] != 'f')
722 throw std::invalid_argument("External function variable name must start with 'f'");
723
724 const std::string sindex = varName.substr(1, i - 1);
725 const size_t index = boost::lexical_cast<size_t>(sindex);
726
727 if (i == varName.size() - 1)
728 throw std::invalid_argument("Name cannot be empty");
729
730 return std::make_pair(varName.substr(i + 1), index);
731 }
732}
733
740size_t CompositeFunction::parameterLocalIndex(size_t i, bool recursive) const {
741 size_t iFun = functionIndex(i);
742 auto localIndex = i - m_paramOffsets[iFun];
743 if (recursive) {
744 auto cf = dynamic_cast<const CompositeFunction *>(m_functions[iFun].get());
745 if (cf) {
746 return cf->parameterLocalIndex(localIndex, recursive);
747 }
748 }
749 return localIndex;
750}
751
758std::string CompositeFunction::parameterLocalName(size_t i, bool recursive) const {
759 size_t iFun = functionIndex(i);
760 auto localIndex = i - m_paramOffsets[iFun];
761 auto localFunction = m_functions[iFun].get();
762 if (recursive) {
763 auto cf = dynamic_cast<const CompositeFunction *>(localFunction);
764 if (cf) {
765 return cf->parameterLocalName(localIndex, recursive);
766 }
767 }
768 return localFunction->parameterName(localIndex);
769}
770
775 if (hasOrderedTies()) {
777 } else {
778 for (size_t i = 0; i < nFunctions(); i++) {
779 getFunction(i)->applyTies();
780 }
782 }
783}
784
790 for (size_t i = 0; i < nFunctions(); i++) {
791 getFunction(i)->clearTies();
792 }
793}
794
800 bool foundAndRemovedTie = IFunction::removeTie(i);
801 if (!foundAndRemovedTie) {
802 size_t iFun = functionIndex(i);
803 bool res = m_functions[iFun]->removeTie(i - m_paramOffsets[iFun]);
804 return res;
805 }
806 return foundAndRemovedTie;
807}
808
814 auto tie = IFunction::getTie(i);
815 if (tie == nullptr) {
816 size_t iFun = functionIndex(i);
817 tie = m_functions[iFun]->getTie(i - m_paramOffsets[iFun]);
818 }
819 return tie;
820}
821
828void CompositeFunction::declareParameter(const std::string &name, double initValue, const std::string &description) {
829 (void)name; // Avoid compiler warning
830 (void)initValue; // Avoid compiler warning
831 (void)description; // Avoid compiler warning
832 throw Kernel::Exception::NotImplementedError("CompositeFunction cannot not have its own parameters.");
833}
839void CompositeFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue) {
840 IFunction::declareAttribute(name, defaultValue);
841 m_globalAttributeNames.emplace_back(name);
842}
843
850void CompositeFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue,
851 const Kernel::IValidator &validator) {
852 IFunction::declareAttribute(name, defaultValue, validator);
853 m_globalAttributeNames.emplace_back(name);
854}
855
860 for (size_t i = 0; i < nFunctions(); i++) {
861 getFunction(i)->registerFunctionUsage(internal);
862 }
863}
864
870 // set up the member functions
871 for (size_t i = 0; i < nFunctions(); i++) {
872 getFunction(i)->setUpForFit();
873 }
874
875 // Instead of automatically switching to numeric derivatives
876 // log a warning about a danger of not using it
877 if (!getAttribute("NumDeriv").asBool()) {
878 for (size_t i = 0; i < nParams(); ++i) {
879 ParameterTie *tie = getTie(i);
880 if (tie && !tie->isConstant()) {
881 g_log.warning() << "Numeric derivatives should be used when "
882 "non-constant ties defined.\n";
883 break;
884 }
885 }
886 }
887}
888
893 auto constraint = IFunction::getConstraint(i);
894 if (constraint == nullptr) {
895 size_t iFun = functionIndex(i);
896 constraint = m_functions[iFun]->getConstraint(i - m_paramOffsets[iFun]);
897 }
898 return constraint;
899}
900
904void CompositeFunction::removeConstraint(const std::string &parName) {
905 auto i = parameterIndex(parName);
906 auto constraint = IFunction::getConstraint(i);
907 if (constraint != nullptr) {
909 } else {
910 size_t iPar = parameterIndex(parName);
911 size_t iFun = functionIndex(iPar);
912 getFunction(iFun)->removeConstraint(parameterLocalName(iPar));
913 }
914}
915
921 size_t iFun = functionIndex(i);
922 return m_functions[iFun]->isExplicitlySet(i - m_paramOffsets[iFun]);
923}
924
932 if (ref.getLocalFunction() == this && ref.getLocalIndex() < nParams()) {
933 return ref.getLocalIndex();
934 }
935 for (size_t iFun = 0; iFun < nFunctions(); iFun++) {
936 IFunction_sptr fun = getFunction(iFun);
937 size_t iLocalIndex = fun->getParameterIndex(ref);
938 if (iLocalIndex < fun->nParams()) {
939 return m_paramOffsets[iFun] + iLocalIndex;
940 }
941 }
942 return nParams();
943}
944
951 for (size_t iFun = 0; iFun < nFunctions(); iFun++) {
952 IFunction_sptr fun = getFunction(iFun);
953 if (fun->getParameterIndex(ref) < fun->nParams()) {
954 return fun;
955 }
956 }
957 return IFunction_sptr();
958}
959
962 auto n = nFunctions();
963 if (n == 0) {
964 return 1;
965 }
966 size_t nd = getFunction(0)->getNumberDomains();
967 for (size_t iFun = 1; iFun < n; ++iFun) {
968 if (getFunction(0)->getNumberDomains() != nd) {
969 throw std::runtime_error("CompositeFunction has members with "
970 "inconsistent domain numbers.");
971 }
972 }
973 return nd;
974}
975
981std::vector<IFunction_sptr> CompositeFunction::createEquivalentFunctions() const {
982 auto nd = getNumberDomains();
983 if (nd == 1) {
984 return std::vector<IFunction_sptr>(1, FunctionFactory::Instance().createInitialized(asString()));
985 }
986
987 auto nf = nFunctions();
988 std::vector<std::vector<IFunction_sptr>> equiv;
989 equiv.reserve(nf);
990 for (size_t i = 0; i < nf; ++i) {
991 equiv.emplace_back(getFunction(i)->createEquivalentFunctions());
992 }
993
994 std::vector<IFunction_sptr> funs;
995 funs.reserve(nd);
996 for (size_t i = 0; i < nd; ++i) {
997 auto comp = new CompositeFunction;
998 funs.emplace_back(IFunction_sptr(comp));
999 for (size_t j = 0; j < nf; ++j) {
1000 comp->addFunction(equiv[j][i]);
1001 }
1002 }
1003 return funs;
1004}
1005size_t CompositeFunction::getAttributeOffset(size_t attributeIndex) const {
1006 auto functionIndex = m_attributeIndex[attributeIndex];
1007 return std::distance(std::find(m_attributeIndex.begin(), m_attributeIndex.end(), functionIndex),
1008 m_attributeIndex.begin() + attributeIndex);
1009}
1010
1011} // namespace Mantid::API
gsl_vector * tmp
double value
The value of the point.
Definition: FitMW.cpp:51
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
A composite function is a function containing other functions.
size_t nAttributes() const override
Returns the number of attributes associated with the function.
std::string nameOfActive(size_t i) const override
Returns the name of active parameter i.
void clearTies() override
Remove all ties.
static std::pair< std::string, size_t > parseName(const std::string &varName)
Extract function index and parameter name from a variable name.
ParameterTie * getTie(size_t i) const override
Get the tie of i-th parameter.
void setUpForFit() override
Prepare function for a fit.
std::string parameterLocalName(size_t i, bool recursive=false) const
Returns the name of parameter i as it declared in its function.
size_t m_nParams
Total number of parameters.
std::string descriptionOfActive(size_t i) const override
Returns the name of active parameter i.
void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override
Derivatives of function with respect to active parameters.
bool hasParameter(const std::string &name) const override
Check if function has a parameter with this name.
virtual std::vector< std::string > getLocalAttributeNames() const
Returns a list of attribute names.
virtual size_t addFunction(IFunction_sptr f)
Add a function at the back of the internal function list.
void setActiveParameter(size_t i, double value) override
Set new value of i-th active parameter.
void function(const FunctionDomain &domain, FunctionValues &values) const override
Function you want to fit to.
std::string attributeName(size_t i) const override
Returns the name of attribute i.
size_t nGlobalAttributes() const noexcept
std::vector< size_t > m_attributeIndex
void setParameter(size_t, const double &value, bool explicitlySet=true) override
Set i-th parameter.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
size_t paramOffset(size_t i) const
std::vector< std::shared_ptr< IFunction > > createEquivalentFunctions() const override
Split this function (if needed) into a list of independent functions.
size_t m_nAttributes
Total number of attributes.
void replaceFunctionPtr(const IFunction_sptr &f_old, const IFunction_sptr &f_new)
Replace a function.
bool removeTie(size_t i) override
Removes i-th parameter's tie.
void setWorkspace(std::shared_ptr< const Workspace > ws) override
Sets the workspace for each member function.
size_t getParameterIndex(const ParameterReference &ref) const override
Return parameter index from a parameter reference.
std::vector< size_t > m_paramOffsets
Individual function parameter offsets (function index in m_functions) e.g.
size_t parameterIndex(const std::string &name) const override
Returns the index of parameter name.
void setParameterDescription(size_t, const std::string &description) override
Set i-th parameter description.
bool hasAttribute(const std::string &name) const override
Check if a function has an attribute with this name.
std::size_t nFunctions() const override
Number of functions.
bool isExplicitlySet(size_t i) const override
Checks if a parameter has been set explicitly.
size_t nParams() const override
Total number of parameters.
void replaceFunction(size_t functionIndex, const IFunction_sptr &f)
Replace a function.
size_t getNumberDomains() const override
Get number of domains required by this function.
double getParameter(size_t i) const override
Get i-th parameter.
double getError(size_t i) const override
Get the fitting error for a parameter.
Attribute getAttribute(const std::string &name) const override
Return a value of attribute attName.
std::vector< std::string > m_globalAttributeNames
void init() override
Function initialization. Declare function parameters in this method.
IFunction_sptr getContainingFunction(const ParameterReference &ref) const
Get the containing function.
void removeConstraint(const std::string &parName) override
Remove a constraint.
std::string name() const override
Returns the function's name.
std::string parameterDescription(size_t i) const override
Returns the description of parameter i.
std::string writeToString(const std::string &parentLocalAttributesStr="") const override
Writes itself into a string.
void setMatrixWorkspace(std::shared_ptr< const API::MatrixWorkspace > workspace, size_t wi, double startX, double endX) override
Set matrix workspace.
std::size_t attributeFunctionIndex(std::size_t i) const
Get the index of the function to which parameter i belongs.
void removeFunction(size_t i)
Remove a function.
std::vector< size_t > m_IFunction
Keeps the function index for each declared parameter (parameter declared index)
virtual Attribute getLocalAttribute(size_t i, const std::string &attName) const
Return a value of attribute attName.
CompositeFunction()
Default constructor.
size_t parameterLocalIndex(size_t i, bool recursive=false) const
Returns the index of parameter i as it declared in its function.
double activeParameter(size_t i) const override
Value of i-th active parameter.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
std::string parameterName(size_t i) const override
Returns the name of parameter i.
IFunction_sptr getFunction(std::size_t i) const override
Returns the pointer to i-th function.
size_t getAttributeOffset(size_t attributeIndex) const
void setError(size_t i, double err) override
Set the fitting error for a parameter.
IConstraint * getConstraint(size_t i) const override
Get constraint of i-th parameter.
void setStepSizeMethod(const StepSizeMethod stepSizeMethod) override
Sets the function to use when calculating the step size.
void setAttribute(const std::string &name, const API::IFunction::Attribute &value) override
Set a value of a named attribute.
void applyTies() override
Apply the ties.
ParameterStatus getParameterStatus(size_t i) const override
Get status of parameter.
std::vector< IFunction_sptr > m_functions
Pointers to the included functions.
void registerFunctionUsage(bool internal) override
Registers the usage of the function with the UsageService.
std::size_t functionIndex(const std::string &functionName) const
Get the first function index with a matching function name.
void checkFunction()
Check the function.
bool hasFunction(const std::string &functionName) const
Returns true if the composite has at least one of this function.
void clear()
Remove all member functions.
void setParameterStatus(size_t i, ParameterStatus status) override
Change status of parameter.
Base class that represents the domain of a function.
A class to store values calculated by a function.
void zeroCalculated()
Set all calculated values to zero.
An interface to a constraint.
Definition: IConstraint.h:26
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
std::string value() const
Returns the attribute value as a string.
Definition: IFunction.cpp:652
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
bool hasOrderedTies() const
Definition: IFunction.cpp:295
virtual void removeConstraint(const std::string &parName)
Remove a constraint.
Definition: IFunction.cpp:403
std::string writeTies() const
Write a parameter tie to a string.
Definition: IFunction.cpp:261
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
Definition: IFunction.cpp:1394
virtual void clearTies()
Remove all ties.
Definition: IFunction.cpp:366
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
Definition: IFunction.cpp:1418
ParameterStatus
Describe parameter status in relation to fitting: Active: Fit varies such parameter directly.
Definition: IFunction.h:649
virtual void tie(const std::string &parName, const std::string &expr, bool isDefault=false)
Tie a parameter to other parameters (or a constant)
Definition: IFunction.cpp:214
virtual void applyTies()
Apply the ties.
Definition: IFunction.cpp:306
virtual ParameterTie * getTie(size_t i) const
Get the tie of i-th parameter.
Definition: IFunction.cpp:356
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Definition: IFunction.cpp:1409
virtual void setUpForFit()
Set up the function for a fit.
Definition: IFunction.cpp:433
virtual std::string attributeName(size_t index) const
Get name of ith attribute.
Definition: IFunction.cpp:1382
std::string asString() const
Writes itself into a string.
Definition: IFunction.cpp:462
void calNumericalDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Calculate numerical derivatives.
Definition: IFunction.cpp:1031
std::string writeConstraints() const
Write a parameter constraint to a string.
Definition: IFunction.cpp:441
virtual void removeTie(const std::string &parName)
Removes the tie off a parameter.
Definition: IFunction.cpp:254
virtual IConstraint * getConstraint(size_t i) const
Get constraint of i-th parameter.
Definition: IFunction.cpp:392
StepSizeMethod
Describes the method in which the step size will be calculated: DEFAULT: Uses the traditional Mantid ...
Definition: IFunction.h:658
Represents the Jacobian in IFitFunction::functionDeriv.
Definition: Jacobian.h:22
A reference to a parameter in a function.
std::size_t getLocalIndex() const
Return parameter index in the local function.
IFunction * getLocalFunction() const
Return pointer to the local function.
Ties fitting parameters.
Definition: ParameterTie.h:35
A Jacobian for individual functions.
Marks code as not implemented yet.
Definition: Exception.h:138
IValidator is the basic interface for all validators for properties.
Definition: IValidator.h:43
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition: IFunction.h:732
std::shared_ptr< const IFunction > IFunction_const_sptr
shared pointer to the function base class (const version)
Definition: IFunction.h:734
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
std::string to_string(const wide_integer< Bits, Signed > &n)