Mantid
Loading...
Searching...
No Matches
IFunction.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 +
8#include "MantidAPI/Axis.h"
14#include "MantidAPI/Jacobian.h"
28#include "MantidKernel/Logger.h"
34
35#include <boost/lexical_cast.hpp>
36
38
39#include <algorithm>
40#include <limits>
41#include <sstream>
42#include <utility>
43
44namespace {
45
46constexpr double EPSILON = std::numeric_limits<double>::epsilon();
47constexpr double MIN_DOUBLE = std::numeric_limits<double>::min();
48constexpr double STEP_PERCENTAGE = 0.001;
49
50const auto defaultStepSize = [](const double parameterValue) -> double {
51 return fabs(parameterValue) < 100.0 * MIN_DOUBLE / STEP_PERCENTAGE ? 100.0 * EPSILON
52 : parameterValue * STEP_PERCENTAGE;
53};
54
55const auto sqrtEpsilonStepSize = [](const double parameterValue) -> double {
56 return fabs(parameterValue) < 1 ? sqrt(EPSILON) : parameterValue * sqrt(EPSILON);
57};
58
59} // namespace
60
61namespace Mantid::API {
62using namespace Geometry;
63
64namespace {
66Kernel::Logger g_log("IFunction");
67
69struct TieNode {
70 // Index of the tied parameter
71 size_t left;
72 // Indices of parameters on the right-hand-side of the expression
73 std::vector<size_t> right;
74 // This tie must be applied before the other if the RHS of the other
75 // contains this (left) parameter.
76 bool operator<(TieNode const &other) const {
77 return std::find(other.right.begin(), other.right.end(), left) != other.right.end();
78 }
79};
80const std::vector<std::string> EXCLUDEUSAGE = {"CompositeFunction"};
81} // namespace
82
86IFunction ::IFunction()
87 : m_isParallel(false), m_handler(nullptr), m_chiSquared(0.0), m_stepSizeFunction(defaultStepSize) {}
88
93
98 if (!Kernel::UsageService::Instance().isEnabled()) {
99 return;
100 }
101 if (std::find(EXCLUDEUSAGE.cbegin(), EXCLUDEUSAGE.cend(), name()) == EXCLUDEUSAGE.cend() && !m_isRegistered) {
102 m_isRegistered = true;
103 Kernel::UsageService::Instance().registerFeatureUsage(Kernel::FeatureType::Function, name(), internal);
104 }
105}
109std::shared_ptr<IFunction> IFunction::clone() const {
110 auto clonedFunction = FunctionFactory::Instance().createInitialized(this->asString());
111 for (size_t i = 0; i < this->nParams(); i++) {
112 double error = this->getError(i);
113 clonedFunction->setError(i, error);
114 }
115 return clonedFunction;
116}
117
123void IFunction::setProgressReporter(std::shared_ptr<Kernel::ProgressBase> reporter) {
124 m_progReporter = std::move(reporter);
125 m_progReporter->setNotifyStep(0.01);
126}
127
132void IFunction::reportProgress(const std::string &msg) const {
133 if (m_progReporter) {
134 const_cast<Kernel::ProgressBase *>(m_progReporter.get())->report(msg);
135 }
136}
137
144 if (m_progReporter)
146 else
147 return false;
148}
149
155void IFunction::functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) { calNumericalDeriv(domain, jacobian); }
156
160bool IFunction::isActive(size_t i) const { return getParameterStatus(i) == Active; }
161
167bool IFunction::isFixed(size_t i) const {
168 auto status = getParameterStatus(i);
169 return status == Fixed || status == FixedByDefault;
170}
171
176
181void IFunction::fix(size_t i, bool isDefault) {
182 auto status = getParameterStatus(i);
183 if (status == Tied) {
184 throw std::runtime_error("Cannot fix parameter " + std::to_string(i) + " (" + parameterName(i) +
185 "): it has a tie.");
186 }
187 if (isDefault) {
189 } else {
191 }
192}
193
197void IFunction::unfix(size_t i) {
198 auto status = getParameterStatus(i);
199 if (status == Tied) {
200 throw std::runtime_error("Cannot unfix parameter " + std::to_string(i) + " (" + parameterName(i) +
201 "): it has a tie.");
202 }
204}
205
213std::unique_ptr<ParameterTie> IFunction::createAndProcessTie(const std::string &parName, const std::string &expr,
214 bool isDefault) {
215 auto newTie = std::make_unique<ParameterTie>(this, parName, expr, isDefault);
216
217 if (!isDefault && newTie->isConstant()) {
218 setParameter(parName, newTie->eval());
219 fix(getParameterIndex(*newTie));
220 return nullptr;
221 }
222
223 return newTie;
224}
225
233void IFunction::tie(const std::string &parName, const std::string &expr, bool isDefault) {
234 auto tiePtr = createAndProcessTie(parName, expr, isDefault);
235
236 if (tiePtr) {
237 addTie(std::move(tiePtr));
238 }
239}
240
250void IFunction::addTies(const std::string &ties, bool isDefault) {
251 std::map<size_t, std::pair<size_t, std::string>> oldTies;
252
253 Expression list;
254 list.parse(ties);
255 list.toList();
256 for (const auto &t : list) {
257 if (t.name() == "=" && t.size() >= 2) {
258 size_t n = t.size() - 1;
259 const std::string expr = t[n].str();
260 for (size_t i = n; i != 0;) {
261 --i;
262 const auto &parName = t[i].name();
263 auto parTie = createAndProcessTie(parName, expr, isDefault);
264
265 if (parTie) {
266 auto iPar = getParameterIndex(*parTie);
267 oldTies[iPar] = insertTie(std::move(parTie));
268 }
269 }
270 }
271 }
272
273 try {
274 sortTies(true);
275 } catch (std::runtime_error &) {
276 for (const auto &[iPar, oldTie] : oldTies) {
277 auto [oldIdx, oldExp] = oldTie;
278
279 if (!oldExp.empty()) {
280 m_ties[oldIdx] = std::make_unique<ParameterTie>(this, parameterName(iPar), oldExp);
281 } else {
282 removeTie(iPar);
283 }
284 }
285 throw;
286 }
287 applyTies();
288}
289
294void IFunction::removeTie(const std::string &parName) {
295 size_t i = parameterIndex(parName);
296 this->removeTie(i);
297}
298
301std::string IFunction::writeTies() const {
302 std::ostringstream tieStream;
303 bool first = true;
304 for (auto &parTie : m_ties) {
305 if (parTie->isDefault())
306 continue;
307 if (!first) {
308 tieStream << ',';
309 } else {
310 first = false;
311 }
312 tieStream << parTie->asString(this);
313 }
314 return tieStream.str();
315}
316
322std::pair<std::size_t, std::string> IFunction::insertTie(std::unique_ptr<ParameterTie> tie) {
323 auto iPar = getParameterIndex(*tie);
324 std::size_t existingTieIndex =
325 std::distance(m_ties.begin(), std::find_if(m_ties.begin(), m_ties.end(),
326 [&](const auto &m_tie) { return getParameterIndex(*m_tie) == iPar; }));
327 std::string oldExp = "";
328 const auto oldTie = getTie(iPar);
329 if (oldTie) {
330 const auto oldTieStr = oldTie->asString();
331 oldExp = oldTieStr.substr(oldTieStr.find("=") + 1);
332 }
333
334 if (existingTieIndex < m_ties.size()) {
335 m_ties[existingTieIndex] = std::move(tie);
336 } else {
337 m_ties.emplace_back(std::move(tie));
339 }
340
341 if (oldTie) {
342 return {existingTieIndex, oldExp};
343 } else {
344 return {existingTieIndex, ""};
345 }
346}
347
353void IFunction::addTie(std::unique_ptr<ParameterTie> tie) {
354 auto iPar = getParameterIndex(*tie);
355 const auto [oldIdx, oldExp] = insertTie(std::move(tie));
356
357 try {
358 // sortTies checks for circular and self ties
359 sortTies(true);
360 } catch (std::runtime_error &) {
361 // revert / remove tie if invalid
362 if (!oldExp.empty()) {
363 m_ties[oldIdx] = std::make_unique<ParameterTie>(this, parameterName(iPar), oldExp);
364 } else {
365 removeTie(iPar);
366 }
367 throw;
368 }
369}
370
371bool IFunction::hasOrderedTies() const { return !m_orderedTies.empty(); }
372
374 for (auto &&parTie : m_orderedTies) {
375 parTie->eval();
376 }
377}
378
383 if (hasOrderedTies()) {
385 } else {
386 for (auto &parTie : m_ties) {
387 parTie->eval();
388 }
389 }
390}
391
399 const size_t m_i;
400
401public:
403 explicit ReferenceEqual(const IFunction &fun, size_t i) : m_fun(fun), m_i(i) {}
407 template <class T> bool operator()(const std::unique_ptr<T> &p) { return m_fun.getParameterIndex(*p) == m_i; }
408};
409
414bool IFunction::removeTie(size_t i) {
415 if (i >= nParams()) {
416 throw std::out_of_range("Function parameter index out of range.");
417 }
418 auto it = std::find_if(m_ties.begin(), m_ties.end(), ReferenceEqual(*this, i));
419 if (it != m_ties.end()) {
420 m_ties.erase(it);
422 return true;
423 }
424 unfix(i);
425 return false;
426}
427
433 auto it = std::find_if(m_ties.cbegin(), m_ties.cend(), ReferenceEqual(*this, i));
434 if (it != m_ties.cend()) {
435 return it->get();
436 }
437 return nullptr;
438}
439
443 for (size_t i = 0; i < nParams(); ++i) {
445 }
446 m_ties.clear();
447}
448
452void IFunction::addConstraint(std::unique_ptr<IConstraint> ic) {
453 size_t iPar = ic->parameterIndex();
454 auto it = std::find_if(m_constraints.begin(), m_constraints.end(),
455 [&iPar](const auto &constraint) { return constraint->parameterIndex() == iPar; });
456
457 if (it != m_constraints.end()) {
458 *it = std::move(ic);
459 } else {
460 m_constraints.emplace_back(std::move(ic));
461 }
462}
463
469 auto it = std::find_if(m_constraints.cbegin(), m_constraints.cend(), ReferenceEqual(*this, i));
470 if (it != m_constraints.cend()) {
471 return it->get();
472 }
473 return nullptr;
474}
475
479void IFunction::removeConstraint(const std::string &parName) {
480 size_t iPar = parameterIndex(parName);
481 const auto it = std::find_if(m_constraints.cbegin(), m_constraints.cend(),
482 [&iPar](const auto &constraint) { return iPar == constraint->getLocalIndex(); });
483 if (it != m_constraints.cend()) {
484 m_constraints.erase(it);
485 }
486}
487
492void IFunction::setConstraintPenaltyFactor(const std::string &parName, const double &c) {
493 size_t iPar = parameterIndex(parName);
494 const auto it = std::find_if(m_constraints.cbegin(), m_constraints.cend(),
495 [&iPar](const auto &constraint) { return iPar == constraint->getLocalIndex(); });
496
497 if (it != m_constraints.cend()) {
498 (*it)->setPenaltyFactor(c);
499 } else {
500 g_log.warning() << parName << " does not have constraint so setConstraintPenaltyFactor failed"
501 << "\n";
502 }
503}
504
507
509 for (auto &constraint : m_constraints) {
510 constraint->setParamToSatisfyConstraint();
511 }
512}
513
516std::string IFunction::writeConstraints() const {
517 std::ostringstream stream;
518 bool first = true;
519 for (const auto &constrint : m_constraints) {
520 if (constrint->isDefault())
521 continue;
522 if (!first) {
523 stream << ',';
524 } else {
525 first = false;
526 }
527 stream << constrint->asString();
528 }
529 return stream.str();
530}
531
537std::string IFunction::asString() const { return writeToString(); }
538
546std::string IFunction::writeToString(const std::string &parentLocalAttributesStr) const {
547 std::ostringstream ostr;
548 ostr << "name=" << this->name();
549 // print the attributes
550 std::vector<std::string> attr = this->getAttributeNames();
551 for (const auto &attName : attr) {
552 std::string attValue = this->getAttribute(attName).value();
553 if (!attValue.empty() && attValue != "\"\"") {
554 ostr << ',' << attName << '=' << attValue;
555 }
556 }
557 std::vector<std::string> ties;
558 // print the parameters
559 for (size_t i = 0; i < nParams(); i++) {
560 std::ostringstream paramOut;
561 paramOut << parameterName(i) << '=' << getParameter(i);
562 ostr << ',' << paramOut.str();
563 // Output non-default ties only.
564 if (getParameterStatus(i) == Fixed) {
565 ties.emplace_back(paramOut.str());
566 }
567 }
568
569 // collect non-default constraints
570 std::string constraints = writeConstraints();
571 // print constraints
572 if (!constraints.empty()) {
573 ostr << ",constraints=(" << constraints << ")";
574 }
575
576 // collect the non-default ties
577 auto tiesString = writeTies();
578 if (!tiesString.empty()) {
579 ties.emplace_back(tiesString);
580 }
581 // print the ties
582 if (!ties.empty()) {
583 ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",") << ")";
584 }
585 // "local" attributes of a parent composite function
586 ostr << parentLocalAttributesStr;
587 return ostr.str();
588}
589
596void IFunction::addConstraints(const std::string &str, bool isDefault) {
597 Expression list;
598 list.parse(str);
599 list.toList();
600 for (auto it = list.begin(); it != list.end(); ++it) {
601 auto expr = (*it);
602 if (expr.terms()[0].str().compare("penalty") == 0) {
603 continue;
604 }
605 if ((it + 1) != list.end()) {
606 auto next_expr = *(it + 1);
607 if (next_expr.terms()[0].str().compare("penalty") == 0) {
608 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
609 double penalty_factor = std::stof(next_expr.terms()[1].str(), NULL);
610 c->setPenaltyFactor(penalty_factor);
611 this->addConstraint(std::move(c));
612 } else {
613 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
614 this->addConstraint(std::move(c));
615 }
616 } else {
617 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
618 this->addConstraint(std::move(c));
619 }
620 }
621}
622
626std::vector<std::string> IFunction::getParameterNames() const {
627 std::vector<std::string> out;
628 for (size_t i = 0; i < nParams(); ++i) {
629 out.emplace_back(parameterName(i));
630 }
631 return out;
632}
633
637void IFunction::setHandler(std::unique_ptr<FunctionHandler> handler) {
638 if (handler && handler->function().get() != this) {
639 throw std::runtime_error("Function handler points to a different function");
640 }
641
642 m_handler = std::move(handler);
643 m_handler->init();
644}
645
653
659std::ostream &operator<<(std::ostream &ostr, const IFunction &f) {
660 ostr << f.asString();
661 return ostr;
662}
663
664namespace {
668class AttType : public IFunction::ConstAttributeVisitor<std::string> {
669protected:
671 std::string apply(const std::string & /*str*/) const override { return "std::string"; }
673 std::string apply(const int & /*i*/) const override { return "int"; }
675 std::string apply(const double & /*d*/) const override { return "double"; }
677 std::string apply(const bool & /*i*/) const override { return "bool"; }
679 std::string apply(const std::vector<double> & /*unused*/) const override { return "std::vector<double>"; }
680};
681} // namespace
682
683std::string IFunction::Attribute::type() const {
684 AttType tmp;
685 return apply(tmp);
686}
687
688namespace {
692class AttValue : public IFunction::ConstAttributeVisitor<std::string> {
693public:
694 explicit AttValue(bool quoteString = false)
695 : IFunction::ConstAttributeVisitor<std::string>(), m_quoteString(quoteString) {}
696
697protected:
699 std::string apply(const std::string &str) const override {
700 return (m_quoteString) ? std::string("\"" + str + "\"") : str;
701 }
703 std::string apply(const int &i) const override { return std::to_string(i); }
705 std::string apply(const double &d) const override { return boost::lexical_cast<std::string>(d); }
707 std::string apply(const bool &b) const override { return b ? "true" : "false"; }
709 std::string apply(const std::vector<double> &v) const override {
710 std::string res = "(";
711 if (!v.empty()) {
712 for (size_t i = 0; i < v.size() - 1; ++i) {
713 res += boost::lexical_cast<std::string>(v[i]) + ",";
714 }
715 res += boost::lexical_cast<std::string>(v.back());
716 }
717 res += ")";
718 return res;
719 }
720
721private:
724};
725} // namespace
726
727std::string IFunction::Attribute::value() const {
728 AttValue tmp(m_quoteValue);
729 return apply(tmp);
730}
731
736 if (m_quoteValue)
737 return asQuotedString();
738
739 try {
740 return boost::get<std::string>(m_data);
741 } catch (...) {
742 throw std::runtime_error("Trying to access a " + type() +
743 " attribute "
744 "as string");
745 }
746}
747
752 std::string attr;
753
754 try {
755 attr = boost::get<std::string>(m_data);
756 } catch (...) {
757 throw std::runtime_error("Trying to access a " + type() +
758 " attribute "
759 "as string");
760 }
761
762 if (attr.empty())
763 return "\"\"";
764
765 std::string quoted(attr);
766 if (*(attr.begin()) != '\"')
767 quoted = "\"" + attr;
768 if (*(quoted.end() - 1) != '\"')
769 quoted += "\"";
770
771 return quoted;
772}
773
778 std::string attr;
779
780 try {
781 attr = boost::get<std::string>(m_data);
782 } catch (...) {
783 throw std::runtime_error("Trying to access a " + type() +
784 " attribute "
785 "as string");
786 }
787 std::string unquoted(attr);
788 if (attr.empty())
789 return "";
790 if (*(attr.begin()) == '\"')
791 unquoted = std::string(attr.begin() + 1, attr.end() - 1);
792 if (*(unquoted.end() - 1) == '\"')
793 unquoted.resize(unquoted.size() - 1);
794
795 return unquoted;
796}
797
802 try {
803 return boost::get<int>(m_data);
804 } catch (...) {
805 throw std::runtime_error("Trying to access a " + type() +
806 " attribute "
807 "as int");
808 }
809}
810
815 try {
816 return boost::get<double>(m_data);
817 } catch (...) {
818 throw std::runtime_error("Trying to access a " + type() +
819 " attribute "
820 "as double");
821 }
822}
823
828 try {
829 return boost::get<bool>(m_data);
830 } catch (...) {
831 throw std::runtime_error("Trying to access a " + type() +
832 " attribute "
833 "as bool");
834 }
835}
836
840std::vector<double> IFunction::Attribute::asVector() const {
841 try {
842 return boost::get<std::vector<double>>(m_data);
843 } catch (...) {
844 throw std::runtime_error("Trying to access a " + type() +
845 " attribute "
846 "as vector");
847 }
848}
849
854void IFunction::Attribute::setString(const std::string &str) {
855 evaluateValidator(str);
856
857 try {
858 boost::get<std::string>(m_data) = str;
859 } catch (...) {
860 throw std::runtime_error("Trying to access a " + type() +
861 " attribute "
862 "as string");
863 }
864}
865
871 evaluateValidator(d);
872
873 try {
874 boost::get<double>(m_data) = d;
875 } catch (...) {
876 throw std::runtime_error("Trying to access a " + type() +
877 " attribute "
878 "as double");
879 }
880}
881
887 evaluateValidator(i);
888
889 try {
890 boost::get<int>(m_data) = i;
891 } catch (...) {
892 throw std::runtime_error("Trying to access a " + type() +
893 " attribute "
894 "as int");
895 }
896}
897
902void IFunction::Attribute::setBool(const bool &b) {
903 evaluateValidator(b);
904
905 try {
906 boost::get<bool>(m_data) = b;
907 } catch (...) {
908 throw std::runtime_error("Trying to access a " + type() +
909 " attribute "
910 "as bool");
911 }
912}
913
919void IFunction::Attribute::setVector(const std::vector<double> &v) {
920 evaluateValidator(v);
921
922 try {
923 auto &data = boost::get<std::vector<double>>(m_data);
924 data.assign(v.begin(), v.end());
925 } catch (...) {
926 throw std::runtime_error("Trying to access a " + type() +
927 " attribute "
928 "as vector");
929 }
930}
931
934 try {
935 return boost::get<std::string>(m_data).empty();
936 } catch (...) {
937 throw std::runtime_error("Trying to access a " + type() + " attribute as string");
938 }
939}
940
941namespace {
945class SetValue : public IFunction::AttributeVisitor<> {
946public:
952 explicit SetValue(std::string value, Mantid::Kernel::IValidator_sptr validator = Mantid::Kernel::IValidator_sptr())
953 : m_value(std::move(value)), m_validator(validator) {}
954
955protected:
957 void apply(std::string &str) const override {
958 evaluateValidator(m_value);
959 str = m_value;
960 }
962 void apply(int &i) const override {
963 int tempi = 0;
964
965 std::istringstream istr(m_value + " ");
966 istr >> tempi;
967 if (!istr.good())
968 throw std::invalid_argument("Failed to set int attribute "
969 "from string " +
970 m_value);
971
972 evaluateValidator(tempi);
973 i = tempi;
974 }
976 void apply(double &d) const override {
977 double tempd = 0;
978
979 std::istringstream istr(m_value + " ");
980 istr >> tempd;
981 if (!istr.good())
982 throw std::invalid_argument("Failed to set double attribute "
983 "from string " +
984 m_value);
985
986 evaluateValidator(tempd);
987 d = tempd;
988 }
990 void apply(bool &b) const override {
991 bool tempb = false;
992
993 tempb = (m_value == "true" || m_value == "TRUE" || m_value == "1");
994 evaluateValidator(tempb);
995
996 b = (m_value == "true" || m_value == "TRUE" || m_value == "1");
997 }
999 void apply(std::vector<double> &v) const override {
1000 if (m_value.empty() || m_value == "EMPTY") {
1001 v.clear();
1002 return;
1003 }
1004 if (m_value.size() > 2) {
1005 // check if the value is in brackets (...)
1006 if (m_value.front() == '(' && m_value.back() == ')') {
1007 m_value.erase(0, 1);
1008 m_value.erase(m_value.size() - 1);
1009 }
1010 }
1011 Kernel::StringTokenizer tokenizer(m_value, ",", Kernel::StringTokenizer::TOK_TRIM);
1012 size_t newSize = tokenizer.count();
1013
1014 // if visitor has an associated validator, first populate temp vec and evaluate against validator.
1015 if (m_validator != nullptr) {
1016 std::vector<double> tempVec(newSize);
1017
1018 for (size_t i = 0; i < tempVec.size(); ++i) {
1019 tempVec[i] = boost::lexical_cast<double>(tokenizer[i]);
1020 }
1021 evaluateValidator(tempVec);
1022 }
1023
1024 v.resize(newSize);
1025 for (size_t i = 0; i < v.size(); ++i) {
1026 v[i] = boost::lexical_cast<double>(tokenizer[i]);
1027 }
1028 }
1029
1031 template <typename T> void evaluateValidator(T &inputData) const {
1032 if (m_validator != nullptr) {
1033 IFunction::ValidatorEvaluator::evaluate(inputData, m_validator);
1034 }
1035 }
1036
1037private:
1038 mutable std::string m_value;
1039 mutable Kernel::IValidator_sptr m_validator;
1040};
1041} // namespace
1042
1046void IFunction::Attribute::fromString(const std::string &str) {
1047 SetValue tmp(str, m_validator);
1048 apply(tmp);
1049}
1050
1055
1060
1063double IFunction::activeParameter(size_t i) const {
1064 if (!isActive(i)) {
1065 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1066 }
1067 return getParameter(i);
1068}
1069
1072void IFunction::setActiveParameter(size_t i, double value) {
1073 if (!isActive(i)) {
1074 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1075 }
1076 setParameter(i, value);
1077}
1078
1083std::string IFunction::nameOfActive(size_t i) const {
1084 if (!isActive(i)) {
1085 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1086 }
1087 return parameterName(i);
1088}
1089
1094std::string IFunction::descriptionOfActive(size_t i) const {
1095 if (!isActive(i)) {
1096 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1097 }
1098 return parameterDescription(i);
1099}
1100
1107 /*
1108 * There is a similar more specialized method for 1D functions in IFunction1D
1109 * but the method takes different parameters and uses slightly different
1110 * function calls in places making it difficult to share code. Please also
1111 * consider that method when updating this.
1112 */
1113
1114 const size_t nParam = nParams();
1115 size_t nData = getValuesSize(domain);
1116
1117 FunctionValues minusStep(nData);
1118 FunctionValues plusStep(nData);
1119
1120 applyTies(); // just in case
1121 function(domain, minusStep);
1122
1123 if (nData == 0) {
1124 nData = minusStep.size();
1125 }
1126
1127 double step;
1128 for (size_t iP = 0; iP < nParam; iP++) {
1129 if (isActive(iP)) {
1130 const double val = activeParameter(iP);
1131 step = calculateStepSize(val);
1132
1133 const double paramPstep = val + step;
1134 setActiveParameter(iP, paramPstep);
1135 applyTies();
1136 function(domain, plusStep);
1137 setActiveParameter(iP, val);
1138 applyTies();
1139
1140 step = paramPstep - val;
1141 for (size_t i = 0; i < nData; i++) {
1142 jacobian.set(i, iP, (plusStep.getCalculated(i) - minusStep.getCalculated(i)) / step);
1143 }
1144 }
1145 }
1146}
1147
1152double IFunction::calculateStepSize(const double parameterValue) const { return m_stepSizeFunction(parameterValue); }
1153
1158 switch (method) {
1160 m_stepSizeFunction = defaultStepSize;
1161 return;
1163 m_stepSizeFunction = sqrtEpsilonStepSize;
1164 return;
1165 }
1166 throw std::invalid_argument("An invalid method for calculating the step size was provided.");
1167}
1168
1175void IFunction::setMatrixWorkspace(std::shared_ptr<const API::MatrixWorkspace> workspace, size_t wi, double startX,
1176 double endX) {
1177 UNUSED_ARG(startX);
1178 UNUSED_ARG(endX);
1179
1180 if (!workspace)
1181 return; // unset the workspace
1182
1183 try {
1184
1185 // check if parameter are specified in instrument definition file
1186
1187 const auto &paramMap = workspace->constInstrumentParameters();
1188
1189 Geometry::IDetector const *detectorPtr = nullptr;
1190 size_t numDetectors = workspace->getSpectrum(wi).getDetectorIDs().size();
1191 if (numDetectors > 1) {
1192 // If several detectors are on this workspace index, just use the ID of
1193 // the first detector
1194 // Note JZ oct 2011 - I'm not sure why the code uses the first detector
1195 // and not the group. Ask Roman.
1196 auto firstDetectorId = *workspace->getSpectrum(wi).getDetectorIDs().begin();
1197
1198 const auto &detectorInfo = workspace->detectorInfo();
1199 const auto detectorIndex = detectorInfo.indexOf(firstDetectorId);
1200 const auto &detector = detectorInfo.detector(detectorIndex);
1201 detectorPtr = &detector;
1202 } else {
1203 // Get the detector (single) at this workspace index
1204 const auto &spectrumInfo = workspace->spectrumInfo();
1205 const auto &detector = spectrumInfo.detector(wi);
1206 detectorPtr = &detector;
1207 }
1208
1209 for (size_t i = 0; i < nParams(); i++) {
1210 if (!isExplicitlySet(i)) {
1211 Geometry::Parameter_sptr param = paramMap.getRecursive(detectorPtr, parameterName(i), "fitting");
1212 if (param != Geometry::Parameter_sptr()) {
1213 // get FitParameter
1214 const auto &fitParam = param->value<Geometry::FitParameter>();
1215
1216 // check first if this parameter is actually specified for this
1217 // function
1218 if (name() == fitParam.getFunction()) {
1219 // update value
1220 const auto *testWithLocation = dynamic_cast<IFunctionWithLocation *>(this);
1221 if (testWithLocation == nullptr ||
1222 (!fitParam.getLookUpTable().containData() && fitParam.getFormula().empty())) {
1223 setParameter(i, fitParam.getValue());
1224 } else {
1225 double centreValue = testWithLocation->centre();
1226 Kernel::Unit_sptr centreUnit; // unit of value used in formula or
1227 // to look up value in lookup table
1228 if (fitParam.getFormula().empty())
1229 centreUnit = fitParam.getLookUpTable().getXUnit(); // from table
1230 else {
1231 if (!fitParam.getFormulaUnit().empty()) {
1232 try {
1233 centreUnit = Kernel::UnitFactory::Instance().create(fitParam.getFormulaUnit()); // from formula
1234 } catch (...) {
1235 g_log.warning() << fitParam.getFormulaUnit() << " Is not an recognised formula unit for parameter "
1236 << fitParam.getName() << "\n";
1237 }
1238 }
1239 }
1240
1241 // if unit specified convert centre value to unit required by
1242 // formula or look-up-table
1243 if (centreUnit) {
1244 g_log.debug() << "For FitParameter " << parameterName(i)
1245 << " centre of peak before any unit conversion is " << centreValue << '\n';
1246 centreValue = convertValue(centreValue, centreUnit, workspace, wi);
1247 g_log.debug() << "For FitParameter " << parameterName(i)
1248 << " centre of peak after any unit conversion is " << centreValue << '\n';
1249 }
1250
1251 double paramValue = fitParam.getValue(centreValue);
1252
1253 // this returned param value by a formula or a look-up-table may
1254 // have
1255 // a unit of its own. If set convert param value
1256 // See section 'Using fitting parameters in
1257 // docs/source/concepts/InstrumentDefinitionFile.rst
1258 if (fitParam.getFormula().empty()) {
1259 // so from look up table
1260 Kernel::Unit_sptr resultUnit = fitParam.getLookUpTable().getYUnit(); // from table
1261 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1262 << " before y-unit conversion\n";
1263 paramValue /= convertValue(1.0, resultUnit, workspace, wi);
1264 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1265 << " after y-unit conversion\n";
1266 } else {
1267 // so from formula
1268
1269 std::string resultUnitStr = fitParam.getResultUnit();
1270
1271 if (!resultUnitStr.empty()) {
1272 std::vector<std::string> allUnitStr = Kernel::UnitFactory::Instance().getKeys();
1273 for (auto &iUnit : allUnitStr) {
1274 size_t found = resultUnitStr.find(iUnit);
1275 if (found != std::string::npos) {
1276 size_t len = iUnit.size();
1277 std::stringstream readDouble;
1278 Kernel::Unit_sptr unt = Kernel::UnitFactory::Instance().create(iUnit);
1279 readDouble << 1.0 / convertValue(1.0, unt, workspace, wi);
1280 resultUnitStr.replace(found, len, readDouble.str());
1281 }
1282 } // end for
1283
1284 try {
1285 mu::Parser p;
1286 p.SetExpr(resultUnitStr);
1287 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1288 << " before result-unit conversion (using " << resultUnitStr << ")\n";
1289 paramValue *= p.Eval();
1290 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1291 << " after result-unit conversion\n";
1292 } catch (mu::Parser::exception_type &e) {
1293 g_log.error() << "Cannot convert formula unit to workspace unit"
1294 << " Formula unit which cannot be passed is " << resultUnitStr
1295 << ". Muparser error message is: " << e.GetMsg() << '\n';
1296 }
1297 } // end if
1298 } // end trying to convert result-unit from formula or y-unit for
1299 // lookuptable
1300
1301 setParameter(i, paramValue);
1302 } // end of update parameter value
1303
1304 // add tie if specified for this parameter in instrument definition
1305 // file
1306 if (!fitParam.getTie().empty()) {
1307 std::ostringstream str;
1308 str << getParameter(i);
1309 tie(parameterName(i), str.str());
1310 }
1311
1312 // add constraint if specified for this parameter in instrument
1313 // definition file
1314 if (!fitParam.getConstraint().empty()) {
1315 IConstraint *constraint = ConstraintFactory::Instance().createInitialized(this, fitParam.getConstraint());
1316 if (!fitParam.getConstraintPenaltyFactor().empty()) {
1317 try {
1318 double penalty = std::stod(fitParam.getConstraintPenaltyFactor());
1319 constraint->setPenaltyFactor(penalty);
1320 } catch (...) {
1321 g_log.warning() << "Can't set penalty factor for constraint\n";
1322 }
1323 }
1324 addConstraint(std::unique_ptr<IConstraint>(constraint));
1325 }
1326 }
1327 }
1328 }
1329 }
1330 } catch (...) {
1331 }
1332}
1333
1343 const std::shared_ptr<const MatrixWorkspace> &ws, size_t wsIndex) const {
1344 // only required if formula or look-up-table different from ws unit
1345 const auto &wsUnit = ws->getAxis(0)->unit();
1346 if (outUnit->unitID() == wsUnit->unitID())
1347 return value;
1348
1349 // first check if it is possible to do a quick conversion and convert
1350 // slight duplication to below to avoid instantiating vector unless necessary
1351 double factor(0.0), power(0.0);
1352 if (wsUnit->quickConversion(*outUnit, factor, power)) {
1353 return factor * std::pow(value, power);
1354 } else {
1355 std::vector<double> singleValue(1, value);
1356 convertValue(singleValue, outUnit, ws, wsIndex);
1357 return singleValue.front();
1358 }
1359}
1360
1369void IFunction::convertValue(std::vector<double> &values, Kernel::Unit_sptr &outUnit,
1370 const std::shared_ptr<const MatrixWorkspace> &ws, size_t wsIndex) const {
1371 // only required if formula or look-up-table different from ws unit
1372 const auto &wsUnit = ws->getAxis(0)->unit();
1373 if (outUnit->unitID() == wsUnit->unitID())
1374 return;
1375
1376 // first check if it is possible to do a quick conversion convert
1377 double factor, power;
1378 if (wsUnit->quickConversion(*outUnit, factor, power)) {
1379 auto iend = values.end();
1380 for (auto itr = values.begin(); itr != iend; ++itr)
1381 (*itr) = factor * std::pow(*itr, power);
1382 } else {
1383 // Get l1, l2 and theta (see also RemoveBins.calculateDetectorPosition())
1384 Instrument_const_sptr instrument = ws->getInstrument();
1385 Geometry::IComponent_const_sptr sample = instrument->getSample();
1386 if (sample == nullptr) {
1387 g_log.error() << "No sample defined instrument. Cannot convert units for function\n"
1388 << "Ignore conversion.";
1389 return;
1390 }
1391 const auto &spectrumInfo = ws->spectrumInfo();
1392 double l1 = spectrumInfo.l1();
1393 // If this is a monitor then l1+l2 = source-detector distance and twoTheta=0
1394 auto emode = ws->getEMode();
1395
1397 spectrumInfo.getDetectorValues(*wsUnit, *outUnit, emode, false, wsIndex, pmap);
1398 try {
1399 std::vector<double> emptyVec;
1400 wsUnit->toTOF(values, emptyVec, l1, emode, pmap);
1401 outUnit->fromTOF(values, emptyVec, l1, emode, pmap);
1402 } catch (std::exception &) {
1403 throw std::runtime_error("Unable to perform unit conversion to " + outUnit->unitID());
1404 }
1405 }
1406}
1407
1411size_t IFunction::nAttributes() const { return m_attrs.size(); }
1412
1414bool IFunction::hasAttribute(const std::string &name) const { return m_attrs.find(name) != m_attrs.end(); }
1415
1421void IFunction::setAttributeValue(const std::string &attName, const char *value) {
1422 std::string str(value);
1423 setAttributeValue(attName, str);
1424}
1425
1431void IFunction::setAttributeValue(const std::string &attName, const std::string &value) {
1432 Attribute att = getAttribute(attName);
1433 att.setString(value);
1434 setAttribute(attName, att);
1435}
1436
1439 throw std::runtime_error("Function " + name() + " doesn't have children.");
1440}
1441
1443std::vector<std::string> IFunction::getAttributeNames() const {
1444 std::vector<std::string> names;
1445 names.reserve(nAttributes());
1446 for (size_t i = 0; i < nAttributes(); ++i) {
1447 names.emplace_back(attributeName(i));
1448 }
1449 return names;
1450}
1451
1457std::string IFunction::attributeName(size_t index) const {
1458 if (index >= nAttributes()) {
1459 throw std::out_of_range("Function attribute index out of range.");
1460 }
1461 auto itr = std::next(m_attrs.begin(), index);
1462 return itr->first;
1463}
1464
1470 if (hasAttribute(name)) {
1471 return m_attrs.at(name);
1472 } else {
1473 throw std::invalid_argument("ParamFunctionAttributeHolder::getAttribute - Unknown attribute '" + name + "'");
1474 }
1475}
1476
1487
1493void IFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue) {
1495
1496 m_attrs.emplace(name, defaultValue);
1497}
1498
1505void IFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue,
1506 const Kernel::IValidator &validator) {
1507 const Kernel::IValidator_sptr validatorClone = validator.clone();
1509
1510 defaultValue.setValidator(validatorClone);
1511 defaultValue.evaluateValidator();
1512
1513 m_attrs.emplace(name, defaultValue);
1514}
1515
1520void IFunction::checkAttributeName(const std::string &name) {
1521 if (m_attrs.find(name) != m_attrs.end()) {
1522 std::ostringstream msg;
1523 msg << "Attribute (" << name << ") already exists.";
1524 throw std::invalid_argument(msg.str());
1525 }
1526}
1527
1533
1540 if (hasAttribute(name)) {
1541 auto att = m_attrs[name];
1542 const Kernel::IValidator_sptr validatorClone = att.getValidator();
1543 value.setValidator(validatorClone);
1544 value.evaluateValidator();
1545
1546 m_attrs[name] = value;
1547 } else {
1548 throw std::invalid_argument("ParamFunctionAttributeHolder::setAttribute - Unknown attribute '" + name + "'");
1549 }
1550}
1551
1559 const_cast<IFunction *>(this)->storeAttributeValue(name, value);
1560}
1561
1571void IFunction::setCovarianceMatrix(const std::shared_ptr<Kernel::Matrix<double>> &covar) {
1572 // the matrix shouldn't be empty
1573 if (!covar) {
1574 throw std::invalid_argument("IFunction: Cannot set an empty covariance matrix");
1575 }
1576 // the matrix should relate to this function
1577 if (covar->numRows() != nParams() || covar->numCols() != nParams()) {
1578 throw std::invalid_argument("IFunction: Covariance matrix has a wrong size");
1579 }
1580 m_covar = covar;
1581}
1582
1585size_t IFunction::getValuesSize(const FunctionDomain &domain) const { return domain.size(); }
1586
1590void IFunction::fixParameter(const std::string &name, bool isDefault) {
1591 auto i = parameterIndex(name);
1592 fix(i, isDefault);
1593}
1594
1597void IFunction::unfixParameter(const std::string &name) {
1598 auto i = parameterIndex(name);
1599 unfix(i);
1600}
1601
1604void IFunction::fixAll(bool isDefault) {
1605 for (size_t i = 0; i < nParams(); ++i) {
1606 if (isActive(i)) {
1607 fix(i, isDefault);
1608 }
1609 }
1610}
1611
1614 for (size_t i = 0; i < nParams(); ++i) {
1615 if (isFixed(i)) {
1616 unfix(i);
1617 }
1618 }
1619}
1620
1623 for (size_t i = 0; i < nParams(); ++i) {
1625 unfix(i);
1626 }
1627 }
1628}
1629
1635void IFunction::fixAllActive(bool isDefault) {
1636 for (size_t i = 0; i < nParams(); ++i) {
1637 if (getParameterStatus(i) == Active) {
1638 fix(i, isDefault);
1639 }
1640 }
1641}
1642
1647size_t IFunction::getNumberDomains() const { return 1; }
1648
1654std::vector<IFunction_sptr> IFunction::createEquivalentFunctions() const {
1655 return std::vector<IFunction_sptr>(1, FunctionFactory::Instance().createInitialized(asString()));
1656}
1657
1661void IFunction::sortTies(const bool checkOnly) {
1662 if (!checkOnly) {
1663 m_orderedTies.clear();
1664 }
1665
1666 std::list<TieNode> orderedTieNodes;
1667 for (size_t i = 0; i < nParams(); ++i) {
1668 auto const parTie = getTie(i);
1669 if (!parTie || ignoreTie(*parTie)) {
1670 continue;
1671 }
1672
1673 TieNode newNode;
1674 newNode.left = getParameterIndex(*parTie);
1675 auto const rhsParameters = parTie->getRHSParameters();
1676 newNode.right.reserve(rhsParameters.size());
1677 for (auto &&p : rhsParameters) {
1678 newNode.right.emplace_back(this->getParameterIndex(p));
1679 }
1680 if (newNode < newNode) {
1681 throw std::runtime_error("Parameter is tied to itself: " + parTie->asString(this));
1682 }
1683 bool before(false), after(false);
1684 size_t indexBefore(0), indexAfter(0);
1685 for (auto &&node : orderedTieNodes) {
1686 if (newNode < node) {
1687 before = true;
1688 indexBefore = node.left;
1689 }
1690 if (node < newNode) {
1691 after = true;
1692 indexAfter = node.left;
1693 }
1694 }
1695 if (before) {
1696 if (after) {
1697 std::string message = "Circular dependency in ties:\n" + parTie->asString(this) + '\n';
1698 message += getTie(indexBefore)->asString(this);
1699 if (indexAfter != indexBefore) {
1700 message += '\n' + getTie(indexAfter)->asString(this);
1701 }
1702 throw std::runtime_error(message);
1703 }
1704 orderedTieNodes.push_front(newNode);
1705 } else {
1706 orderedTieNodes.emplace_back(newNode);
1707 }
1708 }
1709 if (!checkOnly) {
1710 for (auto &&node : orderedTieNodes) {
1711 auto const parTie = getTie(node.left);
1712 m_orderedTies.emplace_back(parTie);
1713 }
1714 }
1715}
1716
1717} // namespace Mantid::API
1718
1720namespace Mantid::Kernel {
1721
1722template <>
1723MANTID_API_DLL std::shared_ptr<Mantid::API::IFunction>
1724IPropertyManager::getValue<std::shared_ptr<Mantid::API::IFunction>>(const std::string &name) const {
1725 auto *prop = dynamic_cast<PropertyWithValue<std::shared_ptr<Mantid::API::IFunction>> *>(getPointerToProperty(name));
1726 if (prop) {
1727 return *prop;
1728 } else {
1729 std::string message = "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<IFunction>.";
1730 throw std::runtime_error(message);
1731 }
1732}
1733
1734template <>
1735MANTID_API_DLL std::shared_ptr<const Mantid::API::IFunction>
1736IPropertyManager::getValue<std::shared_ptr<const Mantid::API::IFunction>>(const std::string &name) const {
1737 const auto *prop =
1738 dynamic_cast<PropertyWithValue<std::shared_ptr<Mantid::API::IFunction>> *>(getPointerToProperty(name));
1739 if (prop) {
1740 return prop->operator()();
1741 } else {
1742 std::string message =
1743 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<IFunction>.";
1744 throw std::runtime_error(message);
1745 }
1746}
1747
1748} // namespace Mantid::Kernel
const std::string & m_value
Definition Algorithm.cpp:71
Kernel::IValidator_sptr m_validator
bool m_quoteString
Flag to quote a string value returned.
std::string name
Definition Run.cpp:60
gsl_vector * tmp
double value
The value of the point.
Definition FitMW.cpp:51
double error
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
const double EPSILON(1.0E-10)
double left
double right
IntArray detectorIndex
#define fabs(x)
Definition Matrix.cpp:22
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Definition System.h:48
const std::vector< Type > & m_data
This class represents an expression made up of names, binary operators and brackets.
Definition Expression.h:36
void parse(const std::string &str)
Parse a string and create an expression.
iterator end() const
An iterator pointing to the end of the expressions.
Definition Expression.h:86
iterator begin() const
An iterator pointing to the start of the expressions.
Definition Expression.h:84
void toList(const std::string &sep=",")
Make sure the expression is a list of expression separated by sep, eg "term1,term2,...
Base class that represents the domain of a function.
virtual size_t size() const =0
Return the number of points in the domain.
A class to store values calculated by a function.
size_t size() const
Return the number of values.
double getCalculated(size_t i) const
Get i-th calculated value.
An interface to a constraint.
Definition IConstraint.h:26
virtual void setPenaltyFactor(const double &c)=0
set the penalty factor for the constraint Set panelty factor.
An interface to a function with location, which here means a function for which the user may ask what...
Atribute validator visitor class.
Definition IFunction.h:380
Attribute is a non-fitting parameter.
Definition IFunction.h:285
std::string asUnquotedString() const
Returns a string value that is guarenteed to be unquoted.
void setString(const std::string &str)
Sets new value if attribute is a string.
std::vector< double > asVector() const
Returns vector<double> if attribute is vector<double>, throws exception otherwise.
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
void evaluateValidator() const
Evaluates the validator associated with this attribute. Returns error as a string.
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
void setVector(const std::vector< double > &)
Sets new value if attribute is a vector.
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Definition IFunction.h:303
void setDouble(const double &)
Sets new value if attribute is a double.
std::string asQuotedString() const
Returns a string value that is guarenteed to be quoted for use in places where the string is used as ...
void setValidator(const Kernel::IValidator_sptr &validator) const
Set validator to enforce limits on attribute value.
std::string value() const
Returns the attribute value as a string.
void setBool(const bool &)
Sets new value if attribute is a bool.
void fromString(const std::string &str)
Set value from a string.
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
bool isEmpty() const
Check if a string attribute is empty.
void setInt(const int &)
Sets new value if attribute is a int.
bool asBool() const
Returns bool value if attribute is a bool, throws exception otherwise.
std::string type() const
Returns type of the attribute.
Const version of AttributeVisitor.
Definition IFunction.h:244
This is an interface to a fitting function - a semi-abstarct class.
Definition IFunction.h:166
virtual void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Derivatives of function with respect to active parameters.
bool hasOrderedTies() const
virtual std::string descriptionOfActive(size_t i) const
Returns the name of active parameter i.
virtual size_t nParams() const =0
Total number of parameters.
void sortTies(const bool checkOnly=false)
Put all ties in order in which they will be applied correctly.
std::function< double(const double)> m_stepSizeFunction
The function used to calculate the step size.
Definition IFunction.h:733
virtual void removeConstraint(const std::string &parName)
Remove a constraint.
bool isActive(size_t i) const
Check if an active parameter i is actually active.
std::string writeTies() const
Write a parameter tie to a string.
void unfixParameter(const std::string &name)
Free a parameter.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
void setProgressReporter(std::shared_ptr< Kernel::ProgressBase > reporter)
Attach a progress reporter.
virtual double getParameter(size_t i) const =0
Get i-th parameter.
double convertValue(double value, Kernel::Unit_sptr &outUnit, const std::shared_ptr< const MatrixWorkspace > &ws, size_t wsIndex) const
Convert a value from one unit (inUnit) to unit defined in workspace (ws)
virtual void clearTies()
Remove all ties.
virtual void clearConstraints()
Remove all constraints.
virtual ~IFunction()
Virtual destructor.
Definition IFunction.cpp:92
double calculateStepSize(const double parameterValue) const
Calculate step size for the given parameter value.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
virtual std::shared_ptr< IFunction > clone() const
Virtual copy constructor.
void setHandler(std::unique_ptr< FunctionHandler > handler)
Set a function handler.
void storeReadOnlyAttribute(const std::string &name, const API::IFunction::Attribute &value) const
A read-only ("mutable") attribute can be stored in a const method.
virtual void tie(const std::string &parName, const std::string &expr, bool isDefault=false)
Tie a parameter to other parameters (or a constant)
std::map< std::string, API::IFunction::Attribute > m_attrs
The declared attributes.
Definition IFunction.h:719
virtual void declareAttributes()
Override to declare function attributes.
Definition IFunction.h:681
virtual ParameterStatus getParameterStatus(size_t i) const =0
Get status of parameter.
virtual void setMatrixWorkspace(std::shared_ptr< const API::MatrixWorkspace > workspace, size_t wi, double startX, double endX)
Set matrix workspace.
virtual void setParameter(size_t, const double &value, bool explicitlySet=true)=0
Set i-th parameter.
virtual void applyTies()
Apply the ties.
void checkAttributeName(const std::string &name)
Check Attribute to declare does not already exist.
virtual ParameterTie * getTie(size_t i) const
Get the tie of i-th parameter.
virtual void setStepSizeMethod(const StepSizeMethod method)
Sets the StepSizeMethod to use when calculation the step size.
virtual const std::string category() const
The categories the Fit function belong to.
Definition IFunction.h:443
virtual const std::string categorySeparator() const
Function to return the sperator token for the category string.
Definition IFunction.h:448
virtual std::string writeToString(const std::string &parentLocalAttributesStr="") const
Writes itself into a string.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
void unfixAllDefault()
Free all parameters fixed by default.
virtual size_t getValuesSize(const FunctionDomain &domain) const
Get number of values for a given domain.
virtual std::string nameOfActive(size_t i) const
Returns the name of active parameter i.
void fixAllActive(bool isDefault=false)
Fix all active parameters.
bool cancellationRequestReceived() const
Returns true if a progress reporter is set & evalaution has been requested to stop.
virtual double activeParameter(size_t i) const
Value of i-th active parameter.
virtual size_t getParameterIndex(const ParameterReference &ref) const =0
Return parameter index from a parameter reference.
std::pair< std::size_t, std::string > insertTie(std::unique_ptr< ParameterTie > tie)
Insert a new tie to the correct position.
virtual void setUpForFit()
Set up the function for a fit.
virtual const std::vector< std::string > categories() const
Function to return all of the categories that contain this algorithm.
virtual std::string parameterDescription(size_t i) const =0
Returns the description of parameter i.
void fixParameter(const std::string &name, bool isDefault=false)
Fix a parameter.
virtual std::vector< std::string > getAttributeNames() const
Returns a list of attribute names.
virtual std::string attributeName(size_t index) const
Get name of ith attribute.
void reportProgress(const std::string &msg="") const
Reports progress with an optional message.
virtual void setConstraintPenaltyFactor(const std::string &parName, const double &c)
Set a constraint penalty.
std::vector< ParameterTie * > m_orderedTies
Ties ordered in order of correct application.
Definition IFunction.h:729
virtual void addTies(const std::string &ties, bool isDefault=false)
Add several ties.
std::string asString() const
Writes itself into a string.
void unfix(size_t i)
Restores a declared parameter i to the active status.
virtual std::string parameterName(size_t i) const =0
Returns the name of parameter i.
virtual std::string name() const =0
Returns the function's name.
void setCovarianceMatrix(const std::shared_ptr< Kernel::Matrix< double > > &covar)
Set the covariance matrix.
std::vector< std::unique_ptr< ParameterTie > > m_ties
Holds parameter ties.
Definition IFunction.h:725
void calNumericalDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Calculate numerical derivatives.
std::shared_ptr< Kernel::ProgressBase > m_progReporter
Pointer to the progress handler.
Definition IFunction.h:715
std::vector< std::unique_ptr< IConstraint > > m_constraints
Holds the constraints added to function.
Definition IFunction.h:727
virtual bool hasAttribute(const std::string &name) const
Check if attribute attName exists.
void unfixAll()
Free all parameters.
virtual void setParameterStatus(size_t i, ParameterStatus status)=0
Change status of parameter.
virtual std::shared_ptr< IFunction > getFunction(size_t i) const
Returns the pointer to i-th child function.
virtual void addTie(std::unique_ptr< ParameterTie > tie)
Add a new tie. Derived classes must provide storage for ties.
virtual std::vector< std::shared_ptr< IFunction > > createEquivalentFunctions() const
Split this function (if needed) into a list of independent functions.
virtual void addConstraints(const std::string &str, bool isDefault=false)
Add a list of conatraints from a string.
void fixAll(bool isDefault=false)
Fix all parameters.
virtual void function(const FunctionDomain &domain, FunctionValues &values) const =0
Evaluates the function for all arguments in the domain.
virtual void registerFunctionUsage(bool internal)
Registers the usage of the algorithm with the UsageService.
Definition IFunction.cpp:97
virtual size_t parameterIndex(const std::string &name) const =0
Returns the index of parameter name.
std::string writeConstraints() const
Write a parameter constraint to a string.
void setAttributeValue(const std::string &attName, const T &value)
Set an attribute value.
Definition IFunction.h:601
virtual void removeTie(const std::string &parName)
Removes the tie off a parameter.
virtual double getError(size_t i) const =0
Get the fitting error for a parameter.
void storeAttributeValue(const std::string &name, const API::IFunction::Attribute &value)
Store an attribute's value.
virtual void init()
Function initialization. Declare function parameters in this method.
bool isFixedByDefault(size_t i) const
Check if a parameter i is fixed by default (not by user).
std::unique_ptr< ParameterTie > createAndProcessTie(const std::string &parName, const std::string &expr, bool isDefault)
Creates and processes a single tie, handling constant expressions and validation.
virtual void declareParameters()
Override to declare function parameters.
Definition IFunction.h:683
std::vector< std::string > getParameterNames() const
Return a vector with all parameter names.
virtual bool ignoreTie(const ParameterTie &) const
Ignore a tie.
Definition IFunction.h:561
void fix(size_t i, bool isDefault=false)
Removes a parameter i from the list of active.
bool isFixed(size_t i) const
Check if a parameter i is fixed.
virtual void setActiveParameter(size_t i, double value)
Set new value of i-th active parameter.
virtual void addConstraint(std::unique_ptr< IConstraint > ic)
Add a constraint to function.
virtual size_t nAttributes() const
Returns the number of attributes associated with the function.
virtual bool isExplicitlySet(size_t i) const =0
Checks if a parameter has been set explicitly.
virtual IConstraint * getConstraint(size_t i) const
Get constraint of i-th parameter.
std::unique_ptr< FunctionHandler > m_handler
Pointer to a function handler.
Definition IFunction.h:712
virtual size_t getNumberDomains() const
Get number of domains required by this function.
StepSizeMethod
Describes the method in which the step size will be calculated: DEFAULT: Uses the traditional Mantid ...
Definition IFunction.h:663
bool m_isRegistered
whether the function usage has been registered
Definition IFunction.h:731
std::shared_ptr< Kernel::Matrix< double > > m_covar
The covariance matrix of the fitting parameters.
Definition IFunction.h:721
Represents the Jacobian in IFitFunction::functionDeriv.
Definition Jacobian.h:22
virtual void set(size_t iY, size_t iP, double value)=0
Set a value to a Jacobian matrix element.
Ties fitting parameters.
virtual std::string asString(const IFunction *fun=nullptr) const
Return the string that can be used to recreate this tie.
Used to find ParameterTie for a parameter i.
const IFunction & m_fun
The function that has the tie.
bool operator()(const std::unique_ptr< T > &p)
Bracket operator.
ReferenceEqual(const IFunction &fun, size_t i)
Constructor.
const size_t m_i
index to find
Store information about a fitting parameter such as its value if it is constrained or tied.
Interface class for detector objects.
Definition IDetector.h:43
IValidator is the basic interface for all validators for properties.
Definition IValidator.h:43
virtual IValidator_sptr clone() const =0
Make a copy of the present type of validator.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Numerical Matrix class.
Definition Matrix.h:42
virtual bool hasCancellationBeenRequested() const
Override so that the reporter can inform whether a cancellation request has been used.
The concrete, templated class for properties.
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
const TokenVec & asVector()
Returns a vector of tokenized strings.
std::size_t count() const
Get the total number of tokens.
MANTID_API_DLL std::ostream & operator<<(std::ostream &, const AlgorithmHistory &)
Prints a text representation.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
Definition IFunction.h:743
Mantid::Kernel::StringTokenizer tokenizer
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition Parameter.h:194
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition IComponent.h:167
bool operator<(const TrackDirection left, const TrackDirection right)
Definition Track.h:93
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, typename std::enable_if<!(std::is_same< typename std::iterator_traits< ITERATOR_TYPE >::iterator_category, std::random_access_iterator_tag >::value)>::type *=nullptr)
Join a set or vector of (something that turns into a string) together into one string,...
Definition Strings.h:84
std::unordered_map< UnitParams, double > UnitParametersMap
Definition Unit.h:30
std::shared_ptr< Unit > Unit_sptr
Shared pointer to the Unit base class.
Definition Unit.h:194
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
Definition IValidator.h:26
Generate a tableworkspace to store the calibration results.
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)