// @(#)root/mathmore:$Id$
// Author: L. Moneta Thu Jan 25 11:13:48 2007

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 * This library is free software; you can redistribute it and/or      *
 * modify it under the terms of the GNU General Public License        *
 * as published by the Free Software Foundation; either version 2     *
 * of the License, or (at your option) any later version.             *
 *                                                                    *
 * This library is distributed in the hope that it will be useful,    *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   *
 * General Public License for more details.                           *
 *                                                                    *
 * You should have received a copy of the GNU General Public License  *
 * along with this library (see file COPYING); if not, write          *
 * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
 * 330, Boston, MA 02111-1307 USA, or contact the author.             *
 *                                                                    *
 **********************************************************************/

// Header file for class GSLSimAnnealing

#ifndef ROOT_Math_GSLSimAnnealing
#define ROOT_Math_GSLSimAnnealing

#include "Math/IFunctionfwd.h"

#include <vector>

namespace ROOT {

   namespace Math {

      class GSLRandomEngine;

//_____________________________________________________________________________
/**
   GSLSimAnFunc class description.
   Interface class for the  objetive function to be used in simulated annealing
   If user wants to re-implement some of the methods (like the one defining the metric) which are used by the
   the simulated annealing algorithm must build a user derived class.
   NOTE: Derived classes must re-implement the assignment and copy constructor to call them of the parent class

   @ingroup MultiMin
 */
class GSLSimAnFunc {
public:

   /**
      construct from an interface of a multi-dimensional function
    */
   GSLSimAnFunc(const ROOT::Math::IMultiGenFunction & func, const double * x);

   /**
      construct from an interface of a multi-dimensional function
      Use optionally a scale factor (for each coordinate) which can  be used to scale the step sizes
      (this is used for example by the minimization algorithm)
    */
   GSLSimAnFunc(const ROOT::Math::IMultiGenFunction & func, const double * x, const double * scale);

protected:

   /**
      derived classes might need to re-define completely the class
    */
   GSLSimAnFunc() :
      fFunc(0)
   {}

public:


   /// virtual distructor (no operations)
   virtual ~GSLSimAnFunc() { } //


   /**
      fast copy method called by GSL simuated annealing internally
      copy only the things which have been changed
      must be re-implemented by derived classes if needed
   */
   virtual GSLSimAnFunc & FastCopy(const GSLSimAnFunc & f);


   /**
      clone method. Needs to be re-implemented by the derived classes for deep  copying
    */
   virtual GSLSimAnFunc * Clone() const {
      return new GSLSimAnFunc(*this);
   }

   /**
      evaluate the energy ( objective function value)
      re-implement by derived classes if needed to be modified
    */
   virtual double Energy() const;

   /**
      change the x[i] value using a random value urndm generated between [0,1]
      up to a maximum value maxstep
      re-implement by derived classes if needed to be modified
    */
   virtual void Step(const GSLRandomEngine & r, double maxstep);

   /**
      calculate the distance (metric) between  this one and another configuration
      Presently a cartesian metric is used.
      re-implement by derived classes if needed to be modified
    */
   virtual double Distance(const GSLSimAnFunc & func) const;

   /**
      print the position in the standard output std::ostream
      GSL prints in addition n iteration, n function calls, temperature and energy
      re-implement by derived classes if necessary
    */
   virtual void Print();

   /**
       change the x values (used by sim annealing to take a step)
    */
   void SetX(const double * x) {
      std::copy(x, x+ fX.size(), fX.begin() );
   }

   template <class IT>
   void SetX(IT begin, IT end) {
      std::copy(begin, end, fX.begin() );
   }

   unsigned int NDim() const { return fX.size(); }

   double X(unsigned int i) const { return fX[i]; }

   const std::vector<double> &  X() const { return fX; }

   double Scale(unsigned int i) const { return fScale[i]; }

   void SetX(unsigned int i, double x) { fX[i] = x; }

   // use compiler generated  copy ctror and assignment operators

private:

   std::vector<double>  fX;
   std::vector<double>  fScale;
   const ROOT::Math::IMultiGenFunction * fFunc;

};

//_____________________________________________________
/**
    structure holding the simulated annealing parameters

   @ingroup MultiMin
*/
struct GSLSimAnParams {

