BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
DiffUtil.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Histo/DiffUtil.cpp
6 //! @brief Implements namespace DataUtils.
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 
15 #include "Device/Histo/DiffUtil.h"
16 #include "Base/Axis/Bin.h"
17 #include "Base/Axis/FixedBinAxis.h"
18 #include "Base/Axis/Frame.h"
19 #include "Base/Axis/IAxis.h"
20 #include "Base/Math/Numeric.h"
21 #include "Base/Util/Assert.h"
22 #include "Device/Data/Datafield.h"
24 #include <algorithm>
25 #include <iostream>
26 
27 //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).
28 double DiffUtil::meanRelVecDiff(const std::vector<double>& dat, const std::vector<double>& ref)
29 {
30  ASSERT(dat.size() == ref.size());
31  double diff = 0;
32  for (size_t i = 0; i < dat.size(); ++i)
33  diff += Numeric::relativeDifference(dat[i], ref[i]);
34  diff /= dat.size();
35  ASSERT(!std::isnan(diff));
36  return diff;
37 }
38 
40 {
41  ASSERT(dat.hasSameShape(ref));
42  std::vector<double> out(dat.size());
43  for (size_t i = 0; i < dat.size(); ++i)
44  out[i] = Numeric::relativeDifference(dat.valAt(i), ref.valAt(i));
45  return new Datafield(dat.frame().cloned_axes(), out);
46 }
47 
48 //! Returns sum of relative differences between each pair of elements:
49 //! (a, b) -> 2*abs(a - b)/(|a| + |b|) ( and zero if a=b=0 within epsilon )
51 {
52  if (dat.size() != ref.size())
53  throw std::runtime_error("Error in DiffUtil::meanRelativeDifference: "
54  "different number of elements");
55  if (dat.empty())
56  return 0.0;
57  double sum_of_diff = 0.0;
58  for (size_t i = 0; i < dat.size(); ++i)
59  sum_of_diff += Numeric::relativeDifference(dat[i], ref[i]);
60  return sum_of_diff / dat.size();
61 }
62 
63 //! Returns true is relative difference is below threshold; prints informative output
64 bool DiffUtil::checkRelativeDifference(const std::vector<double>& dat,
65  const std::vector<double>& ref, const double threshold)
66 {
67  if (*std::min_element(dat.begin(), dat.end()) == 0
68  && *std::max_element(dat.begin(), dat.end()) == 0) {
69  std::cerr << "FAILED: simulated data set is empty" << std::endl;
70  return false;
71  }
72 
73  try {
74  const double diff = DiffUtil::meanRelVecDiff(dat, ref);
75  if (diff > threshold) {
76  std::cerr << "FAILED: relative deviation of dat from ref is " << diff
77  << ", above given threshold " << threshold << std::endl;
78  return false;
79  }
80  if (diff)
81  std::cerr << "- OK: relative deviation of dat from ref is " << diff
82  << ", within given threshold " << threshold << std::endl;
83  else
84  std::cout << "- OK: dat = ref\n";
85  return true;
86  } catch (...) {
87  return false;
88  }
89 }
Defines the macro ASSERT.
#define ASSERT(condition)
Definition: Assert.h:45
Defines structs Bin1D, Bin1DCVector.
Defines and implements templated class Datafield.
Defines namespace DataUtils.
Defines class FixedBinAxis.
Defines and implements templated class Frame.
Defines interface IAxis.
Defines constants and "almost equal" in namespace Numeric.
Defines class SimulationResult.
Stores radiation power per bin.
Definition: Datafield.h:30
double valAt(size_t i) const
Definition: Datafield.cpp:58
bool hasSameShape(const Datafield &other) const
Returns true if objects a) have same dimensions b) bin boundaries of axes coincide.
Definition: Datafield.cpp:114
size_t size() const
Returns total size of data buffer (product of bin number in every dimension).
Definition: Datafield.cpp:80
const Frame & frame() const
Definition: Datafield.cpp:86
std::vector< IAxis * > cloned_axes() const
Returns cloned axes.
Definition: Frame.cpp:32
Wrapper around Datafield that also provides unit conversions.
bool empty() const
size_t size() const
Datafield * relativeDifferenceField(const Datafield &dat, const Datafield &ref)
Returns Datafield representing relative difference of two histograms.
Definition: DiffUtil.cpp:39
double meanRelVecDiff(const std::vector< double > &dat, const std::vector< double > &ref)
Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]).
Definition: DiffUtil.cpp:28
bool checkRelativeDifference(const std::vector< double > &dat, const std::vector< double > &ref, double threshold)
Returns true is relative difference is below threshold; prints informative output.
Definition: DiffUtil.cpp:64
double meanRelativeDifference(const SimulationResult &dat, const SimulationResult &ref)
Returns sum of relative differences between each pair of elements: (a, b) -> 2*abs(a - b)/(a + b) ( a...
Definition: DiffUtil.cpp:50
double relativeDifference(double a, double b)
Returns the safe relative difference, which is 2(|a-b|)/(|a|+|b|) except in special cases.
Definition: Numeric.cpp:29