BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
ObjectiveMetricUtils.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Sim/Fitting/ObjectiveMetricUtils.cpp
6 //! @brief Implements ObjectiveMetric utilities.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
17 #include <algorithm>
18 #include <cmath>
19 #include <map>
20 #include <sstream>
21 
22 namespace {
23 
24 const std::function<double(double)> l1_norm = [](double term) { return std::abs(term); };
25 const std::function<double(double)> l2_norm = [](double term) { return term * term; };
26 
27 const std::map<std::string, std::function<std::unique_ptr<ObjectiveMetric>()>> metric_factory = {
28  {"chi2", []() { return std::make_unique<Chi2Metric>(); }},
29  {"poisson-like", []() { return std::make_unique<PoissonLikeMetric>(); }},
30  {"log", []() { return std::make_unique<LogMetric>(); }},
31  {"reldiff", []() { return std::make_unique<meanRelativeDifferenceMetric>(); }},
32  {"rq4", []() { return std::make_unique<RQ4Metric>(); }}};
33 const std::string default_metric_name = "poisson-like";
34 
35 const std::map<std::string, std::function<double(double)>> norm_factory = {{"l1", l1_norm},
36  {"l2", l2_norm}};
37 const std::string default_norm_name = "l2";
38 
39 template <class U>
40 std::vector<std::string> keys(const std::map<std::string, U>& map)
41 {
42  std::vector<std::string> result;
43  result.reserve(map.size());
44  for (auto& item : map)
45  result.push_back(item.first);
46  return result;
47 }
48 
49 } // namespace
50 
51 std::function<double(double)> ObjectiveMetricUtils::l1Norm()
52 {
53  return l1_norm;
54 }
55 
56 std::function<double(double)> ObjectiveMetricUtils::l2Norm()
57 {
58  return l2_norm;
59 }
60 
61 std::unique_ptr<ObjectiveMetric> ObjectiveMetricUtils::createMetric(const std::string& metric)
62 {
63  return createMetric(metric, defaultNormName());
64 }
65 
66 std::unique_ptr<ObjectiveMetric> ObjectiveMetricUtils::createMetric(std::string metric,
67  std::string norm)
68 {
69  std::transform(metric.begin(), metric.end(), metric.begin(), ::tolower);
70  std::transform(norm.begin(), norm.end(), norm.begin(), ::tolower);
71  const auto metric_iter = metric_factory.find(metric);
72  const auto norm_iter = norm_factory.find(norm);
73  if (metric_iter == metric_factory.end() || norm_iter == norm_factory.end()) {
74  std::stringstream ss;
75  ss << "Error in ObjectiveMetricUtils::createMetric: either metric (" << metric
76  << ") or norm (" << norm << ") name is unknown.\n";
77  ss << availableMetricOptions();
78  throw std::runtime_error(ss.str());
79  }
80 
81  auto result = metric_iter->second();
82  result->setNorm(norm_iter->second);
83  return result;
84 }
85 
87 {
88  std::stringstream ss;
89  ss << "Available metrics:\n";
90  for (auto& item : metricNames())
91  ss << "\t" << item << "\n";
92  ss << "default metric: " << defaultMetricName() << "\n";
93  ss << "Available norms:\n";
94  for (auto& item : normNames())
95  ss << "\t" << item << "\n";
96  ss << "default norm: " << defaultNormName() << "\n";
97  return ss.str();
98 }
99 
100 std::vector<std::string> ObjectiveMetricUtils::normNames()
101 {
102  return keys(norm_factory);
103 }
104 
105 std::vector<std::string> ObjectiveMetricUtils::metricNames()
106 {
107  return keys(metric_factory);
108 }
109 
111 {
112  return default_norm_name;
113 }
114 
116 {
117  return default_metric_name;
118 }
Defines ObjectiveMetric utilities and corresponding namespace.
Defines ObjectiveMetric classes.
std::string defaultMetricName()
Returns default metric name.
std::string defaultNormName()
Returns default norm name.
std::string availableMetricOptions()
Prints available metric options.
std::unique_ptr< ObjectiveMetric > createMetric(const std::string &metric)
Creates the specified metric with the default norm.
std::vector< std::string > metricNames()
Returns the names of the objective metrics used.
std::function< double(double)> l2Norm()
Returns L2 normalization function.
std::vector< std::string > normNames()
Returns the names of the norms used by ObjectiveMetric.
std::function< double(double)> l1Norm()
Returns L1 normalization function.