BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
Fit::ResidualFunctionAdapter Class Reference
Inheritance diagram for Fit::ResidualFunctionAdapter:
Collaboration diagram for Fit::ResidualFunctionAdapter:

Public Member Functions

 ResidualFunctionAdapter (fcn_residual_t func, const Parameters &parameters)
 
const RootResidualFunctionrootResidualFunction ()
 
int numberOfCalls () const
 
int numberOfGradientCalls () const
 

Protected Attributes

int m_number_of_calls
 
int m_number_of_gradient_calls
 

Private Member Functions

void calculate_gradients (const std::vector< double > &pars)
 
std::vector< double > get_residuals (const std::vector< double > &pars)
 
double element_residual (const std::vector< double > &pars, unsigned int index, std::vector< double > &gradients)
 
double chi2 (const std::vector< double > &pars)
 

Private Attributes

size_t m_datasize
 
fcn_residual_t m_fcn
 
Parameters m_parameters
 
std::vector< double > m_residuals
 
std::vector< std::vector< double > > m_gradients
 
std::unique_ptr< RootResidualFunctionm_root_objective
 

Detailed Description

Provides RootResidualFunction which will be minimizer by ROOT.

Converts ROOT calls to the call of fcn_residual_t.

Definition at line 33 of file ResidualFunctionAdapter.h.

Constructor & Destructor Documentation

◆ ResidualFunctionAdapter()

ResidualFunctionAdapter::ResidualFunctionAdapter ( fcn_residual_t  func,
const Parameters parameters 
)

Definition at line 28 of file ResidualFunctionAdapter.cpp.

30  : m_datasize(0), m_fcn(func), m_parameters(parameters)
31 {
32  // single call of user function to get dataset size
33  auto residuals = m_fcn(parameters);
34  m_datasize = residuals.size();
35 }
fcn_residual_t m_fcn
user function to minimize
size_t m_datasize
Length of vector with residuals, should stay the same during minimization.

References m_datasize, and m_fcn.

Member Function Documentation

◆ rootResidualFunction()

const RootResidualFunction * ResidualFunctionAdapter::rootResidualFunction ( )

Definition at line 37 of file ResidualFunctionAdapter.cpp.

38 {
39  gradient_function_t gradient_fun = [&](const std::vector<double>& pars, unsigned int index,
40  std::vector<double>& gradients) {
41  return element_residual(pars, index, gradients);
42  };
43 
44  scalar_function_t objective_fun = [&](const std::vector<double>& pars) { return chi2(pars); };
45 
46  m_root_objective.reset(
47  new RootResidualFunction(objective_fun, gradient_fun, m_parameters.size(), m_datasize));
48 
49  return m_root_objective.get();
50 }
std::function< double(const std::vector< double > &)> scalar_function_t
Definition: KernelTypes.h:28
std::function< double(const std::vector< double > &, unsigned int, std::vector< double > &)> gradient_function_t
Definition: KernelTypes.h:31
size_t size() const
Definition: Parameters.cpp:51
double element_residual(const std::vector< double > &pars, unsigned int index, std::vector< double > &gradients)
evaluate method for gradients and residuals called directly from the minimizer
double chi2(const std::vector< double > &pars)
Evaluate chi2.
std::unique_ptr< RootResidualFunction > m_root_objective
Minimizer function with access to single data element residuals, required by Fumili2 and GSLMultiMin ...

References chi2(), element_residual(), m_datasize, m_parameters, m_root_objective, and Fit::Parameters::size().

Here is the call graph for this function:

◆ calculate_gradients()

void ResidualFunctionAdapter::calculate_gradients ( const std::vector< double > &  pars)
private

Definition at line 52 of file ResidualFunctionAdapter.cpp.

53 {
54  m_gradients.clear();
55  m_gradients.resize(pars.size());
56  for (size_t i_par = 0; i_par < pars.size(); ++i_par)
57  m_gradients[i_par].resize(m_datasize, 0.0);
58 
59  auto residuals = get_residuals(pars);
61 
62  for (size_t i_par = 0; i_par < pars.size(); ++i_par) {
63  std::vector<double> pars_deriv = pars; // values of parameters for derivative calculation
64  pars_deriv[i_par] += kEps;
65 
66  auto residuals2 = get_residuals(pars_deriv);
67 
68  for (size_t i_data = 0; i_data < m_datasize; ++i_data)
69  m_gradients[i_par][i_data] = (residuals2[i_data] - residuals[i_data]) / kEps;
70  }
71 }
std::vector< double > get_residuals(const std::vector< double > &pars)
std::vector< std::vector< double > > m_gradients

References get_residuals(), anonymous_namespace{ResidualFunctionAdapter.cpp}::kEps, m_datasize, m_gradients, and Fit::IFunctionAdapter::m_number_of_gradient_calls.

Referenced by element_residual().

Here is the call graph for this function:

◆ get_residuals()

std::vector< double > ResidualFunctionAdapter::get_residuals ( const std::vector< double > &  pars)
private

Definition at line 73 of file ResidualFunctionAdapter.cpp.

