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)
145 return m_progReporter->hasCancellationBeenRequested();
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
214void IFunction::tie(const std::string &parName, const std::string &expr, bool isDefault) {
215 auto ti = std::make_unique<ParameterTie>(this, parName, expr, isDefault);
216 if (!isDefault && ti->isConstant()) {
217 setParameter(parName, ti->eval());
219 } else {
220 addTie(std::move(ti));
221 }
222}
223
233void IFunction::addTies(const std::string &ties, bool isDefault) {
234 Expression list;
235 list.parse(ties);
236 list.toList();
237 for (const auto &t : list) {
238 if (t.name() == "=" && t.size() >= 2) {
239 size_t n = t.size() - 1;
240 const std::string value = t[n].str();
241 for (size_t i = n; i != 0;) {
242 --i;
243 this->tie(t[i].name(), value, isDefault);
244 }
245 }
246 }
247 applyTies();
248}
249
254void IFunction::removeTie(const std::string &parName) {
255 size_t i = parameterIndex(parName);
256 this->removeTie(i);
257}
258
261std::string IFunction::writeTies() const {
262 std::ostringstream tieStream;
263 bool first = true;
264 for (auto &tie : m_ties) {
265 if (tie->isDefault())
266 continue;
267 if (!first) {
268 tieStream << ',';
269 } else {
270 first = false;
271 }
272 tieStream << tie->asString(this);
273 }
274 return tieStream.str();
275}
276
282void IFunction::addTie(std::unique_ptr<ParameterTie> tie) {
283 auto iPar = getParameterIndex(*tie);
284 auto it =
285 std::find_if(m_ties.begin(), m_ties.end(), [&](const auto &m_tie) { return getParameterIndex(*m_tie) == iPar; });
286
287 if (it != m_ties.end()) {
288 *it = std::move(tie);
289 } else {
290 m_ties.emplace_back(std::move(tie));
292 }
293}
294
295bool IFunction::hasOrderedTies() const { return !m_orderedTies.empty(); }
296
298 for (auto &&tie : m_orderedTies) {
299 tie->eval();
300 }
301}
302
307 if (hasOrderedTies()) {
309 } else {
310 for (auto &tie : m_ties) {
311 tie->eval();
312 }
313 }
314}
315
323 const size_t m_i;
324
325public:
327 explicit ReferenceEqual(const IFunction &fun, size_t i) : m_fun(fun), m_i(i) {}
331 template <class T> bool operator()(const std::unique_ptr<T> &p) { return m_fun.getParameterIndex(*p) == m_i; }
332};
333
338bool IFunction::removeTie(size_t i) {
339 if (i >= nParams()) {
340 throw std::out_of_range("Function parameter index out of range.");
341 }
342 auto it = std::find_if(m_ties.begin(), m_ties.end(), ReferenceEqual(*this, i));
343 if (it != m_ties.end()) {
344 m_ties.erase(it);
346 return true;
347 }
348 unfix(i);
349 return false;
350}
351
357 auto it = std::find_if(m_ties.cbegin(), m_ties.cend(), ReferenceEqual(*this, i));
358 if (it != m_ties.cend()) {
359 return it->get();
360 }
361 return nullptr;
362}
363
367 for (size_t i = 0; i < nParams(); ++i) {
369 }
370 m_ties.clear();
371}
372
376void IFunction::addConstraint(std::unique_ptr<IConstraint> ic) {
377 size_t iPar = ic->parameterIndex();
378 auto it = std::find_if(m_constraints.begin(), m_constraints.end(),
379 [&iPar](const auto &constraint) { return constraint->parameterIndex() == iPar; });
380
381 if (it != m_constraints.end()) {
382 *it = std::move(ic);
383 } else {
384 m_constraints.emplace_back(std::move(ic));
385 }
386}
387
393 auto it = std::find_if(m_constraints.cbegin(), m_constraints.cend(), ReferenceEqual(*this, i));
394 if (it != m_constraints.cend()) {
395 return it->get();
396 }
397 return nullptr;
398}
399
403void IFunction::removeConstraint(const std::string &parName) {
404 size_t iPar = parameterIndex(parName);
405 for (auto it = m_constraints.begin(); it != m_constraints.end(); ++it) {
406 if (iPar == (**it).getLocalIndex()) {
407 m_constraints.erase(it);
408 break;
409 }
410 }
411}
412
417void IFunction::setConstraintPenaltyFactor(const std::string &parName, const double &c) {
418 size_t iPar = parameterIndex(parName);
419 const auto it = std::find_if(m_constraints.cbegin(), m_constraints.cend(),
420 [&iPar](const auto &constraint) { return iPar == constraint->getLocalIndex(); });
421
422 if (it != m_constraints.cend()) {
423 (*it)->setPenaltyFactor(c);
424 } else {
425 g_log.warning() << parName << " does not have constraint so setConstraintPenaltyFactor failed"
426 << "\n";
427 }
428}
429
432
434 for (auto &constraint : m_constraints) {
435 constraint->setParamToSatisfyConstraint();
436 }
437}
438
441std::string IFunction::writeConstraints() const {
442 std::ostringstream stream;
443 bool first = true;
444 for (auto &constrint : m_constraints) {
445 if (constrint->isDefault())
446 continue;
447 if (!first) {
448 stream << ',';
449 } else {
450 first = false;
451 }
452 stream << constrint->asString();
453 }
454 return stream.str();
455}
456
462std::string IFunction::asString() const { return writeToString(); }
463
471std::string IFunction::writeToString(const std::string &parentLocalAttributesStr) const {
472 std::ostringstream ostr;
473 ostr << "name=" << this->name();
474 // print the attributes
475 std::vector<std::string> attr = this->getAttributeNames();
476 for (const auto &attName : attr) {
477 std::string attValue = this->getAttribute(attName).value();
478 if (!attValue.empty() && attValue != "\"\"") {
479 ostr << ',' << attName << '=' << attValue;
480 }
481 }
482 std::vector<std::string> ties;
483 // print the parameters
484 for (size_t i = 0; i < nParams(); i++) {
485 std::ostringstream paramOut;
486 paramOut << parameterName(i) << '=' << getParameter(i);
487 ostr << ',' << paramOut.str();
488 // Output non-default ties only.
489 if (getParameterStatus(i) == Fixed) {
490 ties.emplace_back(paramOut.str());
491 }
492 }
493
494 // collect non-default constraints
495 std::string constraints = writeConstraints();
496 // print constraints
497 if (!constraints.empty()) {
498 ostr << ",constraints=(" << constraints << ")";
499 }
500
501 // collect the non-default ties
502 auto tiesString = writeTies();
503 if (!tiesString.empty()) {
504 ties.emplace_back(tiesString);
505 }
506 // print the ties
507 if (!ties.empty()) {
508 ostr << ",ties=(" << Kernel::Strings::join(ties.begin(), ties.end(), ",") << ")";
509 }
510 // "local" attributes of a parent composite function
511 ostr << parentLocalAttributesStr;
512 return ostr.str();
513}
514
521void IFunction::addConstraints(const std::string &str, bool isDefault) {
522 Expression list;
523 list.parse(str);
524 list.toList();
525 for (auto it = list.begin(); it != list.end(); ++it) {
526 auto expr = (*it);
527 if (expr.terms()[0].str().compare("penalty") == 0) {
528 continue;
529 }
530 if ((it + 1) != list.end()) {
531 auto next_expr = *(it + 1);
532 if (next_expr.terms()[0].str().compare("penalty") == 0) {
533 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
534 double penalty_factor = std::stof(next_expr.terms()[1].str(), NULL);
535 c->setPenaltyFactor(penalty_factor);
536 this->addConstraint(std::move(c));
537 } else {
538 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
539 this->addConstraint(std::move(c));
540 }
541 } else {
542 auto c = std::unique_ptr<IConstraint>(ConstraintFactory::Instance().createInitialized(this, expr, isDefault));
543 this->addConstraint(std::move(c));
544 }
545 }
546}
547
551std::vector<std::string> IFunction::getParameterNames() const {
552 std::vector<std::string> out;
553 for (size_t i = 0; i < nParams(); ++i) {
554 out.emplace_back(parameterName(i));
555 }
556 return out;
557}
558
562void IFunction::setHandler(std::unique_ptr<FunctionHandler> handler) {
563 if (handler && handler->function().get() != this) {
564 throw std::runtime_error("Function handler points to a different function");
565 }
566
567 m_handler = std::move(handler);
568 m_handler->init();
569}
570
572const std::vector<std::string> IFunction::categories() const {
576 return tokenizer.asVector();
577}
578
584std::ostream &operator<<(std::ostream &ostr, const IFunction &f) {
585 ostr << f.asString();
586 return ostr;
587}
588
589namespace {
593class AttType : public IFunction::ConstAttributeVisitor<std::string> {
594protected:
596 std::string apply(const std::string & /*str*/) const override { return "std::string"; }
598 std::string apply(const int & /*i*/) const override { return "int"; }
600 std::string apply(const double & /*d*/) const override { return "double"; }
602 std::string apply(const bool & /*i*/) const override { return "bool"; }
604 std::string apply(const std::vector<double> & /*unused*/) const override { return "std::vector<double>"; }
605};
606} // namespace
607
608std::string IFunction::Attribute::type() const {
609 AttType tmp;
610 return apply(tmp);
611}
612
613namespace {
617class AttValue : public IFunction::ConstAttributeVisitor<std::string> {
618public:
619 explicit AttValue(bool quoteString = false)
620 : IFunction::ConstAttributeVisitor<std::string>(), m_quoteString(quoteString) {}
621
622protected:
624 std::string apply(const std::string &str) const override {
625 return (m_quoteString) ? std::string("\"" + str + "\"") : str;
626 }
628 std::string apply(const int &i) const override { return std::to_string(i); }
630 std::string apply(const double &d) const override { return boost::lexical_cast<std::string>(d); }
632 std::string apply(const bool &b) const override { return b ? "true" : "false"; }
634 std::string apply(const std::vector<double> &v) const override {
635 std::string res = "(";
636 if (!v.empty()) {
637 for (size_t i = 0; i < v.size() - 1; ++i) {
638 res += boost::lexical_cast<std::string>(v[i]) + ",";
639 }
640 res += boost::lexical_cast<std::string>(v.back());
641 }
642 res += ")";
643 return res;
644 }
645
646private:
649};
650} // namespace
651
652std::string IFunction::Attribute::value() const {
653 AttValue tmp(m_quoteValue);
654 return apply(tmp);
655}
656
661 if (m_quoteValue)
662 return asQuotedString();
663
664 try {
665 return boost::get<std::string>(m_data);
666 } catch (...) {
667 throw std::runtime_error("Trying to access a " + type() +
668 " attribute "
669 "as string");
670 }
671}
672
677 std::string attr;
678
679 try {
680 attr = boost::get<std::string>(m_data);
681 } catch (...) {
682 throw std::runtime_error("Trying to access a " + type() +
683 " attribute "
684 "as string");
685 }
686
687 if (attr.empty())
688 return "\"\"";
689
690 std::string quoted(attr);
691 if (*(attr.begin()) != '\"')
692 quoted = "\"" + attr;
693 if (*(quoted.end() - 1) != '\"')
694 quoted += "\"";
695
696 return quoted;
697}
698
703 std::string attr;
704
705 try {
706 attr = boost::get<std::string>(m_data);
707 } catch (...) {
708 throw std::runtime_error("Trying to access a " + type() +
709 " attribute "
710 "as string");
711 }
712 std::string unquoted(attr);
713 if (attr.empty())
714 return "";
715 if (*(attr.begin()) == '\"')
716 unquoted = std::string(attr.begin() + 1, attr.end() - 1);
717 if (*(unquoted.end() - 1) == '\"')
718 unquoted = std::string(unquoted.begin(), unquoted.end() - 1);
719
720 return unquoted;
721}
722
727 try {
728 return boost::get<int>(m_data);
729 } catch (...) {
730 throw std::runtime_error("Trying to access a " + type() +
731 " attribute "
732 "as int");
733 }
734}
735
740 try {
741 return boost::get<double>(m_data);
742 } catch (...) {
743 throw std::runtime_error("Trying to access a " + type() +
744 " attribute "
745 "as double");
746 }
747}
748
753 try {
754 return boost::get<bool>(m_data);
755 } catch (...) {
756 throw std::runtime_error("Trying to access a " + type() +
757 " attribute "
758 "as bool");
759 }
760}
761
765std::vector<double> IFunction::Attribute::asVector() const {
766 try {
767 return boost::get<std::vector<double>>(m_data);
768 } catch (...) {
769 throw std::runtime_error("Trying to access a " + type() +
770 " attribute "
771 "as vector");
772 }
773}
774
779void IFunction::Attribute::setString(const std::string &str) {
780 evaluateValidator(str);
781
782 try {
783 boost::get<std::string>(m_data) = str;
784 } catch (...) {
785 throw std::runtime_error("Trying to access a " + type() +
786 " attribute "
787 "as string");
788 }
789}
790
796 evaluateValidator(d);
797
798 try {
799 boost::get<double>(m_data) = d;
800 } catch (...) {
801 throw std::runtime_error("Trying to access a " + type() +
802 " attribute "
803 "as double");
804 }
805}
806
812 evaluateValidator(i);
813
814 try {
815 boost::get<int>(m_data) = i;
816 } catch (...) {
817 throw std::runtime_error("Trying to access a " + type() +
818 " attribute "
819 "as int");
820 }
821}
822
827void IFunction::Attribute::setBool(const bool &b) {
828 evaluateValidator(b);
829
830 try {
831 boost::get<bool>(m_data) = b;
832 } catch (...) {
833 throw std::runtime_error("Trying to access a " + type() +
834 " attribute "
835 "as bool");
836 }
837}
838
844void IFunction::Attribute::setVector(const std::vector<double> &v) {
845 evaluateValidator(v);
846
847 try {
848 auto &value = boost::get<std::vector<double>>(m_data);
849 value.assign(v.begin(), v.end());
850 } catch (...) {
851 throw std::runtime_error("Trying to access a " + type() +
852 " attribute "
853 "as vector");
854 }
855}
856
859 try {
860 return boost::get<std::string>(m_data).empty();
861 } catch (...) {
862 throw std::runtime_error("Trying to access a " + type() + " attribute as string");
863 }
864}
865
866namespace {
870class SetValue : public IFunction::AttributeVisitor<> {
871public:
877 explicit SetValue(std::string value, Mantid::Kernel::IValidator_sptr validator = Mantid::Kernel::IValidator_sptr())
878 : m_value(std::move(value)), m_validator(validator) {}
879
880protected:
882 void apply(std::string &str) const override {
883 evaluateValidator(m_value);
884 str = m_value;
885 }
887 void apply(int &i) const override {
888 int tempi = 0;
889
890 std::istringstream istr(m_value + " ");
891 istr >> tempi;
892 if (!istr.good())
893 throw std::invalid_argument("Failed to set int attribute "
894 "from string " +
895 m_value);
896
897 evaluateValidator(tempi);
898 i = tempi;
899 }
901 void apply(double &d) const override {
902 double tempd = 0;
903
904 std::istringstream istr(m_value + " ");
905 istr >> tempd;
906 if (!istr.good())
907 throw std::invalid_argument("Failed to set double attribute "
908 "from string " +
909 m_value);
910
911 evaluateValidator(tempd);
912 d = tempd;
913 }
915 void apply(bool &b) const override {
916 bool tempb = false;
917
918 tempb = (m_value == "true" || m_value == "TRUE" || m_value == "1");
919 evaluateValidator(tempb);
920
921 b = (m_value == "true" || m_value == "TRUE" || m_value == "1");
922 }
924 void apply(std::vector<double> &v) const override {
925 if (m_value.empty() || m_value == "EMPTY") {
926 v.clear();
927 return;
928 }
929 if (m_value.size() > 2) {
930 // check if the value is in brackets (...)
931 if (m_value.front() == '(' && m_value.back() == ')') {
932 m_value.erase(0, 1);
933 m_value.erase(m_value.size() - 1);
934 }
935 }
936 Kernel::StringTokenizer tokenizer(m_value, ",", Kernel::StringTokenizer::TOK_TRIM);
937 size_t newSize = tokenizer.count();
938
939 // if visitor has an associated validator, first populate temp vec and evaluate against validator.
940 if (m_validator != nullptr) {
941 std::vector<double> tempVec(newSize);
942
943 for (size_t i = 0; i < tempVec.size(); ++i) {
944 tempVec[i] = boost::lexical_cast<double>(tokenizer[i]);
945 }
946 evaluateValidator(tempVec);
947 }
948
949 v.resize(newSize);
950 for (size_t i = 0; i < v.size(); ++i) {
951 v[i] = boost::lexical_cast<double>(tokenizer[i]);
952 }
953 }
954
956 template <typename T> void evaluateValidator(T &inputData) const {
957 if (m_validator != nullptr) {
958 IFunction::ValidatorEvaluator::evaluate(inputData, m_validator);
959 }
960 }
961
962private:
963 mutable std::string m_value;
964 mutable Kernel::IValidator_sptr m_validator;
965};
966} // namespace
967
971void IFunction::Attribute::fromString(const std::string &str) {
972 SetValue tmp(str, m_validator);
973 apply(tmp);
974}
975
979void IFunction::Attribute::setValidator(const Kernel::IValidator_sptr &validator) const { m_validator = validator; }
980
985
988double IFunction::activeParameter(size_t i) const {
989 if (!isActive(i)) {
990 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
991 }
992 return getParameter(i);
993}
994
997void IFunction::setActiveParameter(size_t i, double value) {
998 if (!isActive(i)) {
999 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1000 }
1001 setParameter(i, value);
1002}
1003
1008std::string IFunction::nameOfActive(size_t i) const {
1009 if (!isActive(i)) {
1010 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1011 }
1012 return parameterName(i);
1013}
1014
1019std::string IFunction::descriptionOfActive(size_t i) const {
1020 if (!isActive(i)) {
1021 throw std::runtime_error("Attempt to use an inactive parameter " + parameterName(i));
1022 }
1023 return parameterDescription(i);
1024}
1025
1032 /*
1033 * There is a similar more specialized method for 1D functions in IFunction1D
1034 * but the method takes different parameters and uses slightly different
1035 * function calls in places making it difficult to share code. Please also
1036 * consider that method when updating this.
1037 */
1038
1039 const size_t nParam = nParams();
1040 size_t nData = getValuesSize(domain);
1041
1042 FunctionValues minusStep(nData);
1043 FunctionValues plusStep(nData);
1044
1045 applyTies(); // just in case
1046 function(domain, minusStep);
1047
1048 if (nData == 0) {
1049 nData = minusStep.size();
1050 }
1051
1052 double step;
1053 for (size_t iP = 0; iP < nParam; iP++) {
1054 if (isActive(iP)) {
1055 const double val = activeParameter(iP);
1056 step = calculateStepSize(val);
1057
1058 const double paramPstep = val + step;
1059 setActiveParameter(iP, paramPstep);
1060 applyTies();
1061 function(domain, plusStep);
1062 setActiveParameter(iP, val);
1063 applyTies();
1064
1065 step = paramPstep - val;
1066 for (size_t i = 0; i < nData; i++) {
1067 jacobian.set(i, iP, (plusStep.getCalculated(i) - minusStep.getCalculated(i)) / step);
1068 }
1069 }
1070 }
1071}
1072
1077double IFunction::calculateStepSize(const double parameterValue) const { return m_stepSizeFunction(parameterValue); }
1078
1083 switch (method) {
1085 m_stepSizeFunction = defaultStepSize;
1086 return;
1088 m_stepSizeFunction = sqrtEpsilonStepSize;
1089 return;
1090 }
1091 throw std::invalid_argument("An invalid method for calculating the step size was provided.");
1092}
1093
1100void IFunction::setMatrixWorkspace(std::shared_ptr<const API::MatrixWorkspace> workspace, size_t wi, double startX,
1101 double endX) {
1102 UNUSED_ARG(startX);
1103 UNUSED_ARG(endX);
1104
1105 if (!workspace)
1106 return; // unset the workspace
1107
1108 try {
1109
1110 // check if parameter are specified in instrument definition file
1111
1112 const auto &paramMap = workspace->constInstrumentParameters();
1113
1114 Geometry::IDetector const *detectorPtr = nullptr;
1115 size_t numDetectors = workspace->getSpectrum(wi).getDetectorIDs().size();
1116 if (numDetectors > 1) {
1117 // If several detectors are on this workspace index, just use the ID of
1118 // the first detector
1119 // Note JZ oct 2011 - I'm not sure why the code uses the first detector
1120 // and not the group. Ask Roman.
1121 auto firstDetectorId = *workspace->getSpectrum(wi).getDetectorIDs().begin();
1122
1123 const auto &detectorInfo = workspace->detectorInfo();
1124 const auto detectorIndex = detectorInfo.indexOf(firstDetectorId);
1125 const auto &detector = detectorInfo.detector(detectorIndex);
1126 detectorPtr = &detector;
1127 } else {
1128 // Get the detector (single) at this workspace index
1129 const auto &spectrumInfo = workspace->spectrumInfo();
1130 const auto &detector = spectrumInfo.detector(wi);
1131 detectorPtr = &detector;
1132 }
1133
1134 for (size_t i = 0; i < nParams(); i++) {
1135 if (!isExplicitlySet(i)) {
1136 Geometry::Parameter_sptr param = paramMap.getRecursive(detectorPtr, parameterName(i), "fitting");
1137 if (param != Geometry::Parameter_sptr()) {
1138 // get FitParameter
1139 const auto &fitParam = param->value<Geometry::FitParameter>();
1140
1141 // check first if this parameter is actually specified for this
1142 // function
1143 if (name() == fitParam.getFunction()) {
1144 // update value
1145 auto *testWithLocation = dynamic_cast<IFunctionWithLocation *>(this);
1146 if (testWithLocation == nullptr ||
1147 (!fitParam.getLookUpTable().containData() && fitParam.getFormula().empty())) {
1148 setParameter(i, fitParam.getValue());
1149 } else {
1150 double centreValue = testWithLocation->centre();
1151 Kernel::Unit_sptr centreUnit; // unit of value used in formula or
1152 // to look up value in lookup table
1153 if (fitParam.getFormula().empty())
1154 centreUnit = fitParam.getLookUpTable().getXUnit(); // from table
1155 else {
1156 if (!fitParam.getFormulaUnit().empty()) {
1157 try {
1158 centreUnit = Kernel::UnitFactory::Instance().create(fitParam.getFormulaUnit()); // from formula
1159 } catch (...) {
1160 g_log.warning() << fitParam.getFormulaUnit() << " Is not an recognised formula unit for parameter "
1161 << fitParam.getName() << "\n";
1162 }
1163 }
1164 }
1165
1166 // if unit specified convert centre value to unit required by
1167 // formula or look-up-table
1168 if (centreUnit) {
1169 g_log.debug() << "For FitParameter " << parameterName(i)
1170 << " centre of peak before any unit conversion is " << centreValue << '\n';
1171 centreValue = convertValue(centreValue, centreUnit, workspace, wi);
1172 g_log.debug() << "For FitParameter " << parameterName(i)
1173 << " centre of peak after any unit conversion is " << centreValue << '\n';
1174 }
1175
1176 double paramValue = fitParam.getValue(centreValue);
1177
1178 // this returned param value by a formula or a look-up-table may
1179 // have
1180 // a unit of its own. If set convert param value
1181 // See section 'Using fitting parameters in
1182 // www.mantidproject.org/IDF
1183 if (fitParam.getFormula().empty()) {
1184 // so from look up table
1185 Kernel::Unit_sptr resultUnit = fitParam.getLookUpTable().getYUnit(); // from table
1186 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1187 << " before y-unit conversion\n";
1188 paramValue /= convertValue(1.0, resultUnit, workspace, wi);
1189 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1190 << " after y-unit conversion\n";
1191 } else {
1192 // so from formula
1193
1194 std::string resultUnitStr = fitParam.getResultUnit();
1195
1196 if (!resultUnitStr.empty()) {
1197 std::vector<std::string> allUnitStr = Kernel::UnitFactory::Instance().getKeys();
1198 for (auto &iUnit : allUnitStr) {
1199 size_t found = resultUnitStr.find(iUnit);
1200 if (found != std::string::npos) {
1201 size_t len = iUnit.size();
1202 std::stringstream readDouble;
1204 readDouble << 1.0 / convertValue(1.0, unt, workspace, wi);
1205 resultUnitStr.replace(found, len, readDouble.str());
1206 }
1207 } // end for
1208
1209 try {
1210 mu::Parser p;
1211 p.SetExpr(resultUnitStr);
1212 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1213 << " before result-unit conversion (using " << resultUnitStr << ")\n";
1214 paramValue *= p.Eval();
1215 g_log.debug() << "The FitParameter " << parameterName(i) << " = " << paramValue
1216 << " after result-unit conversion\n";
1217 } catch (mu::Parser::exception_type &e) {
1218 g_log.error() << "Cannot convert formula unit to workspace unit"
1219 << " Formula unit which cannot be passed is " << resultUnitStr
1220 << ". Muparser error message is: " << e.GetMsg() << '\n';
1221 }
1222 } // end if
1223 } // end trying to convert result-unit from formula or y-unit for
1224 // lookuptable
1225
1226 setParameter(i, paramValue);
1227 } // end of update parameter value
1228
1229 // add tie if specified for this parameter in instrument definition
1230 // file
1231 if (!fitParam.getTie().empty()) {
1232 std::ostringstream str;
1233 str << getParameter(i);
1234 tie(parameterName(i), str.str());
1235 }
1236
1237 // add constraint if specified for this parameter in instrument
1238 // definition file
1239 if (!fitParam.getConstraint().empty()) {
1240 IConstraint *constraint = ConstraintFactory::Instance().createInitialized(this, fitParam.getConstraint());
1241 if (!fitParam.getConstraintPenaltyFactor().empty()) {
1242 try {
1243 double penalty = std::stod(fitParam.getConstraintPenaltyFactor());
1244 constraint->setPenaltyFactor(penalty);
1245 } catch (...) {
1246 g_log.warning() << "Can't set penalty factor for constraint\n";
1247 }
1248 }
1249 addConstraint(std::unique_ptr<IConstraint>(constraint));
1250 }
1251 }
1252 }
1253 }
1254 }
1255 } catch (...) {
1256 }
1257}
1258
1268 const std::shared_ptr<const MatrixWorkspace> &ws, size_t wsIndex) const {
1269 // only required if formula or look-up-table different from ws unit
1270 const auto &wsUnit = ws->getAxis(0)->unit();
1271 if (outUnit->unitID() == wsUnit->unitID())
1272 return value;
1273
1274 // first check if it is possible to do a quick conversion and convert
1275 // slight duplication to below to avoid instantiating vector unless necessary
1276 double factor(0.0), power(0.0);
1277 if (wsUnit->quickConversion(*outUnit, factor, power)) {
1278 return factor * std::pow(value, power);
1279 } else {
1280 std::vector<double> singleValue(1, value);
1281 convertValue(singleValue, outUnit, ws, wsIndex);
1282 return singleValue.front();
1283 }
1284}
1285
1294void IFunction::convertValue(std::vector<double> &values, Kernel::Unit_sptr &outUnit,
1295 const std::shared_ptr<const MatrixWorkspace> &ws, size_t wsIndex) const {
1296 // only required if formula or look-up-table different from ws unit
1297 const auto &wsUnit = ws->getAxis(0)->unit();
1298 if (outUnit->unitID() == wsUnit->unitID())
1299 return;
1300
1301 // first check if it is possible to do a quick conversion convert
1302 double factor, power;
1303 if (wsUnit->quickConversion(*outUnit, factor, power)) {
1304 auto iend = values.end();
1305 for (auto itr = values.begin(); itr != iend; ++itr)
1306 (*itr) = factor * std::pow(*itr, power);
1307 } else {
1308 // Get l1, l2 and theta (see also RemoveBins.calculateDetectorPosition())
1309 Instrument_const_sptr instrument = ws->getInstrument();
1310 Geometry::IComponent_const_sptr sample = instrument->getSample();
1311 if (sample == nullptr) {
1312 g_log.error() << "No sample defined instrument. Cannot convert units for function\n"
1313 << "Ignore conversion.";
1314 return;
1315 }
1316 const auto &spectrumInfo = ws->spectrumInfo();
1317 double l1 = spectrumInfo.l1();
1318 // If this is a monitor then l1+l2 = source-detector distance and twoTheta=0
1319 auto emode = ws->getEMode();
1320
1322 spectrumInfo.getDetectorValues(*wsUnit, *outUnit, emode, false, wsIndex, pmap);
1323 std::vector<double> emptyVec;
1324 try {
1325 wsUnit->toTOF(values, emptyVec, l1, emode, pmap);
1326 outUnit->fromTOF(values, emptyVec, l1, emode, pmap);
1327 } catch (std::exception &) {
1328 throw std::runtime_error("Unable to perform unit conversion to " + outUnit->unitID());
1329 }
1330 }
1331}
1332
1336size_t IFunction::nAttributes() const { return m_attrs.size(); }
1337
1339bool IFunction::hasAttribute(const std::string &name) const { return m_attrs.find(name) != m_attrs.end(); }
1340
1346void IFunction::setAttributeValue(const std::string &attName, const char *value) {
1347 std::string str(value);
1348 setAttributeValue(attName, str);
1349}
1350
1356void IFunction::setAttributeValue(const std::string &attName, const std::string &value) {
1357 Attribute att = getAttribute(attName);
1358 att.setString(value);
1359 setAttribute(attName, att);
1360}
1361
1364 throw std::runtime_error("Function " + name() + " doesn't have children.");
1365}
1366
1368std::vector<std::string> IFunction::getAttributeNames() const {
1369 std::vector<std::string> names;
1370 names.reserve(nAttributes());
1371 for (size_t i = 0; i < nAttributes(); ++i) {
1372 names.emplace_back(attributeName(i));
1373 }
1374 return names;
1375}
1376
1382std::string IFunction::attributeName(size_t index) const {
1383 if (index >= nAttributes()) {
1384 throw std::out_of_range("Function attribute index out of range.");
1385 }
1386 auto itr = std::next(m_attrs.begin(), index);
1387 return itr->first;
1388}
1389
1395 if (hasAttribute(name)) {
1396 return m_attrs.at(name);
1397 } else {
1398 throw std::invalid_argument("ParamFunctionAttributeHolder::getAttribute - Unknown attribute '" + name + "'");
1399 }
1400}
1401
1411}
1412
1418void IFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue) {
1420
1421 m_attrs.emplace(name, defaultValue);
1422}
1423
1430void IFunction::declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue,
1431 const Kernel::IValidator &validator) {
1432 const Kernel::IValidator_sptr validatorClone = validator.clone();
1434
1435 defaultValue.setValidator(validatorClone);
1436 defaultValue.evaluateValidator();
1437
1438 m_attrs.emplace(name, defaultValue);
1439}
1440
1445void IFunction::checkAttributeName(const std::string &name) {
1446 if (m_attrs.find(name) != m_attrs.end()) {
1447 std::ostringstream msg;
1448 msg << "Attribute (" << name << ") already exists.";
1449 throw std::invalid_argument(msg.str());
1450 }
1451}
1452
1457}
1458
1465 if (hasAttribute(name)) {
1466 auto att = m_attrs[name];
1467 const Kernel::IValidator_sptr validatorClone = att.getValidator();
1468 value.setValidator(validatorClone);
1469 value.evaluateValidator();
1470
1471 m_attrs[name] = value;
1472 } else {
1473 throw std::invalid_argument("ParamFunctionAttributeHolder::setAttribute - Unknown attribute '" + name + "'");
1474 }
1475}
1476
1484 const_cast<IFunction *>(this)->storeAttributeValue(name, value);
1485}
1486
1496void IFunction::setCovarianceMatrix(const std::shared_ptr<Kernel::Matrix<double>> &covar) {
1497 // the matrix shouldn't be empty
1498 if (!covar) {
1499 throw std::invalid_argument("IFunction: Cannot set an empty covariance matrix");
1500 }
1501 // the matrix should relate to this function
1502 if (covar->numRows() != nParams() || covar->numCols() != nParams()) {
1503 throw std::invalid_argument("IFunction: Covariance matrix has a wrong size");
1504 }
1505 m_covar = covar;
1506}
1507
1510size_t IFunction::getValuesSize(const FunctionDomain &domain) const { return domain.size(); }
1511
1515void IFunction::fixParameter(const std::string &name, bool isDefault) {
1516 auto i = parameterIndex(name);
1517 fix(i, isDefault);
1518}
1519
1522void IFunction::unfixParameter(const std::string &name) {
1523 auto i = parameterIndex(name);
1524 unfix(i);
1525}
1526
1529void IFunction::fixAll(bool isDefault) {
1530 for (size_t i = 0; i < nParams(); ++i) {
1531 if (isActive(i)) {
1532 fix(i, isDefault);
1533 }
1534 }
1535}
1536
1539 for (size_t i = 0; i < nParams(); ++i) {
1540 if (isFixed(i)) {
1541 unfix(i);
1542 }
1543 }
1544}
1545
1548 for (size_t i = 0; i < nParams(); ++i) {
1550 unfix(i);
1551 }
1552 }
1553}
1554
1560void IFunction::fixAllActive(bool isDefault) {
1561 for (size_t i = 0; i < nParams(); ++i) {
1562 if (getParameterStatus(i) == Active) {
1563 fix(i, isDefault);
1564 }
1565 }
1566}
1567
1572size_t IFunction::getNumberDomains() const { return 1; }
1573
1579std::vector<IFunction_sptr> IFunction::createEquivalentFunctions() const {
1580 return std::vector<IFunction_sptr>(1, FunctionFactory::Instance().createInitialized(asString()));
1581}
1582
1585 m_orderedTies.clear();
1586 std::list<TieNode> orderedTieNodes;
1587 for (size_t i = 0; i < nParams(); ++i) {
1588 auto const tie = getTie(i);
1589 if (!tie || ignoreTie(*tie)) {
1590 continue;
1591 }
1592
1593 TieNode newNode;
1594 newNode.left = getParameterIndex(*tie);
1595 auto const rhsParameters = tie->getRHSParameters();
1596 newNode.right.reserve(rhsParameters.size());
1597 for (auto &&p : rhsParameters) {
1598 newNode.right.emplace_back(this->getParameterIndex(p));
1599 }
1600 if (newNode < newNode) {
1601 throw std::runtime_error("Parameter is tied to itself: " + tie->asString(this));
1602 }
1603 bool before(false), after(false);
1604 size_t indexBefore(0), indexAfter(0);
1605 for (auto &&node : orderedTieNodes) {
1606 if (newNode < node) {
1607 before = true;
1608 indexBefore = node.left;
1609 }
1610 if (node < newNode) {
1611 after = true;
1612 indexAfter = node.left;
1613 }
1614 }
1615 if (before) {
1616 if (after) {
1617 std::string message = "Circular dependency in ties:\n" + tie->asString(this) + '\n';
1618 message += getTie(indexBefore)->asString(this);
1619 if (indexAfter != indexBefore) {
1620 message += '\n' + getTie(indexAfter)->asString(this);
1621 }
1622 throw std::runtime_error(message);
1623 }
1624 orderedTieNodes.push_front(newNode);
1625 } else {
1626 orderedTieNodes.emplace_back(newNode);
1627 }
1628 }
1629 for (auto &&node : orderedTieNodes) {
1630 auto const tie = getTie(node.left);
1631 m_orderedTies.emplace_back(tie);
1632 }
1633}
1634
1635} // namespace Mantid::API
1636
1638namespace Mantid::Kernel {
1639
1640template <>
1641MANTID_API_DLL std::shared_ptr<Mantid::API::IFunction>
1642IPropertyManager::getValue<std::shared_ptr<Mantid::API::IFunction>>(const std::string &name) const {
1643 auto *prop = dynamic_cast<PropertyWithValue<std::shared_ptr<Mantid::API::IFunction>> *>(getPointerToProperty(name));
1644 if (prop) {
1645 return *prop;
1646 } else {
1647 std::string message = "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<IFunction>.";
1648 throw std::runtime_error(message);
1649 }
1650}
1651
1652template <>
1653MANTID_API_DLL std::shared_ptr<const Mantid::API::IFunction>
1654IPropertyManager::getValue<std::shared_ptr<const Mantid::API::IFunction>>(const std::string &name) const {
1655 auto *prop = dynamic_cast<PropertyWithValue<std::shared_ptr<Mantid::API::IFunction>> *>(getPointerToProperty(name));
1656 if (prop) {
1657 return prop->operator()();
1658 } else {
1659 std::string message =
1660 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<IFunction>.";
1661 throw std::runtime_error(message);
1662 }
1663}
1664
1665} // namespace Mantid::Kernel
const std::string & m_value
Definition: Algorithm.cpp:71
Kernel::IValidator_sptr m_validator
Definition: IFunction.cpp:964
bool m_quoteString
Flag to quote a string value returned.
Definition: IFunction.cpp:648
gsl_vector * tmp
double value
The value of the point.
Definition: FitMW.cpp:51
double error
Definition: IndexPeaks.cpp:133
IPeaksWorkspace_sptr workspace
Definition: IndexPeaks.cpp:114
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
const double EPSILON(1.0E-10)
double left
Definition: LineProfile.cpp:80
double right
Definition: LineProfile.cpp:81
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:64
const std::vector< Type > & m_data
Definition: TableColumn.h:417
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.
Definition: Expression.cpp:159
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,...
Definition: Expression.cpp:559
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:377
Attribute is a non-fitting parameter.
Definition: IFunction.h:282
std::string asUnquotedString() const
Returns a string value that is guarenteed to be unquoted.
Definition: IFunction.cpp:702
void setString(const std::string &str)
Sets new value if attribute is a string.
Definition: IFunction.cpp:779
std::vector< double > asVector() const
Returns vector<double> if attribute is vector<double>, throws exception otherwise.
Definition: IFunction.cpp:765
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
Definition: IFunction.cpp:726
void evaluateValidator() const
Evaluates the validator associated with this attribute. Returns error as a string.
Definition: IFunction.cpp:984
std::string asString() const
Returns string value if attribute is a string, throws exception otherwise.
Definition: IFunction.cpp:660
void setVector(const std::vector< double > &)
Sets new value if attribute is a vector.
Definition: IFunction.cpp:844
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Definition: IFunction.h:300
void setDouble(const double &)
Sets new value if attribute is a double.
Definition: IFunction.cpp:795
std::string asQuotedString() const
Returns a string value that is guarenteed to be quoted for use in places where the string is used as ...
Definition: IFunction.cpp:676
void setValidator(const Kernel::IValidator_sptr &validator) const
Set validator to enforce limits on attribute value.
Definition: IFunction.cpp:979
std::string value() const
Returns the attribute value as a string.
Definition: IFunction.cpp:652
void setBool(const bool &)
Sets new value if attribute is a bool.
Definition: IFunction.cpp:827
void fromString(const std::string &str)
Set value from a string.
Definition: IFunction.cpp:971
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
Definition: IFunction.cpp:739
bool isEmpty() const
Check if a string attribute is empty.
Definition: IFunction.cpp:858
void setInt(const int &)
Sets new value if attribute is a int.
Definition: IFunction.cpp:811
bool asBool() const
Returns bool value if attribute is a bool, throws exception otherwise.
Definition: IFunction.cpp:752
std::string type() const
Returns type of the attribute.
Definition: IFunction.cpp:608
Const version of AttributeVisitor.
Definition: IFunction.h:241
This is an interface to a fitting function - a semi-abstarct class.
Definition: IFunction.h:163
virtual void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Derivatives of function with respect to active parameters.
Definition: IFunction.cpp:155
bool hasOrderedTies() const
Definition: IFunction.cpp:295
virtual std::string descriptionOfActive(size_t i) const
Returns the name of active parameter i.
Definition: IFunction.cpp:1019
virtual size_t nParams() const =0
Total number of parameters.
std::function< double(const double)> m_stepSizeFunction
The function used to calculate the step size.
Definition: IFunction.h:728
virtual void removeConstraint(const std::string &parName)
Remove a constraint.
Definition: IFunction.cpp:403
bool isActive(size_t i) const
Check if an active parameter i is actually active.
Definition: IFunction.cpp:160
std::string writeTies() const
Write a parameter tie to a string.
Definition: IFunction.cpp:261
void unfixParameter(const std::string &name)
Free a parameter.
Definition: IFunction.cpp:1522
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
Definition: IFunction.cpp:1394
void setProgressReporter(std::shared_ptr< Kernel::ProgressBase > reporter)
Attach a progress reporter.
Definition: IFunction.cpp:123
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)
Definition: IFunction.cpp:1267
virtual void clearTies()
Remove all ties.
Definition: IFunction.cpp:366
virtual void clearConstraints()
Remove all constraints.
Definition: IFunction.cpp:431
virtual ~IFunction()
Virtual destructor.
Definition: IFunction.cpp:92
double calculateStepSize(const double parameterValue) const
Calculate step size for the given parameter value.
Definition: IFunction.cpp:1077
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
Definition: IFunction.cpp:1418
void sortTies()
Put all ties in order in which they will be applied correctly.
Definition: IFunction.cpp:1584
virtual std::shared_ptr< IFunction > clone() const
Virtual copy constructor.
Definition: IFunction.cpp:109
void setHandler(std::unique_ptr< FunctionHandler > handler)
Set a function handler.
Definition: IFunction.cpp:562
void storeReadOnlyAttribute(const std::string &name, const API::IFunction::Attribute &value) const
A read-only ("mutable") attribute can be stored in a const method.
Definition: IFunction.cpp:1483
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
std::map< std::string, API::IFunction::Attribute > m_attrs
The declared attributes.
Definition: IFunction.h:714
virtual void declareAttributes()
Override to declare function attributes.
Definition: IFunction.h:676
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.
Definition: IFunction.cpp:1100
virtual void setParameter(size_t, const double &value, bool explicitlySet=true)=0
Set i-th parameter.
virtual void applyTies()
Apply the ties.
Definition: IFunction.cpp:306
void checkAttributeName(const std::string &name)
Check Attribute to declare does not already exist.
Definition: IFunction.cpp:1445
virtual ParameterTie * getTie(size_t i) const
Get the tie of i-th parameter.
Definition: IFunction.cpp:356
virtual void setStepSizeMethod(const StepSizeMethod method)
Sets the StepSizeMethod to use when calculation the step size.
Definition: IFunction.cpp:1082
virtual const std::string category() const
The categories the Fit function belong to.
Definition: IFunction.h:440
virtual const std::string categorySeparator() const
Function to return the sperator token for the category string.
Definition: IFunction.h:445
virtual std::string writeToString(const std::string &parentLocalAttributesStr="") const
Writes itself into a string.
Definition: IFunction.cpp:471
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
Definition: IFunction.cpp:1409
void unfixAllDefault()
Free all parameters fixed by default.
Definition: IFunction.cpp:1547
virtual size_t getValuesSize(const FunctionDomain &domain) const
Get number of values for a given domain.
Definition: IFunction.cpp:1510
virtual std::string nameOfActive(size_t i) const
Returns the name of active parameter i.
Definition: IFunction.cpp:1008
void fixAllActive(bool isDefault=false)
Fix all active parameters.
Definition: IFunction.cpp:1560
bool cancellationRequestReceived() const
Returns true if a progress reporter is set & evalaution has been requested to stop.
Definition: IFunction.cpp:143
virtual double activeParameter(size_t i) const
Value of i-th active parameter.
Definition: IFunction.cpp:988
virtual size_t getParameterIndex(const ParameterReference &ref) const =0
Return parameter index from a parameter reference.
virtual void setUpForFit()
Set up the function for a fit.
Definition: IFunction.cpp:433
virtual const std::vector< std::string > categories() const
Function to return all of the categories that contain this algorithm.
Definition: IFunction.cpp:572
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.
Definition: IFunction.cpp:1515
virtual std::vector< std::string > getAttributeNames() const
Returns a list of attribute names.
Definition: IFunction.cpp:1368
virtual std::string attributeName(size_t index) const
Get name of ith attribute.
Definition: IFunction.cpp:1382
void reportProgress(const std::string &msg="") const
Reports progress with an optional message.
Definition: IFunction.cpp:132
virtual void setConstraintPenaltyFactor(const std::string &parName, const double &c)
Set a constraint penalty.
Definition: IFunction.cpp:417
std::vector< ParameterTie * > m_orderedTies
Ties ordered in order of correct application.
Definition: IFunction.h:724
virtual void addTies(const std::string &ties, bool isDefault=false)
Add several ties.
Definition: IFunction.cpp:233
std::string asString() const
Writes itself into a string.
Definition: IFunction.cpp:462
void unfix(size_t i)
Restores a declared parameter i to the active status.
Definition: IFunction.cpp:197
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.
Definition: IFunction.cpp:1496
std::vector< std::unique_ptr< ParameterTie > > m_ties
Holds parameter ties.
Definition: IFunction.h:720
void calNumericalDeriv(const FunctionDomain &domain, Jacobian &jacobian)
Calculate numerical derivatives.
Definition: IFunction.cpp:1031
std::shared_ptr< Kernel::ProgressBase > m_progReporter
Pointer to the progress handler.
Definition: IFunction.h:710
std::vector< std::unique_ptr< IConstraint > > m_constraints
Holds the constraints added to function.
Definition: IFunction.h:722
virtual bool hasAttribute(const std::string &name) const
Check if attribute attName exists.
Definition: IFunction.cpp:1339
void unfixAll()
Free all parameters.
Definition: IFunction.cpp:1538
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.
Definition: IFunction.cpp:1363
virtual void addTie(std::unique_ptr< ParameterTie > tie)
Add a new tie. Derived classes must provide storage for ties.
Definition: IFunction.cpp:282
virtual std::vector< std::shared_ptr< IFunction > > createEquivalentFunctions() const
Split this function (if needed) into a list of independent functions.
Definition: IFunction.cpp:1579
virtual void addConstraints(const std::string &str, bool isDefault=false)
Add a list of conatraints from a string.
Definition: IFunction.cpp:521
void fixAll(bool isDefault=false)
Fix all parameters.
Definition: IFunction.cpp:1529
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.
Definition: IFunction.cpp:441
void setAttributeValue(const std::string &attName, const T &value)
Set an attribute value.
Definition: IFunction.h:597
virtual void removeTie(const std::string &parName)
Removes the tie off a parameter.
Definition: IFunction.cpp:254
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.
Definition: IFunction.cpp:1464
virtual void init()
Function initialization. Declare function parameters in this method.
Definition: IFunction.cpp:1454
bool isFixedByDefault(size_t i) const
Check if a parameter i is fixed by default (not by user).
Definition: IFunction.cpp:175
virtual void declareParameters()
Override to declare function parameters.
Definition: IFunction.h:678
std::vector< std::string > getParameterNames() const
Return a vector with all parameter names.
Definition: IFunction.cpp:551
virtual bool ignoreTie(const ParameterTie &) const
Ignore a tie.
Definition: IFunction.h:558
void fix(size_t i, bool isDefault=false)
Removes a parameter i from the list of active.
Definition: IFunction.cpp:181
bool isFixed(size_t i) const
Check if a parameter i is fixed.
Definition: IFunction.cpp:167
virtual void setActiveParameter(size_t i, double value)
Set new value of i-th active parameter.
Definition: IFunction.cpp:997
virtual void addConstraint(std::unique_ptr< IConstraint > ic)
Add a constraint to function.
Definition: IFunction.cpp:376
virtual size_t nAttributes() const
Returns the number of attributes associated with the function.
Definition: IFunction.cpp:1336
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.
Definition: IFunction.cpp:392
std::unique_ptr< FunctionHandler > m_handler
Pointer to a function handler.
Definition: IFunction.h:707
virtual size_t getNumberDomains() const
Get number of domains required by this function.
Definition: IFunction.cpp:1572
StepSizeMethod
Describes the method in which the step size will be calculated: DEFAULT: Uses the traditional Mantid ...
Definition: IFunction.h:658
bool m_isRegistered
whether the function usage has been registered
Definition: IFunction.h:726
std::shared_ptr< Kernel::Matrix< double > > m_covar
The covariance matrix of the fitting parameters.
Definition: IFunction.h:716
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.
Definition: ParameterTie.h:35
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.
Definition: IFunction.cpp:319
const IFunction & m_fun
The function that has the tie.
Definition: IFunction.cpp:321
bool operator()(const std::unique_ptr< T > &p)
Bracket operator.
Definition: IFunction.cpp:331
ReferenceEqual(const IFunction &fun, size_t i)
Constructor.
Definition: IFunction.cpp:327
const size_t m_i
index to find
Definition: IFunction.cpp:323
Store information about a fitting parameter such as its value if it is constrained or tied.
Definition: FitParameter.h:26
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:114
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
Numerical Matrix class.
Definition: Matrix.h:42
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
@ 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:732
Mantid::Kernel::StringTokenizer tokenizer
Definition: Expression.cpp:17
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition: IComponent.h:161
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:229
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)