SourceXtractorPlusPlus  0.8
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataVsModelResiduals.icpp
Go to the documentation of this file.
1 
23 namespace ModelFitting {
24 
25 template <typename DataType, typename ModelType, typename WeightType, typename Comparator>
27  DataType data, ModelType model, WeightType weight, Comparator comparator)
28  : m_data{std::move(data)}, m_model{std::move(model)}, m_weight{std::move(weight)},
29  m_comparator(std::move(comparator)), m_residual_no{DataTraits::size(m_data)} {
30  if (DataTraits::size(m_data) != ModelTraits::size(m_model)) {
31  throw Elements::Exception() << "Data size (" << DataTraits::size(m_data)
32  << ") is different than model size (" << ModelTraits::size(m_model) << ")";
33  }
34  if (DataTraits::size(m_data) != WeightTraits::size(m_weight)) {
35  throw Elements::Exception() << "Data size (" << DataTraits::size(m_data)
36  << ") is different than weight size (" << WeightTraits::size(m_weight) << ")";
37  }
38 }
39 
40 template <typename DataType, typename ModelType, typename WeightType, typename Comparator>
42 
43 template <typename DataType, typename ModelType, typename WeightType, typename Comparator>
45  return m_residual_no;
46 }
47 
48 template <typename DataType, typename ModelType, typename WeightType, typename Comparator>
50  auto data_iter = DataTraits::begin(m_data);
51  auto model_iter = ModelTraits::begin(m_model);
52  auto weight_iter = WeightTraits::begin(m_weight);
53 // double test = 0;
54 // static double diff = 0;
55  for (; data_iter!=DataTraits::end(m_data); ++data_iter, ++model_iter, ++weight_iter, ++output_iter) {
56  *output_iter = m_comparator(*data_iter, *model_iter, *weight_iter);
57 // test += *output_iter;
58  }
59 // std::cout << test << " -- " << test-diff << "\n";
60 // diff = test;
61 }
62 
63 // NOTE TO DEVELOPERS:
64 //
65 // The following factory function looks (and is) complicated, but it greatly
66 // simplifies the code using the library. For example, using the factory method,
67 // the code for creating a DataVsModelResiduals looks like:
68 //
69 // std::vector<double> data = ...;
70 // std::vector<double> model = ...;
71 // std::vector<double> weights = ...;
72 // auto res_prov = createDataVsModelResiduals(data, model, weights, ChiSquareComparator{});
73 //
74 // The equivalent command when using directly the constructor would be:
75 //
76 // std::vector<double> data = ...;
77 // std::vector<double> model = ...;
78 // std::vector<double> weights = ...;
79 // unique_ptr<DataVsModelResiduals<std::vector<double>, std::vector<double>,
80 // std::vector<double>, ChiSquareComparator>> res_prov {
81 // new DataVsModelResiduals<std::vector<double>, std::vector<double>,
82 // std::vector<double>, ChiSquareComparator> {
83 // y_data, model, weight, ChiSquareComparator{}
84 // }
85 // };
86 //
87 // The above shows the importance of the existence of this factory. Here are
88 // some tips, to help you understand how the function works:
89 //
90 // - The function perfect-forwards its parameters to the constructor, so it can
91 // be the exact equivalent with calling the constructor, regardless the
92 // r-valueness or l-valueness of the parameters. If you don't know what the
93 // perfect forwarding is, search the internet for a good explanation before
94 // you continue trying to understand this code.
95 //
96 // - The template parameters of the factory method are NOT the same with the ones
97 // of the DataVsModelResiduals object being created. This is a result of the
98 // use of the perfect forwarding. More precisely, the template types of the
99 // factory method are lvalue or rvalue REFERENCES (which is how perfect
100 // forwarding works), when the template types of the DataVsModelResiduals are
101 // the actual types (and no references to them).
102 //
103 // - The "typename std::remove_reference<...>::type" (which is used a lot bellow)
104 // simply removes any reference from the type, creating the proper template
105 // parameter for the DataVsModelResiduals class. The keyword "typename" has to
106 // be used because, during the first passage, the compiler will fail to recognize
107 // that the "std::remove_reference<...>::type" is an existing type (because
108 // it contains a template parameter itself).
109 //
110 // I hope the above will help you to understand how the factory method works.
111 template <typename DataType, typename ModelType, typename WeightType, typename Comparator>
116  > createDataVsModelResiduals(DataType&& data, ModelType&& model,
117  WeightType&& weight, Comparator&& comparator) {
122  > {
124  typename std::remove_reference<ModelType>::type,
125  typename std::remove_reference<WeightType>::type,
127  std::forward<DataType>(data), std::forward<ModelType>(model),
128  std::forward<WeightType>(weight), std::forward<Comparator>(comparator)
129  }
130  };
131 }
132 
133 } // end of namespace ModelFitting
std::size_t numberOfResiduals() const override
void populateResidualBlock(IterType output_iter) override
Updates the values where the iterator points with the residuals.
T move(T...args)
virtual ~DataVsModelResiduals()
Destructor.
DataVsModelResiduals(DataType data, ModelType model, WeightType weight, Comparator comparator)
Constructs a new instance of DataVsModelResiduals.
STL class.
std::unique_ptr< DataVsModelResiduals< typename std::remove_reference< DataType >::type, typename std::remove_reference< ModelType >::type, typename std::remove_reference< WeightType >::type, typename std::remove_reference< Comparator >::type > > createDataVsModelResiduals(DataType &&data, ModelType &&model, WeightType &&weight, Comparator &&comparator)
ResidualBlockProvider for weighted comparison between data and a model.