74 {
75  if (pars.size() != m_parameters.size()) {
76  std::ostringstream ostr;
77  ostr << "ResidualFunctionAdapter::residuals() -> Error. Number of fit parameters "
78  << "has changed in the course of minimization. Initially was " << m_parameters.size()
79  << " become " << pars.size() << "\n";
80  throw std::runtime_error(ostr.str());
81  }
82 
83  m_parameters.setValues(pars);
84  auto result = m_fcn(m_parameters);
85 
86  if (result.size() != m_datasize) {
87  std::ostringstream ostr;
88  ostr << "ResidualFunctionAdapter::residuals() -> Error. Size of data "
89  << "has changed in the course of minimization. Initial length " << m_datasize
90  << " new length " << result.size() << "\n";
91  throw std::runtime_error(ostr.str());
92  }
93  return result;
94 }
void setValues(const std::vector< double > &values)
Definition: Parameters.cpp:64

References m_datasize, m_fcn, m_parameters, Fit::Parameters::setValues(), and Fit::Parameters::size().

Referenced by calculate_gradients(), chi2(), and element_residual().

Here is the call graph for this function:

◆ element_residual()

double ResidualFunctionAdapter::element_residual ( const std::vector< double > &  pars,
unsigned int  index,
std::vector< double > &  gradients 
)
private

evaluate method for gradients and residuals called directly from the minimizer

Returns residual for given data element index.

If gradients vector size is not empty, also calculates gradients. Actuall calculation is done for all data elements when index==0. If index!=0 - cached value of residuals/gradients will be used.

Definition at line 100 of file ResidualFunctionAdapter.cpp.

102 {
103  if (index == 0) {
104  m_residuals = get_residuals(pars);
105  }
106 
107  if (!gradients.empty()) {
108  // Non zero size means that minimizer wants to know gradients.
109  if (pars.size() != gradients.size())
110  throw std::runtime_error("ResidualFunctionAdapter::element_residual() -> Error. "
111  "Number of gradients doesn't match number of fit parameters.");
112  if (index == 0)
113  calculate_gradients(pars);
114  for (size_t i_par = 0; i_par < pars.size(); ++i_par)
115  gradients[i_par] = m_gradients[i_par][index];
116  }
117 
118  return m_residuals[index];
119 }
void calculate_gradients(const std::vector< double > &pars)

References calculate_gradients(), get_residuals(), m_gradients, and m_residuals.

Referenced by rootResidualFunction().

Here is the call graph for this function:

◆ chi2()

double ResidualFunctionAdapter::chi2 ( const std::vector< double > &  pars)
private

Evaluate chi2.

Definition at line 121 of file ResidualFunctionAdapter.cpp.

122 {
124 
125  double result(0.0);
126  for (auto x : get_residuals(pars))
127  result += x * x;
128 
129  int fnorm = static_cast<int>(m_datasize) - static_cast<int>(m_parameters.freeParameterCount());
130  if (fnorm <= 0)
131  throw std::runtime_error("ResidualFunctionAdapter::chi2() -> Error. Normalization is 0");
132 
133  return result / fnorm;
134 }
size_t freeParameterCount() const
Returns number of free parameters.
Definition: Parameters.cpp:132

References Fit::Parameters::freeParameterCount(), get_residuals(), m_datasize, Fit::IFunctionAdapter::m_number_of_calls, and m_parameters.

Referenced by rootResidualFunction().

Here is the call graph for this function:

◆ numberOfCalls()

int IFunctionAdapter::numberOfCalls ( ) const
inherited

Definition at line 23 of file IFunctionAdapter.cpp.

24 {
25  return m_number_of_calls;
26 }

References Fit::IFunctionAdapter::m_number_of_calls.

◆ numberOfGradientCalls()

int IFunctionAdapter::numberOfGradientCalls ( ) const
inherited

Definition at line 28 of file IFunctionAdapter.cpp.

29 {
31 }

References Fit::IFunctionAdapter::m_number_of_gradient_calls.

Member Data Documentation

◆ m_datasize

size_t Fit::ResidualFunctionAdapter::m_datasize
private

Length of vector with residuals, should stay the same during minimization.

Definition at line 51 of file ResidualFunctionAdapter.h.

Referenced by calculate_gradients(), chi2(), get_residuals(), ResidualFunctionAdapter(), and rootResidualFunction().

◆ m_fcn

fcn_residual_t Fit::ResidualFunctionAdapter::m_fcn
private

user function to minimize

Definition at line 52 of file ResidualFunctionAdapter.h.

Referenced by get_residuals(), and ResidualFunctionAdapter().

◆ m_parameters

Parameters Fit::ResidualFunctionAdapter::m_parameters
private

Definition at line 53 of file ResidualFunctionAdapter.h.

Referenced by chi2(), get_residuals(), and rootResidualFunction().

◆ m_residuals

std::vector<double> Fit::ResidualFunctionAdapter::m_residuals
private

Definition at line 54 of file ResidualFunctionAdapter.h.

Referenced by element_residual().

◆ m_gradients

std::vector<std::vector<double> > Fit::ResidualFunctionAdapter::m_gradients
private

Definition at line 55 of file ResidualFunctionAdapter.h.

Referenced by calculate_gradients(), and element_residual().

◆ m_root_objective

std::unique_ptr<RootResidualFunction> Fit::ResidualFunctionAdapter::m_root_objective
private

Definition at line 56 of file ResidualFunctionAdapter.h.

Referenced by rootResidualFunction().

◆ m_number_of_calls

int Fit::IFunctionAdapter::m_number_of_calls
protectedinherited

◆ m_number_of_gradient_calls

int Fit::IFunctionAdapter::m_number_of_gradient_calls
protectedinherited

The documentation for this class was generated from the following files: