// @(#)root/mathmore:$Id$
// Author: L. Moneta 2009

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/
// Header file for class MinimizerVariable

#ifndef ROOT_Math_MinimizerVariable
#define ROOT_Math_MinimizerVariable

#ifndef ROOT_Math_MinimizerVariableTransformation
#include "MinimizerVariableTransformation.h"
#endif

#include <memory>

namespace ROOT {

   namespace Math {

      /**
         Enumeration describing the status of the variable
         The enumeration are used in the minimizer classes to categorize the variables
      */
      enum EMinimVariableType {
         kDefault,    // free variable (unlimited)
         kFix,        // fixed variable
         kBounds,     //  variable has two bounds
         kLowBound,   // variable has a lower bound
         kUpBound     // variable has an upper bounds
      };



/**
   MinimTransformVariable class
   Contains meta information of the variables such as bounds, fix flags and
   deals with transformation of the variable
   The class does not contain the values and the step size (error) of the variable
   This is an internal class used by the MinimTransformFunction class

   @ingroup MultiMin
*/


class MinimTransformVariable {

public:

   /**
     Default Constructor for  an unlimited variable
   */
   MinimTransformVariable () :
      fFix(false), fLowBound(false), fUpBound(false), fBounds(false),
      fTransform(0), fLower(1), fUpper(0)
   {}

   // constructor for fixed variable
   MinimTransformVariable (double value) :
      fFix(true), fLowBound(false), fUpBound(false), fBounds(false),
      fTransform(0), fLower(value), fUpper(value)
   {}

   // constructor for double bound variable
   MinimTransformVariable (double lower, double upper, SinVariableTransformation * trafo) :
      fFix(false), fLowBound(false), fUpBound(false), fBounds(true),
      fTransform(trafo),
      fLower(lower), fUpper(upper)
   {   }

   // constructor for lower bound variable
   MinimTransformVariable (double lower, SqrtLowVariableTransformation * trafo) :
      fFix(false), fLowBound(true), fUpBound(false), fBounds(false),
      fTransform(trafo), fLower(lower), fUpper(lower)
   {}

   // constructor for upper bound variable
   MinimTransformVariable (double upper, SqrtUpVariableTransformation * trafo) :
      fFix(false), fLowBound(true), fUpBound(false), fBounds(false),
      fTransform(trafo), fLower(upper), fUpper(upper)
   {}

   // copy constructor
   MinimTransformVariable (const MinimTransformVariable & rhs) :
      fFix(rhs.fFix), fLowBound(rhs.fLowBound), fUpBound(rhs.fUpBound), fBounds(rhs.fBounds),
      fLower(rhs.fLower), fUpper(rhs.fUpper)
   {
      // swap auto_ptr
      fTransform.reset( const_cast<MinimTransformVariable &>( rhs).fTransform.release() ) ;
   }

   // assignment
   MinimTransformVariable & operator= (const MinimTransformVariable & rhs) {
      if (&rhs == this) return *this;
      fFix = rhs.fFix;
      fLowBound = rhs.fLowBound;
      fUpBound  = rhs.fUpBound;
      fBounds   = rhs.fBounds;
      fLower = rhs.fLower;  fUpper = rhs.fUpper;

      // swap auto_ptr
      fTransform.reset( const_cast<MinimTransformVariable &>( rhs).fTransform.release() ) ;
      return *this;
   }


   bool IsFixed() const { return fFix; }

   bool IsLimited() const { return fBounds || fLowBound || fUpBound; }

   bool HasLowerBound() const { return fLowBound || fBounds; }

   bool HasUpperBound() const { return fUpBound || fBounds; }

   double LowerBound() const { return fLower; }

   double UpperBound() const { return fUpper; }

   double FixValue() const { return fLower; }

   // internal to external transformation
   double InternalToExternal( double x) const {
      return (fTransform.get() ) ? fTransform->Int2ext(x, fLower, fUpper) : x;
   }

   // derivative of the internal to external transformation ( d Int2Ext / d int )
   double DerivativeIntToExt ( double x) const {
      return (fTransform.get() ) ? fTransform->DInt2Ext( x, fLower, fUpper) : 1.0;
   }

   // etxernal to internal transformation
   double ExternalToInternal(double x) const {
      return (fTransform.get() ) ? fTransform->Ext2int(x, fLower, fUpper) : x;
   }

private:

   bool fFix;         // fix variable
   bool fLowBound;    // has lower bound
   bool fUpBound;     // has uppper bound param
   bool fBounds;      // has double bound
   std::auto_ptr< MinimizerVariableTransformation> fTransform; // pointer to the minimizer transformation
   double fLower;   // lower parameter limit
   double fUpper;   // upper parameter limit

};

   } // end namespace Math

} // end namespace ROOT


