The Gaudi Framework  v28r3 (cc1cf868)
FuncMinimum.cpp
Go to the documentation of this file.
1 // Include files
2 
3 #include <cstdlib>
4 #include <cstdio>
5 // from Gaudi
7 //from GSL
8 #include "gsl/gsl_vector.h"
9 #include "gsl/gsl_multimin.h"
10 #include "gsl/gsl_math.h"
11 #include "gsl/gsl_matrix.h"
12 #include "gsl/gsl_linalg.h"
13 #include "gsl/gsl_blas.h"
14 #include "gsl/gsl_errno.h"
15 
16 // local
17 #include "FuncMinimum.h"
18 
19 // Handle CLHEP 2.0.x move to CLHEP namespace
20 namespace CLHEP { }
21 using namespace CLHEP;
22 
30 // ============================================================================
31 // ============================================================================
33 ( const FuncMinimum::GenFunc& func ,
34  FuncMinimum::Arg& arg )
35  : m_argum ( arg )
36  , m_eq ( &func )
37  , m_grad ()
38 {
39  const size_t N = func.dimensionality () ;
40 
41  for( size_t i = 0 ; i < N ; ++i ) {
42  Genfun::GENFUNCTION fun = func.partial(i);
43  m_grad.push_back (fun.clone());
44  }
45 }
46 //=============================================================================
47 namespace
48 {
49  using namespace Genfun;
51  double fun_gsl ( const gsl_vector* v ,
52  void * params)
53  {
55  static_cast <FuncMinimum::FuncMinimumMisc*> (params);
56  const FuncMinimum::GenFunc& eq = *(local->equation());
57  Argument& arg = local->argument() ;
58 
59  for (unsigned int i = 0; i < v->size; ++i) {
60  arg[i] = gsl_vector_get (v, i);
61  }
62 
63  return eq(arg);
64  }
65 
67  void dfun_gsl ( const gsl_vector* v , void * params,
68  gsl_vector* df )
69  {
71  static_cast <FuncMinimum::FuncMinimumMisc*> (params);
72  const FuncMinimum::Gradient& grad = local->gradient();
73  Argument& arg = local->argument() ;
74 
75  for ( unsigned int i = 0; i < v->size; ++i) {
76  arg[i] = gsl_vector_get (v, i);
77  }
78 
79  for( unsigned int i = 0 ; i < df->size ; ++i ) {
80  Genfun::GENFUNCTION f = *(grad[i]);
81  gsl_vector_set ( df, i, f(arg) );
82  }
83 
84 
85  }
86 
89  void fdfun_gsl ( const gsl_vector* v ,
90  void* params ,
91  double* f ,
92  gsl_vector* df )
93  {
94  *f = fun_gsl( v , params );
95  dfun_gsl ( v , params, df);
96  }
97 
98 }
99 
100 //=============================================================================
106  IFuncMinimum::Arg& arg ) const
107 //=============================================================================
108 {
109  using namespace Genfun;
110 
111  gsl_vector_view vect = gsl_vector_view_array ( &arg[0] ,
112  arg.dimension() );
113  FuncMinimumMisc local (func, arg);
114 
115  gsl_multimin_function_fdf function;
116 
117  function.f = &fun_gsl;
118  function.df = &dfun_gsl;
119  function.fdf = &fdfun_gsl;
120  function.n = vect.vector.size;
121  function.params = (void*) &local;
122 
123  size_t iter = 0 ;
124  int status = 0 ;
125  const gsl_multimin_fdfminimizer_type *T = m_type ;
126 
127  gsl_multimin_fdfminimizer *s;
128 
129  s = gsl_multimin_fdfminimizer_alloc ( T, vect.vector.size);
130 
131  gsl_multimin_fdfminimizer_set ( s, &function,
132  &vect.vector, m_step_size, m_tol);
133 
134  for( iter = 0 ; iter < m_max_iter ; ++iter ) {
135  status = gsl_multimin_fdfminimizer_iterate (s);
136 
137  if ( status ) {
138  return Error
139  ("Error from gsl_multimin_fdfminimizer_iterate '"
140  + std::string(gsl_strerror(status)) + "'") ;
141  }
142 
143  status = gsl_multimin_test_gradient (s->gradient,
144  m_norm_gradient);
145 
146 
147  if ( status != GSL_CONTINUE ) { break; }
148  }
149 
150  for (unsigned int i = 0; i < vect.vector.size; ++i) {
151  gsl_vector_set (&vect.vector, i, gsl_vector_get (s->x, i));
152  }
153 
154  if (status == GSL_SUCCESS) {
155  debug()
156  << "We stopped in the method on the " << iter
157  << " iteration (we have maximum " << m_max_iter
158  << " iterations)" << endmsg;
159 
160  msgStream() << "The Euclidean norm of gradient = "
161  << gsl_blas_dnrm2 (s->gradient)
162  << " by the absolute tolerance = "
163  << m_norm_gradient << endmsg;
164  } else if (status == GSL_CONTINUE && iter <= m_max_iter ) {
165  return Error ( "Method finished with '"
166  + std::string(gsl_strerror(status))
167  + "' error" );
168  } else {
169  return Error ( "Method finished with '" +
170  std::string(gsl_strerror(status))
171  + "' error" );
172  }
173 
174  gsl_multimin_fdfminimizer_free (s);
175 
176  if (status) {
177  return Error ( "Method finished with '"
178  + std::string(gsl_strerror(status))
179  + "' error" );
180  }
181 
182  return StatusCode::SUCCESS;
183 }
184 
185 //=============================================================================
191  IFuncMinimum::Arg& arg ,
192  IFuncMinimum::Covariance& covar ) const
193 //=============================================================================
194 {
196  StatusCode sc = minimum (func, arg) ;
197 
198  if (sc.isFailure()) {
199  return Error ( "MINIMUM IS NOT FOUND. StatusCode = '"
200  + std::to_string( sc.getCode() ) + '\'',
201  sc );
202  }
203  HepSymMatrix cov(arg.dimension(), 0);
204  for (unsigned int i = 0; i < arg.dimension(); ++i) {
205  auto f = func.partial(i);
206  for (unsigned int j = i; j < arg.dimension(); ++j) {
207  auto fij = f.partial(j);
208  cov(i+1, j+1) = 0.5 * fij(arg);
209  }
210  }
211 
212  int inv;
213  covar = cov.inverse(inv);
214  return inv == 0 ? StatusCode::SUCCESS
215  : Error ("Matrix of Error is not complete successful");
216 }
217 
218 //=============================================================================
220 
221 {
223 
224  if ( sc.isFailure() ) {
225  return Error ("Could not initialize base class GaudiTool", sc);
226  }
227 
229  if( "conjugate_fr" == m_algType ) {
230  m_type = gsl_multimin_fdfminimizer_conjugate_fr ;
231  debug()
232  << "Minimization algorithm to be used: "
233  << "'gsl_multimin_fdfminimizer_conjugate_fr'"
234  << endmsg;
235  } else if ( "conjugate_pr" == m_algType ) {
236  m_type = gsl_multimin_fdfminimizer_conjugate_pr ;
237  debug()
238  << "Minimization algorithm to be used: "
239  << "'gsl_multimin_fdfminimizer_conjugate_pr'"
240  << endmsg;
241  } else if ( "vector_bfgs" == m_algType ) {
242  m_type = gsl_multimin_fdfminimizer_vector_bfgs ;
243  debug()
244  << "Minimization algorithm to be used: " <<
245  "'gsl_multimin_fdfminimizer_vector_bfgs'" << endmsg;
246  } else if ( "steepest_descent" == m_algType ) {
247  m_type = gsl_multimin_fdfminimizer_steepest_descent ;
248  debug()
249  << "Minimization algorithm to be used: "
250  << "'gsl_multimin_fdfminimizer_steepest_descent'"
251  << endmsg;
252  } else {
253  return Error(" Unknown algorithm type '" + m_algType + "'");
254  }
255 
256  return StatusCode::SUCCESS;
257 }
258 //=============================================================================
259 
260 // Declaration of the Tool Factory
Genfun::Argument Arg
Argument of function "GenFunc" (.
Definition: IFuncMinimum.h:34
unsigned long getCode() const
Get the status code by value.
Definition: StatusCode.h:91
T to_string(T...args)
const Arg & argument() const
Definition: FuncMinimum.h:54
const GenFunc * equation() const
Definition: FuncMinimum.h:56
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
STL class.
Gaudi::Property< std::string > m_algType
Definition: EqSolver.h:80
int N
Definition: IOTest.py:90
Gaudi::Property< double > m_max_iter
Definition: EqSolver.h:82
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Genfun::AbsFunction GenFunc
Function which we minimize (.
Definition: IFuncMinimum.h:32
CLHEP::HepSymMatrix Covariance
Covariance matrix (matrix of error) (.
Definition: IFuncMinimum.h:36
The simplest concrete implementation of IFuncMinimum interface.
Definition: FuncMinimum.h:24
const Gradient & gradient() const
Definition: FuncMinimum.h:57
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
StatusCode Error(const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const
Print the error message and return with the given StatusCode.
Definition: GaudiTool.h:671
StatusCode minimum(const GenFunc &func, Arg &arg) const override
Find minimum of the function "GenFunc".
double fun(const std::vector< double > &x)
Definition: PFuncTest.cpp:26
MsgStream & msgStream() const
Return an uninitialized MsgStream.
string s
Definition: gaudirun.py:245
const gsl_multiroot_fdfsolver_type * m_type
Definition: EqSolver.h:85
CLHEP.
Definition: IEqSolver.h:13
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode initialize() override
standard initialization method
Definition: GaudiTool.cpp:157
StatusCode initialize() override
Overriding initialize.