8 #include "gsl/gsl_blas.h" 9 #include "gsl/gsl_errno.h" 10 #include "gsl/gsl_linalg.h" 11 #include "gsl/gsl_math.h" 12 #include "gsl/gsl_matrix.h" 13 #include "gsl/gsl_multimin.h" 14 #include "gsl/gsl_vector.h" 23 using namespace CLHEP;
35 : m_argum( arg ), m_eq( &func ), m_grad()
37 const size_t N = func.dimensionality();
39 for (
size_t i = 0; i <
N; ++i ) {
40 Genfun::GENFUNCTION
fun = func.partial( i );
41 m_grad.push_back( fun.clone() );
49 double fun_gsl(
const gsl_vector* v,
void* params )
52 const FuncMinimum::GenFunc& eq = *( local->
equation() );
55 for (
unsigned int i = 0; i < v->size; ++i ) {
56 arg[i] = gsl_vector_get( v, i );
63 void dfun_gsl(
const gsl_vector* v,
void* params, gsl_vector* df )
69 for (
unsigned int i = 0; i < v->size; ++i ) {
70 arg[i] = gsl_vector_get( v, i );
73 for (
unsigned int i = 0; i < df->size; ++i ) {
74 Genfun::GENFUNCTION f = *( grad[i] );
75 gsl_vector_set( df, i, f( arg ) );
81 void fdfun_gsl(
const gsl_vector* v,
void* params,
double* f, gsl_vector* df )
83 *f = fun_gsl( v, params );
84 dfun_gsl( v, params, df );
98 gsl_vector_view vect = gsl_vector_view_array( &arg[0], arg.dimension() );
99 FuncMinimumMisc local( func, arg );
101 gsl_multimin_function_fdf
function;
103 function.f = &fun_gsl;
104 function.df = &dfun_gsl;
105 function.fdf = &fdfun_gsl;
106 function.n = vect.vector.size;
107 function.params = (
void*)&local;
111 const gsl_multimin_fdfminimizer_type* T =
m_type;
113 gsl_multimin_fdfminimizer*
s;
115 s = gsl_multimin_fdfminimizer_alloc( T, vect.vector.size );
117 gsl_multimin_fdfminimizer_set( s, &
function, &vect.vector, m_step_size, m_tol );
120 status = gsl_multimin_fdfminimizer_iterate( s );
123 return Error(
"Error from gsl_multimin_fdfminimizer_iterate '" +
std::string( gsl_strerror( status ) ) +
"'" );
126 status = gsl_multimin_test_gradient( s->gradient, m_norm_gradient );
128 if ( status != GSL_CONTINUE ) {
133 for (
unsigned int i = 0; i < vect.vector.size; ++i ) {
134 gsl_vector_set( &vect.vector, i, gsl_vector_get( s->x, i ) );
137 if ( status == GSL_SUCCESS ) {
138 debug() <<
"We stopped in the method on the " << iter <<
" iteration (we have maximum " << m_max_iter
139 <<
" iterations)" <<
endmsg;
141 msgStream() <<
"The Euclidean norm of gradient = " << gsl_blas_dnrm2( s->gradient )
142 <<
" by the absolute tolerance = " << m_norm_gradient <<
endmsg;
143 }
else if ( status == GSL_CONTINUE && iter <= m_max_iter ) {
144 return Error(
"Method finished with '" +
std::string( gsl_strerror( status ) ) +
"' error" );
146 return Error(
"Method finished with '" +
std::string( gsl_strerror( status ) ) +
"' error" );
149 gsl_multimin_fdfminimizer_free( s );
152 return Error(
"Method finished with '" +
std::string( gsl_strerror( status ) ) +
"' error" );
173 HepSymMatrix cov( arg.dimension(), 0 );
174 for (
unsigned int i = 0; i < arg.dimension(); ++i ) {
175 auto f = func.partial( i );
176 for (
unsigned int j = i; j < arg.dimension(); ++j ) {
177 auto fij = f.partial( j );
178 cov( i + 1, j + 1 ) = 0.5 * fij( arg );
183 covar = cov.inverse( inv );
194 return Error(
"Could not initialize base class GaudiTool", sc );
199 m_type = gsl_multimin_fdfminimizer_conjugate_fr;
200 debug() <<
"Minimization algorithm to be used: " 201 <<
"'gsl_multimin_fdfminimizer_conjugate_fr'" <<
endmsg;
202 }
else if (
"conjugate_pr" ==
m_algType ) {
203 m_type = gsl_multimin_fdfminimizer_conjugate_pr;
204 debug() <<
"Minimization algorithm to be used: " 205 <<
"'gsl_multimin_fdfminimizer_conjugate_pr'" <<
endmsg;
206 }
else if (
"vector_bfgs" ==
m_algType ) {
207 m_type = gsl_multimin_fdfminimizer_vector_bfgs;
208 debug() <<
"Minimization algorithm to be used: " 209 <<
"'gsl_multimin_fdfminimizer_vector_bfgs'" <<
endmsg;
210 }
else if (
"steepest_descent" ==
m_algType ) {
211 m_type = gsl_multimin_fdfminimizer_steepest_descent;
212 debug() <<
"Minimization algorithm to be used: " 213 <<
"'gsl_multimin_fdfminimizer_steepest_descent'" <<
endmsg;
Genfun::Argument Arg
Argument of function "GenFunc" (.
const Arg & argument() const
const GenFunc * equation() const
#define DECLARE_COMPONENT(type)
Gaudi::Property< std::string > m_algType
Gaudi::Property< double > m_max_iter
This class is used for returning status codes from appropriate routines.
Genfun::AbsFunction GenFunc
Function which we minimize (.
CLHEP::HepSymMatrix Covariance
Covariance matrix (matrix of error) (.
The simplest concrete implementation of IFuncMinimum interface.
constexpr static const auto SUCCESS
const Gradient & gradient() const
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
StatusCode minimum(const GenFunc &func, Arg &arg) const override
Find minimum of the function "GenFunc".
double fun(const std::vector< double > &x)
MsgStream & msgStream() const
Return an uninitialized MsgStream.
const gsl_multiroot_fdfsolver_type * m_type
code_t getCode() const
Retrieve value ("checks" the StatusCode)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
StatusCode initialize() override
Overriding initialize.