All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
FuncMinimum.cpp
Go to the documentation of this file.
1 // Include files
2 
3 #include <stdlib.h>
4 #include <stdio.h>
5 // from Gaudi
6 #include "GaudiKernel/MsgStream.h"
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  {
43  Genfun::GENFUNCTION fun = func.partial(i);
44  m_grad.push_back (fun.clone());
45  }
46 }
47 // ============================================================================
48 
49 //=============================================================================
50 // Standard constructor, initializes variables
51 //=============================================================================
52 FuncMinimum::FuncMinimum( const std::string& type,
53  const std::string& name,
54  const IInterface* parent )
55  : base_class ( type, name , parent )
56 {
58  declareProperty ( "Algorithm", m_algType );
60  declareProperty ( "Iteration", m_max_iter );
62  declareProperty ( "Gradient" , m_norm_gradient );
64  declareProperty ( "Step_size", m_step_size );
66  declareProperty ( "Tol" , m_tol );
67 }
68 //=============================================================================
69 namespace
70 {
71  using namespace Genfun;
73  double fun_gsl ( const gsl_vector* v ,
74  void * params)
75  {
77  static_cast <FuncMinimum::FuncMinimumMisc*> (params);
78  const FuncMinimum::GenFunc& eq = *(local->equation());
79  Argument& arg = local->argument() ;
80 
81  for (unsigned int i = 0; i < v->size; ++i) {
82  arg[i] = gsl_vector_get (v, i);
83  }
84 
85  return eq(arg);
86  }
87 
89  void dfun_gsl ( const gsl_vector* v , void * params,
90  gsl_vector* df )
91  {
93  static_cast <FuncMinimum::FuncMinimumMisc*> (params);
94  const FuncMinimum::Gradient& grad = local->gradient();
95  Argument& arg = local->argument() ;
96 
97  for ( unsigned int i = 0; i < v->size; ++i) {
98  arg[i] = gsl_vector_get (v, i);
99  }
100 
101 
102  for( unsigned int i = 0 ; i < df->size ; ++i )
103  {
104  Genfun::GENFUNCTION f = *(grad[i]);
105  gsl_vector_set ( df, i, f(arg) );
106  }
107 
108 
109  }
110 
113  void fdfun_gsl ( const gsl_vector* v ,
114  void* params ,
115  double* f ,
116  gsl_vector* df )
117  {
118  *f = fun_gsl( v , params );
119  dfun_gsl ( v , params, df);
120  }
121 
122 }
123 
124 //=============================================================================
130  IFuncMinimum::Arg& arg ) const
131 //=============================================================================
132 {
133  using namespace Genfun;
134 
135  gsl_vector_view vect = gsl_vector_view_array ( &arg[0] ,
136  arg.dimension() );
137  MsgStream log( msgSvc(), name() );
138 
139  FuncMinimumMisc local (func, arg);
140 
141  gsl_multimin_function_fdf function;
142 
143  function.f = &fun_gsl;
144  function.df = &dfun_gsl;
145  function.fdf = &fdfun_gsl;
146  function.n = vect.vector.size;
147  function.params = (void*) &local;
148 
149  size_t iter = 0 ;
150  int status = 0 ;
151  const gsl_multimin_fdfminimizer_type *T = m_type ;
152 
153  gsl_multimin_fdfminimizer *s;
154 
155  s = gsl_multimin_fdfminimizer_alloc ( T, vect.vector.size);
156 
157  gsl_multimin_fdfminimizer_set ( s, &function,
158  &vect.vector, m_step_size, m_tol);
159 
160  for( iter = 0 ; iter < m_max_iter ; ++iter )
161  {
162  status = gsl_multimin_fdfminimizer_iterate (s);
163 
164  if ( status )
165  {
166  return Error
167  ("Error from gsl_multimin_fdfminimizer_iterate '"
168  + std::string(gsl_strerror(status)) + "'") ;
169  }
170 
171  status = gsl_multimin_test_gradient (s->gradient,
172  m_norm_gradient);
173 
174 
175  if ( status != GSL_CONTINUE ) { break; }
176  }
177 
178  for (unsigned int i = 0; i < vect.vector.size; ++i)
179  {
180  gsl_vector_set (&vect.vector, i, gsl_vector_get (s->x, i));
181  }
182 
183  if (status == GSL_SUCCESS)
184  {
185  log << MSG::DEBUG
186  << "We stopped in the method on the " << iter
187  << " iteration (we have maximum " << m_max_iter
188  << " iterations)" << endmsg;
189 
190  log << "The Euclidean norm of gradient = "
191  << gsl_blas_dnrm2 (s->gradient)
192  << " by the absolute tolerance = "
193  << m_norm_gradient << endmsg;
194  }
195  else if (status == GSL_CONTINUE && iter <= m_max_iter )
196  {
197  return Error ( "Method finished with '"
198  + std::string(gsl_strerror(status))
199  + "' error" );
200  }
201  else
202  {
203  return Error ( "Method finished with '" +
204  std::string(gsl_strerror(status))
205  + "' error" );
206  }
207 
208  gsl_multimin_fdfminimizer_free (s);
209 
210  if (status)
211  {
212  return Error ( "Method finished with '"
213  + std::string(gsl_strerror(status))
214  + "' error" );
215  }
216 
217  return StatusCode::SUCCESS;
218 }
219 
220 //=============================================================================
226  IFuncMinimum::Arg& arg ,
227  IFuncMinimum::Covariance& covar ) const
228 //=============================================================================
229 {
230  MsgStream log( msgSvc(), name() );
231 
233  StatusCode sc = minimum (func, arg) ;
234 
235  if (sc.isFailure())
236  {
237  return Error ( "MINIMUM IS NOT FOUND. StatusCode = '"
238  + std::to_string( sc.getCode() ) + '\'',
239  sc );
240  }
241  else
242  {
243  HepSymMatrix cov(arg.dimension(), 0);
244  for (unsigned int i = 0; i < arg.dimension(); ++i)
245  {
246  Genfun::GENFUNCTION f = func.partial(i);
247  for (unsigned int j = i; j < arg.dimension(); ++j)
248  {
249  Genfun::GENFUNCTION fij = f.partial(j);
250  cov(i+1, j+1) = 0.5 * fij(arg);
251  }
252  }
253 
254  int inv;
255  covar = cov.inverse(inv);
256  if ( inv != 0)
257  {
258  return Error
259  ("Matrix of Error is not complete successful");
260  }
261 
262  return StatusCode::SUCCESS;
263  }
264 
265 }
266 
267 //=============================================================================
269 
270 {
272 
273  MsgStream log( msgSvc() , name() ) ;
274 
275  if ( sc.isFailure() )
276  {
277  return Error ("Could not initialize base class GaudiTool", sc);
278  }
279 
281  if( "conjugate_fr" == m_algType )
282  {
283  m_type = gsl_multimin_fdfminimizer_conjugate_fr ;
284  log << MSG::DEBUG
285  << "Minimization algorithm to be used: "
286  << "'gsl_multimin_fdfminimizer_conjugate_fr'"
287  << endmsg;
288  }
289  else if ( "conjugate_pr" == m_algType )
290  {
291  m_type = gsl_multimin_fdfminimizer_conjugate_pr ;
292  log << MSG::DEBUG
293  << "Minimization algorithm to be used: "
294  << "'gsl_multimin_fdfminimizer_conjugate_pr'"
295  << endmsg;
296  }
297  else if ( "vector_bfgs" == m_algType )
298  {
299  m_type = gsl_multimin_fdfminimizer_vector_bfgs ;
300  log << MSG::DEBUG
301  << "Minimization algorithm to be used: " <<
302  "'gsl_multimin_fdfminimizer_vector_bfgs'" << endmsg;
303  }
304  else if ( "steepest_descent" == m_algType )
305  {
306  m_type = gsl_multimin_fdfminimizer_steepest_descent ;
307  log << MSG::DEBUG
308  << "Minimization algorithm to be used: "
309  << "'gsl_multimin_fdfminimizer_steepest_descent'"
310  << endmsg;
311  }
312  else
313  {
314  return Error(" Unknown algorithm type '" + m_algType + "'");
315  }
316 
317  return StatusCode::SUCCESS;
318 }
319 //=============================================================================
321 {
323 
324  MsgStream log( msgSvc() , name() ) ;
325 
326  if ( sc.isFailure() )
327  {
328  return Error("Could not finalize base class GaudiTool", sc);
329  }
330  return StatusCode::SUCCESS;
331 }
332 //=============================================================================
333 
334 // Declaration of the Tool Factory
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
string to_string(const T &value)
Definition: mergesort.cpp:40
double m_norm_gradient
Definition: FuncMinimum.h:101
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
unsigned long getCode() const
Get the status code by value.
Definition: StatusCode.h:93
Genfun::Argument Arg
Argument of function "GenFunc" (.
Definition: IFuncMinimum.h:35
const Arg & argument() const
Definition: FuncMinimum.h:60
std::vector< const GenFunc * > Gradient
Definition: FuncMinimum.h:26
double m_tol
Definition: FuncMinimum.h:103
const GenFunc * equation() const
Definition: FuncMinimum.h:62
const gsl_multimin_fdfminimizer_type * m_type
Definition: FuncMinimum.h:104
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StatusCode minimum(const GenFunc &func, Arg &arg) const override
Find minimum of the function "GenFunc".
double m_step_size
Definition: FuncMinimum.h:102
int N
Definition: IOTest.py:90
Genfun::AbsFunction GenFunc
Function which we minimize (.
Definition: IFuncMinimum.h:33
std::string m_algType
Definition: FuncMinimum.h:99
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
Definition of the basic interface.
Definition: IInterface.h:234
The simplest concrete implementation of IFuncMinimum interface.
Definition: FuncMinimum.h:24
const Gradient & gradient() const
Definition: FuncMinimum.h:63
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
CLHEP::HepSymMatrix Covariance
Covariance matrix (matrix of error) (.
Definition: IFuncMinimum.h:37
double fun(const std::vector< double > &x)
Definition: PFuncTest.cpp:26
StatusCode finalize() override
standard finalization method
Definition: GaudiTool.cpp:179
string s
Definition: gaudirun.py:245
StatusCode finalize() override
CLHEP.
Definition: IEqSolver.h:13
FuncMinimum()=delete
default constructor is private
double m_max_iter
Definition: FuncMinimum.h:100
list i
Definition: ana.py:128
StatusCode initialize() override
standard initialization method
Definition: GaudiTool.cpp:161
StatusCode initialize() override
Overriding initialize.
string type
Definition: gaudirun.py:151