SourceXtractorPlusPlus  0.8
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LevmarEngine.cpp
Go to the documentation of this file.
1 
23 #include <cmath>
24 #include <mutex>
25 
26 #include <levmar.h>
30 
31 
32 namespace ModelFitting {
33 
34 static std::shared_ptr<LeastSquareEngine> createLevmarEngine(unsigned max_iterations) {
35  return std::make_shared<LevmarEngine>(max_iterations);
36 }
37 
39 
40 LevmarEngine::LevmarEngine(size_t itmax, double tau, double epsilon1,
41  double epsilon2, double epsilon3, double delta)
42  : m_itmax{itmax}, m_opts{tau, epsilon1, epsilon2, epsilon3, delta} { }
43 
44 LevmarEngine::~LevmarEngine() = default;
45 
46 
47 #ifdef LINSOLVERS_RETAIN_MEMORY
48 // If the Levmar library is not configured for multithreading, this mutex is used to ensure only one thread
49 // at a time can enter levmar
50 namespace {
51  std::mutex levmar_mutex;
52 }
53 #endif
54 
56  ResidualEstimator& residual_estimator) {
57  // Create a tuple which keeps the references to the given manager and estimator
58  auto adata = std::tie(parameter_manager, residual_estimator);
59 
60  // The function which is called by the levmar loop
61  auto levmar_res_func = [](double *p, double *hx, int, int, void *extra) {
62 #ifdef LINSOLVERS_RETAIN_MEMORY
63  levmar_mutex.unlock();
64 #endif
65  auto* extra_ptr = (decltype(adata)*)extra;
66  EngineParameterManager& pm = std::get<0>(*extra_ptr);
67  pm.updateEngineValues(p);
68  ResidualEstimator& re = std::get<1>(*extra_ptr);
69  re.populateResiduals(hx);
70 
71 #ifdef LINSOLVERS_RETAIN_MEMORY
72  levmar_mutex.lock();
73 #endif
74  };
75 
76  // Create the vector which will be used for keeping the parameter values
77  // and initialize it to the current values of the parameters
78  std::vector<double> param_values (parameter_manager.numberOfParameters());
79  parameter_manager.getEngineValues(param_values.begin());
80 
81  // Create a vector for getting the information of the minimization
83 
84  std::vector<double> covariance_matrix (parameter_manager.numberOfParameters() * parameter_manager.numberOfParameters());
85 
86 #ifdef LINSOLVERS_RETAIN_MEMORY
87  levmar_mutex.lock();
88 #endif
89  // Call the levmar library
90  auto res = dlevmar_dif(levmar_res_func, // The function called from the levmar algorithm
91  param_values.data(), // The pointer where the parameter values are
92  NULL, // We don't use any measurement vector
93  parameter_manager.numberOfParameters(), // The number of free parameters
94  residual_estimator.numberOfResiduals(), // The number of residuals
95  m_itmax, // The maximum number of iterations
96  m_opts.data(), // The minimization options
97  info.data(), // Where the information of the minimization is stored
98  NULL, // Working memory is allocated internally
99  covariance_matrix.data(),
100  &adata // No additional data needed
101  );
102 #ifdef LINSOLVERS_RETAIN_MEMORY
103  levmar_mutex.unlock();
104 #endif
105 
106  // Create and return the summary object
107  LeastSquareSummary summary {};
108 
109  auto converted_covariance_matrix = parameter_manager.convertCovarianceMatrixToWorldSpace(covariance_matrix);
110  for (unsigned int i=0; i<parameter_manager.numberOfParameters(); i++) {
111  summary.parameter_sigmas.push_back(sqrt(converted_covariance_matrix[i*(parameter_manager.numberOfParameters()+1)]));
112  }
113 
114  summary.success_flag = (res != -1);
115  summary.iteration_no = info[5];
116  summary.underlying_framework_info = info;
117  return summary;
118 }
119 
120 } // end of namespace ModelFitting
virtual ~LevmarEngine()
Destructor.
T tie(T...args)
Class containing the summary information of solving a least square minimization problem.
void populateResiduals(DoubleIter output_iter) const
void getEngineValues(DoubleIter output_iter) const
Returns the engine values of the managed parameters.
void updateEngineValues(DoubleIter new_values_iter)
Updates the managed parameters with the given engine values.
T push_back(T...args)
T data(T...args)
static std::shared_ptr< LeastSquareEngine > createLevmarEngine(unsigned max_iterations)
Definition: GSLEngine.cpp:18
std::vector< double > m_opts
Definition: LevmarEngine.h:72
LevmarEngine(size_t itmax=1000, double tau=1E-3, double epsilon1=1E-8, double epsilon2=1E-8, double epsilon3=1E-8, double delta=1E-4)
Constructs a new instance of the engine.
std::size_t numberOfResiduals() const
static LeastSquareEngineManager::StaticEngine levmar_engine
Definition: GSLEngine.cpp:22
STL class.
Class responsible for managing the parameters the least square engine minimizes.
std::vector< double > convertCovarianceMatrixToWorldSpace(std::vector< double > covariance_matrix) const
T sqrt(T...args)
LeastSquareSummary solveProblem(EngineParameterManager &parameter_manager, ResidualEstimator &residual_estimator) override
Provides to the LeastSquareEngine the residual values.
std::size_t numberOfParameters()
Returns the number of parameters managed by the manager.