#endif /* ROOT_Math_MinimTransformVariable */


 MinimTransformVariable.h:1
 MinimTransformVariable.h:2
 MinimTransformVariable.h:3
 MinimTransformVariable.h:4
 MinimTransformVariable.h:5
 MinimTransformVariable.h:6
 MinimTransformVariable.h:7
 MinimTransformVariable.h:8
 MinimTransformVariable.h:9
 MinimTransformVariable.h:10
 MinimTransformVariable.h:11
 MinimTransformVariable.h:12
 MinimTransformVariable.h:13
 MinimTransformVariable.h:14
 MinimTransformVariable.h:15
 MinimTransformVariable.h:16
 MinimTransformVariable.h:17
 MinimTransformVariable.h:18
 MinimTransformVariable.h:19
 MinimTransformVariable.h:20
 MinimTransformVariable.h:21
 MinimTransformVariable.h:22
 MinimTransformVariable.h:23
 MinimTransformVariable.h:24
 MinimTransformVariable.h:25
 MinimTransformVariable.h:26
 MinimTransformVariable.h:27
 MinimTransformVariable.h:28
 MinimTransformVariable.h:29
 MinimTransformVariable.h:30
 MinimTransformVariable.h:31
 MinimTransformVariable.h:32
 MinimTransformVariable.h:33
 MinimTransformVariable.h:34
 MinimTransformVariable.h:35
 MinimTransformVariable.h:36
 MinimTransformVariable.h:37
 MinimTransformVariable.h:38
 MinimTransformVariable.h:39
 MinimTransformVariable.h:40
 MinimTransformVariable.h:41
 MinimTransformVariable.h:42
 MinimTransformVariable.h:43
 MinimTransformVariable.h:44
 MinimTransformVariable.h:45
 MinimTransformVariable.h:46
 MinimTransformVariable.h:47
 MinimTransformVariable.h:48
 MinimTransformVariable.h:49
 MinimTransformVariable.h:50
 MinimTransformVariable.h:51
 MinimTransformVariable.h:52
 MinimTransformVariable.h:53
 MinimTransformVariable.h:54
 MinimTransformVariable.h:55
 MinimTransformVariable.h:56
 MinimTransformVariable.h:57
 MinimTransformVariable.h:58
 MinimTransformVariable.h:59
 MinimTransformVariable.h:60
 MinimTransformVariable.h:61
 MinimTransformVariable.h:62
 MinimTransformVariable.h:63
 MinimTransformVariable.h:64
 MinimTransformVariable.h:65
 MinimTransformVariable.h:66
 MinimTransformVariable.h:67
 MinimTransformVariable.h:68
 MinimTransformVariable.h:69
 MinimTransformVariable.h:70
 MinimTransformVariable.h:71
 MinimTransformVariable.h:72
 MinimTransformVariable.h:73
 MinimTransformVariable.h:74
 MinimTransformVariable.h:75
 MinimTransformVariable.h:76
 MinimTransformVariable.h:77
 MinimTransformVariable.h:78
 MinimTransformVariable.h:79
 MinimTransformVariable.h:80
 MinimTransformVariable.h:81
 MinimTransformVariable.h:82
 MinimTransformVariable.h:83
 MinimTransformVariable.h:84
 MinimTransformVariable.h:85
 MinimTransformVariable.h:86
 MinimTransformVariable.h:87
 MinimTransformVariable.h:88
 MinimTransformVariable.h:89
 MinimTransformVariable.h:90
 MinimTransformVariable.h:91
 MinimTransformVariable.h:92
 MinimTransformVariable.h:93
 MinimTransformVariable.h:94
 MinimTransformVariable.h:95
 MinimTransformVariable.h:96
 MinimTransformVariable.h:97
 MinimTransformVariable.h:98
 MinimTransformVariable.h:99
 MinimTransformVariable.h:100
 MinimTransformVariable.h:101
 MinimTransformVariable.h:102
 MinimTransformVariable.h:103
 MinimTransformVariable.h:104
 MinimTransformVariable.h:105
 MinimTransformVariable.h:106
 MinimTransformVariable.h:107
 MinimTransformVariable.h:108
 MinimTransformVariable.h:109
 MinimTransformVariable.h:110
 MinimTransformVariable.h:111
 MinimTransformVariable.h:112
 MinimTransformVariable.h:113
 MinimTransformVariable.h:114
 MinimTransformVariable.h:115
 MinimTransformVariable.h:116
 MinimTransformVariable.h:117
 MinimTransformVariable.h:118
 MinimTransformVariable.h:119
 MinimTransformVariable.h:120
 MinimTransformVariable.h:121
 MinimTransformVariable.h:122
 MinimTransformVariable.h:123
 MinimTransformVariable.h:124
 MinimTransformVariable.h:125
 MinimTransformVariable.h:126
 MinimTransformVariable.h:127
 MinimTransformVariable.h:128
 MinimTransformVariable.h:129
 MinimTransformVariable.h:130
 MinimTransformVariable.h:131
 MinimTransformVariable.h:132
 MinimTransformVariable.h:133
 MinimTransformVariable.h:134
 MinimTransformVariable.h:135
 MinimTransformVariable.h:136
 MinimTransformVariable.h:137
 MinimTransformVariable.h:138
 MinimTransformVariable.h:139
 MinimTransformVariable.h:140
 MinimTransformVariable.h:141
 MinimTransformVariable.h:142
 MinimTransformVariable.h:143
 MinimTransformVariable.h:144
 MinimTransformVariable.h:145
 MinimTransformVariable.h:146
 MinimTransformVariable.h:147
 MinimTransformVariable.h:148
 MinimTransformVariable.h:149
 MinimTransformVariable.h:150
 MinimTransformVariable.h:151
 MinimTransformVariable.h:152
 MinimTransformVariable.h:153
 MinimTransformVariable.h:154
 MinimTransformVariable.h:155
 MinimTransformVariable.h:156
 MinimTransformVariable.h:157
 MinimTransformVariable.h:158
 MinimTransformVariable.h:159