SourceXtractorPlusPlus 1.0.3
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
FlexibleModelFittingParameter.cpp
Go to the documentation of this file.
1
17/*
18 * FlexibleModelFittingParameter.cpp
19 *
20 * Created on: Oct 8, 2018
21 * Author: mschefer
22 */
23
24#include <iostream>
25
26#include <boost/version.hpp>
27#if BOOST_VERSION >= 106700
28
29#if BOOST_VERSION >= 107000
30#include <boost/math/differentiation/finite_difference.hpp>
31namespace bmd = boost::math::differentiation;
32#else
33#include <boost/math/tools/numerical_differentiation.hpp>
34namespace bmd = boost::math::tools;
35#endif
36
37#endif
38
39#include "AlexandriaKernel/memory_tools.h"
40#include "ElementsKernel/Logging.h"
45
52
53
55
56
57namespace SourceXtractor {
58
59using namespace ModelFitting;
60
62
64 return m_id;
65}
66
69
76
78 FlexibleModelFittingParameterManager& /*parameter_manager*/,
80 const SourceInterface& source) const {
81 double initial_value = m_initial_value(source);
82
83 auto converter = m_converter_factory->getConverter(initial_value, source);
84 auto parameter = std::make_shared<EngineParameter>(initial_value, std::move(converter));
85 engine_manager.registerParameter(parameter);
86
87 return parameter;
88}
89
91 FlexibleModelFittingParameterManager& /*parameter_manager*/,
93 const SourceInterface& source,
94 double initial_value, double current_value) const {
95 auto converter = m_converter_factory->getConverter(initial_value, source);
96 auto parameter = std::make_shared<EngineParameter>(current_value, std::move(converter));
97 engine_manager.registerParameter(parameter);
98
99 return parameter;
100}
101
103 const std::vector<double>& free_parameter_sigmas) const {
104 auto modelfitting_parameter = parameter_manager.getParameter(source, shared_from_this());
105 return free_parameter_sigmas[parameter_manager.getParameterIndex(source, shared_from_this())];
106}
107
109 return m_initial_value(source);
110}
111
112namespace {
113
114template <typename T>
115double doubleResolver(const T&) {
116 return 0;
117}
118
119
120template<typename ... Parameters>
121std::shared_ptr<ModelFitting::BasicParameter> createDependentParameterHelper(
122 FlexibleModelFittingParameterManager& parameter_manager,
123 const SourceInterface& source,
125 std::shared_ptr<Parameters>... parameters) {
126
127 auto coordinate_system = source.getProperty<ReferenceCoordinates>().getCoordinateSystem();
128 auto calc = [value_calculator, coordinate_system] (decltype(doubleResolver(std::declval<Parameters>()))... params) -> double {
129 std::vector<double> materialized{params...};
130 return value_calculator(coordinate_system, materialized);
131 };
132 return createDependentParameter(calc, parameter_manager.getParameter(source, parameters)...);
133}
134
135}
136
137
139 FlexibleModelFittingParameterManager& parameter_manager,
141 const SourceInterface& source) const {
142 switch (m_parameters.size()) {
143 case 1:
144 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
145 m_parameters[0]);
146 case 2:
147 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
149 case 3:
150 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
152 case 4:
153 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
155 case 5:
156 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
158 case 6:
159 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
161 m_parameters[5]);
162 case 7:
163 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
166 case 8:
167 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
170 case 9:
171 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
174 case 10:
175 return createDependentParameterHelper(parameter_manager, source, m_value_calculator,
178 }
179 throw Elements::Exception() << "Dependent parameters can depend on maximum 10 other parameters";
180}
181
183 const SourceInterface& source, const std::vector<double>& param_values) const {
184 assert(param_values.size() == m_parameters.size());
185
186 std::vector<double> result(param_values.size());
187 auto cs = source.getProperty<ReferenceCoordinates>().getCoordinateSystem();
188
189 for (unsigned int i = 0; i < result.size(); i++) {
190
191 auto f = [&](double x) {
192 auto params = param_values;
193 params[i] = x;
194 return m_value_calculator(cs, params);
195 };
196
197#if BOOST_VERSION >= 106700
198 result[i] = bmd::finite_difference_derivative(f, param_values[i]);
199#else
200 // if boost's function is unavailable use our own function
201 result[i] = NumericalDerivative::centralDifference(f, param_values[i]);
202#endif
203 }
204
205 return result;
206}
207
209 const std::vector<double>& free_parameter_sigmas) const {
210 auto dependees = getDependees();
211 std::vector<double> values;
212
213 for (auto& dependee : dependees) {
214 values.emplace_back(parameter_manager.getParameter(source, dependee)->getValue());
215 }
216
217 double sigma = 0.0;
218 auto partial_derivatives = getPartialDerivatives(source, values);
219
220 assert(dependees.size() == partial_derivatives.size());
221 for (unsigned int i = 0; i < partial_derivatives.size(); i++) {
222 auto dependee_sigma = dependees[i]->getSigma(parameter_manager, source, free_parameter_sigmas);
223 sigma += partial_derivatives[i] * partial_derivatives[i] * dependee_sigma * dependee_sigma;
224 }
225 sigma = sqrt(sigma);
226
227 return sigma;
228}
229
230}
static Elements::Logging logger
static Logging getLogger(const std::string &name="")
virtual double getValue() const
Class responsible for managing the parameters the least square engine minimizes.
void registerParameter(std::shared_ptr< EngineParameter > parameter)
Registers an EngineParameter to the EngineParameterManager.
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
std::function< double(const SourceInterface &)> ValueFunc
std::function< double(const std::shared_ptr< CoordinateSystem > &, const std::vector< double > &)> ValueFunc
std::vector< std::shared_ptr< FlexibleModelFittingParameter > > m_parameters
double getSigma(FlexibleModelFittingParameterManager &parameter_manager, const SourceInterface &source, const std::vector< double > &free_parameter_sigmas) const override
const std::vector< std::shared_ptr< FlexibleModelFittingParameter > > & getDependees() const
std::vector< double > getPartialDerivatives(const SourceInterface &source, const std::vector< double > &param_values) const
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
double getSigma(FlexibleModelFittingParameterManager &parameter_manager, const SourceInterface &source, const std::vector< double > &free_parameter_sigmas) const override
double getInitialValue(const SourceInterface &source) const
std::shared_ptr< FlexibleModelFittingConverterFactory > m_converter_factory
std::shared_ptr< ModelFitting::BasicParameter > create(FlexibleModelFittingParameterManager &parameter_manager, ModelFitting::EngineParameterManager &engine_manager, const SourceInterface &source) const override
int getParameterIndex(std::shared_ptr< ModelFitting::BasicParameter > engine_parameter) const
std::shared_ptr< ModelFitting::BasicParameter > getParameter(const SourceInterface &source, std::shared_ptr< const FlexibleModelFittingParameter > parameter) const
static double centralDifference(std::function< double(double)> f, double x)
The SourceInterface is an abstract "source" that has properties attached to it.
const PropertyType & getProperty(unsigned int index=0) const
Convenience template method to call getProperty() with a more user-friendly syntax.
T declval(T... args)
T emplace_back(T... args)
T make_shared(T... args)
T move(T... args)
std::shared_ptr< DependentParameter< Parameters... > > createDependentParameter(typename DependentParameter< Parameters... >::ValueCalculator value_calculator, Parameters... parameters)
T size(T... args)
T sqrt(T... args)