Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
GSLMinimizer1D.cxx
Go to the documentation of this file.
1 // @(#)root/mathmore:$Id$
2 // Authors: L. Moneta, A. Zsenei 08/2005
3  /**********************************************************************
4  * *
5  * Copyright (c) 2004 moneta, CERN/PH-SFT *
6  * *
7  * This library is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License *
9  * as published by the Free Software Foundation; either version 2 *
10  * of the License, or (at your option) any later version. *
11  * *
12  * This library is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this library (see file COPYING); if not, write *
19  * to the Free Software Foundation, Inc., 59 Temple Place, Suite *
20  * 330, Boston, MA 02111-1307 USA, or contact the author. *
21  * *
22  **********************************************************************/
23 
24 // Implementation file for class GSLMinimizer1D
25 //
26 // Created by: moneta at Wed Dec 1 15:04:51 2004
27 //
28 // Last update: Wed Dec 1 15:04:51 2004
29 //
30 
31 #include <assert.h>
32 
33 #include "Math/GSLMinimizer1D.h"
34 #include "Math/Error.h"
35 
36 #include "GSLFunctionWrapper.h"
37 #include "GSL1DMinimizerWrapper.h"
38 
39 
40 #include "gsl/gsl_min.h"
41 #include "gsl/gsl_errno.h"
42 
43 #include <iostream>
44 #include <cmath>
45 
46 namespace ROOT {
47 
48 namespace Math {
49 
50 
51 GSLMinimizer1D::GSLMinimizer1D(Minim1D::Type type) :
52  fXmin(0), fXlow(0), fXup(0), fMin(0), fLow(0), fUp(0),
53  fIter(0), fStatus(-1), fIsSet(false),
54  fMinimizer(0), fFunction(0)
55 {
56  // construct a minimizer passing the algorithm type as an enumeration
57 
58  const gsl_min_fminimizer_type* T = 0 ;
59  switch ( type )
60  {
61  case Minim1D::kGOLDENSECTION :
62  T = gsl_min_fminimizer_goldensection;
63  break ;
64  case Minim1D::kBRENT :
65  T = gsl_min_fminimizer_brent;
66  break ;
67  default :
68  // default case is brent
69  T = gsl_min_fminimizer_brent;
70  break ;
71  }
72 
73  fMinimizer = new GSL1DMinimizerWrapper(T);
74  fFunction = new GSLFunctionWrapper();
75 
76 }
77 
78 GSLMinimizer1D::~GSLMinimizer1D()
79 {
80  // destructor: clean up minimizer and function pointers
81 
82  if (fMinimizer) delete fMinimizer;
83  if (fFunction) delete fFunction;
84 }
85 
86 GSLMinimizer1D::GSLMinimizer1D(const GSLMinimizer1D &): IMinimizer1D()
87 {
88  // dummy copy ctr
89 }
90 
91 GSLMinimizer1D & GSLMinimizer1D::operator = (const GSLMinimizer1D &rhs)
92 {
93  // dummy operator =
94  if (this == &rhs) return *this; // time saving self-test
95  return *this;
96 }
97 
98 void GSLMinimizer1D::SetFunction( GSLFuncPointer f, void * p, double xmin, double xlow, double xup) {
99  // set the function to be minimized
100  assert(fFunction);
101  assert(fMinimizer);
102  fXlow = xlow;
103  fXup = xup;
104  fXmin = xmin;
105  fFunction->SetFuncPointer( f );
106  fFunction->SetParams( p );
107 
108 #ifdef DEBUG
109  std::cout << " [ "<< xlow << " , " << xup << " ]" << std::endl;
110 #endif
111 
112  int status = gsl_min_fminimizer_set( fMinimizer->Get(), fFunction->GetFunc(), xmin, xlow, xup);
113  if (status != GSL_SUCCESS)
114  std::cerr <<"GSLMinimizer1D: Error: Interval [ "<< xlow << " , " << xup << " ] does not contain a minimum" << std::endl;
115 
116 
117  fIsSet = true;
118  fStatus = -1;
119  return;
120 }
121 
122 int GSLMinimizer1D::Iterate() {
123  // perform an iteration and update values
124  if (!fIsSet) {
125  std::cerr << "GSLMinimizer1D- Error: Function has not been set in Minimizer" << std::endl;
126  return -1;
127  }
128 
129  int status = gsl_min_fminimizer_iterate(fMinimizer->Get());
130  // update values
131  fXmin = gsl_min_fminimizer_x_minimum(fMinimizer->Get() );
132  fMin = gsl_min_fminimizer_f_minimum(fMinimizer->Get() );
133  // update interval values
134  fXlow = gsl_min_fminimizer_x_lower(fMinimizer->Get() );
135  fXup = gsl_min_fminimizer_x_upper(fMinimizer->Get() );
136  fLow = gsl_min_fminimizer_f_lower(fMinimizer->Get() );
137  fUp = gsl_min_fminimizer_f_upper(fMinimizer->Get() );
138  return status;
139 }
140 
141 double GSLMinimizer1D::XMinimum() const {
142  // return x value at function minimum
143  return fXmin;
144 }
145 
146 double GSLMinimizer1D::XLower() const {
147  // return lower x value of bracketing interval
148  return fXlow;
149 }
150 
151 double GSLMinimizer1D::XUpper() const {
152  // return upper x value of bracketing interval
153  return fXup;
154 }
155 
156 double GSLMinimizer1D::FValMinimum() const {
157  // return function value at minimum
158  return fMin;
159 }
160 
161 double GSLMinimizer1D::FValLower() const {
162  // return function value at x lower
163  return fLow;
164 }
165 
166 double GSLMinimizer1D::FValUpper() const {
167  // return function value at x upper
168  return fUp;
169 }
170 
171 const char * GSLMinimizer1D::Name() const {
172  // return name of minimization algorithm
173  return gsl_min_fminimizer_name(fMinimizer->Get() );
174 }
175 
176 bool GSLMinimizer1D::Minimize (int maxIter, double absTol, double relTol)
177 {
178  // find the minimum via multiple iterations
179  fStatus = -1;
180  int iter = 0;
181  int status = 0;
182  do {
183  iter++;
184  status = Iterate();
185  if (status != GSL_SUCCESS) {
186  MATH_ERROR_MSG("GSLMinimizer1D::Minimize","error returned when performing an iteration");
187  fStatus = status;
188  return false;
189  }
190 
191 #ifdef DEBUG
192  std::cout << "Min1D - iteration " << iter << " interval : [ " << fXlow << " , " << fXup << " ] min = " << fXmin
193  << " fmin " << fMin << " f(a) " << fLow << " f(b) " << fUp << std::endl;
194 #endif
195 
196 
197  status = TestInterval(fXlow, fXup, absTol, relTol);
198  if (status == GSL_SUCCESS) {
199  fIter = iter;
200  fStatus = status;
201  return true;
202  }
203  }
204  while (status == GSL_CONTINUE && iter < maxIter);
205  if (status == GSL_CONTINUE) {
206  double tol = std::abs(fXup-fXlow);
207  MATH_INFO_MSGVAL("GSLMinimizer1D::Minimize","exceeded max iterations, reached tolerance is not sufficient",tol);
208  }
209  fStatus = status;
210  return false;
211 }
212 
213 
214 int GSLMinimizer1D::TestInterval( double xlow, double xup, double epsAbs, double epsRel) {
215 // static function to test interval
216  return gsl_min_test_interval(xlow, xup, epsAbs, epsRel);
217 }
218 
219 } // end namespace Math
220 
221 } // end namespace ROOT
222