   // constructor with some default values
   GSLSimAnParams() {
      n_tries =    200;
      iters_fixed_T =  10;
      step_size =   10;
      // the following parameters are for the Boltzmann distribution */
      k = 1.0;
      t_initial =  0.002;
      mu =  1.005;
      t_min = 2.0E-6;
   }


   int n_tries;            // number of points to try for each step
   int iters_fixed_T;      // number of iterations at each temperature
   double step_size;       // max step size used in random walk
   /// parameters for the Boltzman distribution
   double k;
   double t_initial;
   double mu;
   double t_min;
};

//___________________________________________________________________________
/**
   GSLSimAnnealing class for performing  a simulated annealing search of
   a multidimensional function

   @ingroup MultiMin
*/
class GSLSimAnnealing {

public:

   /**
      Default constructor
   */
   GSLSimAnnealing ();

   /**
      Destructor (no operations)
   */
   ~GSLSimAnnealing ()  {}

private:
   // usually copying is non trivial, so we make this unaccessible

   /**
      Copy constructor
   */
   GSLSimAnnealing(const GSLSimAnnealing &) {}

   /**
      Assignment operator
   */
   GSLSimAnnealing & operator = (const GSLSimAnnealing & rhs)  {
      if (this == &rhs) return *this;  // time saving self-test
      return *this;
   }

public:


   /**
      solve the simulated annealing given a multi-dim function, the initial vector parameters
      and a vector containing the scaling factors for the parameters
   */
   int Solve(const ROOT::Math::IMultiGenFunction & func, const double * x0, const double * scale, double * xmin, bool debug = false);

   /**
      solve the simulated annealing given a GSLSimAnFunc object
      The object will contain the initial state at the beginning and the final minimum state at the end
   */
   int Solve(GSLSimAnFunc & func, bool debug = false);


   GSLSimAnParams & Params() { return fParams; }
   const GSLSimAnParams & Params() const { return fParams; }


protected:


private:

   GSLSimAnParams fParams; // parameters for GSLSimAnnealig

};

   } // end namespace Math

} // end namespace ROOT


