00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Math/MinimTransformFunction.h"
00014
00015
00016 #include <cmath>
00017 #include <cassert>
00018
00019 namespace ROOT {
00020
00021 namespace Math {
00022
00023 MinimTransformFunction::MinimTransformFunction ( const IMultiGradFunction * f, const std::vector<EMinimVariableType> & types,
00024 const std::vector<double> & values,
00025 const std::map<unsigned int, std::pair<double, double> > & bounds) :
00026 fX( values ),
00027 fFunc(f)
00028 {
00029
00030
00031
00032
00033 unsigned int ntot = NTot();
00034 assert ( types.size() == ntot );
00035 fVariables.reserve(ntot);
00036 fIndex.reserve(ntot);
00037 for (unsigned int i = 0; i < ntot; ++i ) {
00038 if (types[i] == kFix )
00039 fVariables.push_back( MinimizerVariable( values[i]) );
00040 else {
00041 fIndex.push_back(i);
00042
00043 if ( types[i] == kDefault)
00044 fVariables.push_back( MinimizerVariable() );
00045 else {
00046 std::map<unsigned int, std::pair<double,double> >::const_iterator itr = bounds.find(i);
00047 assert ( itr != bounds.end() );
00048 double low = itr->second.first;
00049 double up = itr->second.second;
00050 if (types[i] == kBounds )
00051 fVariables.push_back( MinimizerVariable( low, up, new SinVariableTransformation()));
00052 else if (types[i] == kLowBound)
00053 fVariables.push_back( MinimizerVariable( low, new SqrtLowVariableTransformation()));
00054 else if (types[i] == kUpBound)
00055 fVariables.push_back( MinimizerVariable( up, new SqrtUpVariableTransformation()));
00056 }
00057 }
00058 }
00059 }
00060
00061 const double * MinimTransformFunction::Transformation( const double * x) const {
00062
00063
00064 unsigned int nfree = fIndex.size();
00065
00066
00067
00068
00069
00070 for (unsigned int i = 0; i < nfree; ++i ) {
00071 unsigned int extIndex = fIndex[i];
00072 const MinimizerVariable & var = fVariables[ extIndex ];
00073 if (var.IsLimited() )
00074 fX[ extIndex ] = var.InternalToExternal( x[i] );
00075 else
00076 fX[ extIndex ] = x[i];
00077 }
00078
00079
00080
00081
00082
00083 return &fX.front();
00084 }
00085
00086 void MinimTransformFunction::InvTransformation(const double * xExt, double * xInt) const {
00087
00088 for (unsigned int i = 0; i < NDim(); ++i ) {
00089 unsigned int extIndex = fIndex[i];
00090 const MinimizerVariable & var = fVariables[ extIndex ];
00091 assert ( !var.IsFixed() );
00092 if (var.IsLimited() )
00093 xInt[ i ] = var.ExternalToInternal( xExt[extIndex] );
00094 else
00095 xInt[ i ] = xExt[extIndex];
00096 }
00097 }
00098
00099 void MinimTransformFunction::InvStepTransformation(const double * x, const double * sExt, double * sInt) const {
00100
00101 for (unsigned int i = 0; i < NDim(); ++i ) {
00102 unsigned int extIndex = fIndex[i];
00103 const MinimizerVariable & var = fVariables[ extIndex ];
00104 assert ( !var.IsFixed() );
00105 if (var.IsLimited() ) {
00106
00107 double x2 = x[extIndex] + sExt[extIndex];
00108 if (var.HasUpperBound() && x2 >= var.UpperBound() )
00109 x2 = x[extIndex] - sExt[extIndex];
00110
00111 double xint = var.ExternalToInternal ( x[extIndex] );
00112 double x2int = var.ExternalToInternal( x2 );
00113 sInt[i] = std::abs( x2int - xint);
00114 }
00115 else
00116 sInt[ i ] = sExt[extIndex];
00117 }
00118 }
00119
00120 void MinimTransformFunction::GradientTransformation(const double * x, const double *gExt, double * gInt) const {
00121
00122 unsigned int nfree = fIndex.size();
00123 for (unsigned int i = 0; i < nfree; ++i ) {
00124 unsigned int extIndex = fIndex[i];
00125 const MinimizerVariable & var = fVariables[ extIndex ];
00126 assert (!var.IsFixed() );
00127 if (var.IsLimited() )
00128 gInt[i] = gExt[ extIndex ] * var.DerivativeIntToExt( x[i] );
00129 else
00130 gInt[i] = gExt[ extIndex ];
00131 }
00132 }
00133
00134
00135 void MinimTransformFunction::MatrixTransformation(const double * x, const double *covInt, double * covExt) const {
00136
00137
00138
00139 unsigned int nfree = fIndex.size();
00140 unsigned int ntot = NTot();
00141 for (unsigned int i = 0; i < nfree; ++i ) {
00142 unsigned int iext = fIndex[i];
00143 const MinimizerVariable & ivar = fVariables[ iext ];
00144 assert (!ivar.IsFixed());
00145 double ddi = ( ivar.IsLimited() ) ? ivar.DerivativeIntToExt( x[i] ) : 1.0;
00146
00147 for (unsigned int j = 0; j < nfree; ++j ) {
00148 unsigned int jext = fIndex[j];
00149 const MinimizerVariable & jvar = fVariables[ jext ];
00150 double ddj = ( jvar.IsLimited() ) ? jvar.DerivativeIntToExt( x[j] ) : 1.0;
00151 assert (!jvar.IsFixed() );
00152 covExt[ iext * ntot + jext] = ddi * ddj * covInt[ i * nfree + j];
00153 }
00154 }
00155 }
00156
00157
00158 }
00159
00160 }
00161