#endif /* ROOT_Math_GSLSimAnnealing */
 GSLSimAnnealing.h:1
 GSLSimAnnealing.h:2
 GSLSimAnnealing.h:3
 GSLSimAnnealing.h:4
 GSLSimAnnealing.h:5
 GSLSimAnnealing.h:6
 GSLSimAnnealing.h:7
 GSLSimAnnealing.h:8
 GSLSimAnnealing.h:9
 GSLSimAnnealing.h:10
 GSLSimAnnealing.h:11
 GSLSimAnnealing.h:12
 GSLSimAnnealing.h:13
 GSLSimAnnealing.h:14
 GSLSimAnnealing.h:15
 GSLSimAnnealing.h:16
 GSLSimAnnealing.h:17
 GSLSimAnnealing.h:18
 GSLSimAnnealing.h:19
 GSLSimAnnealing.h:20
 GSLSimAnnealing.h:21
 GSLSimAnnealing.h:22
 GSLSimAnnealing.h:23
 GSLSimAnnealing.h:24
 GSLSimAnnealing.h:25
 GSLSimAnnealing.h:26
 GSLSimAnnealing.h:27
 GSLSimAnnealing.h:28
 GSLSimAnnealing.h:29
 GSLSimAnnealing.h:30
 GSLSimAnnealing.h:31
 GSLSimAnnealing.h:32
 GSLSimAnnealing.h:33
 GSLSimAnnealing.h:34
 GSLSimAnnealing.h:35
 GSLSimAnnealing.h:36
 GSLSimAnnealing.h:37
 GSLSimAnnealing.h:38
 GSLSimAnnealing.h:39
 GSLSimAnnealing.h:40
 GSLSimAnnealing.h:41
 GSLSimAnnealing.h:42
 GSLSimAnnealing.h:43
 GSLSimAnnealing.h:44
 GSLSimAnnealing.h:45
 GSLSimAnnealing.h:46
 GSLSimAnnealing.h:47
 GSLSimAnnealing.h:48
 GSLSimAnnealing.h:49
 GSLSimAnnealing.h:50
 GSLSimAnnealing.h:51
 GSLSimAnnealing.h:52
 GSLSimAnnealing.h:53
 GSLSimAnnealing.h:54
 GSLSimAnnealing.h:55
 GSLSimAnnealing.h:56
 GSLSimAnnealing.h:57
 GSLSimAnnealing.h:58
 GSLSimAnnealing.h:59
 GSLSimAnnealing.h:60
 GSLSimAnnealing.h:61
 GSLSimAnnealing.h:62
 GSLSimAnnealing.h:63
 GSLSimAnnealing.h:64
 GSLSimAnnealing.h:65
 GSLSimAnnealing.h:66
 GSLSimAnnealing.h:67
 GSLSimAnnealing.h:68
 GSLSimAnnealing.h:69
 GSLSimAnnealing.h:70
 GSLSimAnnealing.h:71
 GSLSimAnnealing.h:72
 GSLSimAnnealing.h:73
 GSLSimAnnealing.h:74
 GSLSimAnnealing.h:75
 GSLSimAnnealing.h:76
 GSLSimAnnealing.h:77
 GSLSimAnnealing.h:78
 GSLSimAnnealing.h:79
 GSLSimAnnealing.h:80
 GSLSimAnnealing.h:81
 GSLSimAnnealing.h:82
 GSLSimAnnealing.h:83
 GSLSimAnnealing.h:84
 GSLSimAnnealing.h:85
 GSLSimAnnealing.h:86
 GSLSimAnnealing.h:87
 GSLSimAnnealing.h:88
 GSLSimAnnealing.h:89
 GSLSimAnnealing.h:90
 GSLSimAnnealing.h:91
 GSLSimAnnealing.h:92
 GSLSimAnnealing.h:93
 GSLSimAnnealing.h:94
 GSLSimAnnealing.h:95
 GSLSimAnnealing.h:96
 GSLSimAnnealing.h:97
 GSLSimAnnealing.h:98
 GSLSimAnnealing.h:99
 GSLSimAnnealing.h:100
 GSLSimAnnealing.h:101
 GSLSimAnnealing.h:102
 GSLSimAnnealing.h:103
 GSLSimAnnealing.h:104
 GSLSimAnnealing.h:105
 GSLSimAnnealing.h:106
 GSLSimAnnealing.h:107
 GSLSimAnnealing.h:108
 GSLSimAnnealing.h:109
 GSLSimAnnealing.h:110
 GSLSimAnnealing.h:111
 GSLSimAnnealing.h:112
 GSLSimAnnealing.h:113
 GSLSimAnnealing.h:114
 GSLSimAnnealing.h:115
 GSLSimAnnealing.h:116
 GSLSimAnnealing.h:117
 GSLSimAnnealing.h:118
 GSLSimAnnealing.h:119
 GSLSimAnnealing.h:120
 GSLSimAnnealing.h:121
 GSLSimAnnealing.h:122
 GSLSimAnnealing.h:123
 GSLSimAnnealing.h:124
 GSLSimAnnealing.h:125
 GSLSimAnnealing.h:126
 GSLSimAnnealing.h:127
 GSLSimAnnealing.h:128
 GSLSimAnnealing.h:129
 GSLSimAnnealing.h:130
 GSLSimAnnealing.h:131
 GSLSimAnnealing.h:132
 GSLSimAnnealing.h:133
 GSLSimAnnealing.h:134
 GSLSimAnnealing.h:135
 GSLSimAnnealing.h:136
 GSLSimAnnealing.h:137
 GSLSimAnnealing.h:138
 GSLSimAnnealing.h:139
 GSLSimAnnealing.h:140
 GSLSimAnnealing.h:141
 GSLSimAnnealing.h:142
 GSLSimAnnealing.h:143
 GSLSimAnnealing.h:144
 GSLSimAnnealing.h:145
 GSLSimAnnealing.h:146
 GSLSimAnnealing.h:147
 GSLSimAnnealing.h:148
 GSLSimAnnealing.h:149
 GSLSimAnnealing.h:150
 GSLSimAnnealing.h:151
 GSLSimAnnealing.h:152
 GSLSimAnnealing.h:153
 GSLSimAnnealing.h:154
 GSLSimAnnealing.h:155
 GSLSimAnnealing.h:156
 GSLSimAnnealing.h:157
 GSLSimAnnealing.h:158
 GSLSimAnnealing.h:159
 GSLSimAnnealing.h:160
 GSLSimAnnealing.h:161
 GSLSimAnnealing.h:162
 GSLSimAnnealing.h:163
 GSLSimAnnealing.h:164
 GSLSimAnnealing.h:165
 GSLSimAnnealing.h:166
 GSLSimAnnealing.h:167
 GSLSimAnnealing.h:168
 GSLSimAnnealing.h:169
 GSLSimAnnealing.h:170
 GSLSimAnnealing.h:171
 GSLSimAnnealing.h:172
 GSLSimAnnealing.h:173
 GSLSimAnnealing.h:174
 GSLSimAnnealing.h:175
 GSLSimAnnealing.h:176
 GSLSimAnnealing.h:177
 GSLSimAnnealing.h:178
 GSLSimAnnealing.h:179
 GSLSimAnnealing.h:180
 GSLSimAnnealing.h:181
 GSLSimAnnealing.h:182
 GSLSimAnnealing.h:183
 GSLSimAnnealing.h:184
 GSLSimAnnealing.h:185
 GSLSimAnnealing.h:186
 GSLSimAnnealing.h:187
 GSLSimAnnealing.h:188
 GSLSimAnnealing.h:189
 GSLSimAnnealing.h:190
 GSLSimAnnealing.h:191
 GSLSimAnnealing.h:192
 GSLSimAnnealing.h:193
 GSLSimAnnealing.h:194
 GSLSimAnnealing.h:195
 GSLSimAnnealing.h:196
 GSLSimAnnealing.h:197
 GSLSimAnnealing.h:198
 GSLSimAnnealing.h:199
 GSLSimAnnealing.h:200
 GSLSimAnnealing.h:201
 GSLSimAnnealing.h:202
 GSLSimAnnealing.h:203
 GSLSimAnnealing.h:204
 GSLSimAnnealing.h:205
 GSLSimAnnealing.h:206
 GSLSimAnnealing.h:207
 GSLSimAnnealing.h:208
 GSLSimAnnealing.h:209
 GSLSimAnnealing.h:210
 GSLSimAnnealing.h:211
 GSLSimAnnealing.h:212
 GSLSimAnnealing.h:213
 GSLSimAnnealing.h:214
 GSLSimAnnealing.h:215
 GSLSimAnnealing.h:216
 GSLSimAnnealing.h:217
 GSLSimAnnealing.h:218
 GSLSimAnnealing.h:219
 GSLSimAnnealing.h:220
 GSLSimAnnealing.h:221
 GSLSimAnnealing.h:222
 GSLSimAnnealing.h:223
 GSLSimAnnealing.h:224
 GSLSimAnnealing.h:225
 GSLSimAnnealing.h:226
 GSLSimAnnealing.h:227
 GSLSimAnnealing.h:228
 GSLSimAnnealing.h:229
 GSLSimAnnealing.h:230
 GSLSimAnnealing.h:231
 GSLSimAnnealing.h:232
 GSLSimAnnealing.h:233
 GSLSimAnnealing.h:234
 GSLSimAnnealing.h:235
 GSLSimAnnealing.h:236
 GSLSimAnnealing.h:237
 GSLSimAnnealing.h:238
 GSLSimAnnealing.h:239
 GSLSimAnnealing.h:240
 GSLSimAnnealing.h:241
 GSLSimAnnealing.h:242
 GSLSimAnnealing.h:243
 GSLSimAnnealing.h:244
 GSLSimAnnealing.h:245
 GSLSimAnnealing.h:246
 GSLSimAnnealing.h:247
 GSLSimAnnealing.h:248
 GSLSimAnnealing.h:249
 GSLSimAnnealing.h:250
 GSLSimAnnealing.h:251
 GSLSimAnnealing.h:252
 GSLSimAnnealing.h:253
 GSLSimAnnealing.h:254
 GSLSimAnnealing.h:255
 GSLSimAnnealing.h:256
 GSLSimAnnealing.h:257