28    MnParStr(
const std::string & name) : fName(name) {}
 
   32    bool operator()(
const MinuitParameter& par)
 const {
 
   34       return par.GetName() == fName;
 
   38    const std::string & fName;
 
   42 MnUserTransformation::MnUserTransformation(
const std::vector<double>& par, 
const std::vector<double>& err) : fPrecision(MnMachinePrecision()), fParameters(std::vector<MinuitParameter>()), fExtOfInt(std::vector<unsigned int>()), fDoubleLimTrafo(SinParameterTransformation()),fUpperLimTrafo(SqrtUpParameterTransformation()), fLowerLimTrafo(SqrtLowParameterTransformation()), fCache(std::vector<double>()) {
 
   48    fParameters.reserve(par.size());
 
   49    fExtOfInt.reserve(par.size());
 
   50    fCache.reserve(par.size());
 
   53    for(
unsigned int i = 0; i < par.size(); i++) {
 
   54       std::ostringstream buf;
 
   57       Add(parName, par[i], err[i]);
 
   63 std::vector<double> MnUserTransformation::operator()(
const MnAlgebraicVector& pstates )
 const {
 
   66    unsigned int n = pstates.size();
 
   68    std::vector<double> pcache( fCache );
 
   69    for(
unsigned int i = 0; i < n; i++) {
 
   70       if(fParameters[fExtOfInt[i]].HasLimits()) {
 
   71          pcache[fExtOfInt[i]] = Int2ext(i, pstates(i));
 
   73          pcache[fExtOfInt[i]] = pstates(i);
 
   95 double MnUserTransformation::Int2ext(
unsigned int i, 
double val)
 const {
 
   97    if(fParameters[fExtOfInt[i]].HasLimits()) {
 
   98       if(fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit())
 
   99          return fDoubleLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].UpperLimit(), fParameters[fExtOfInt[i]].LowerLimit());
 
  100       else if(fParameters[fExtOfInt[i]].HasUpperLimit() && !fParameters[fExtOfInt[i]].HasLowerLimit())
 
  101          return fUpperLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].UpperLimit());
 
  103          return fLowerLimTrafo.Int2ext(val, fParameters[fExtOfInt[i]].LowerLimit());
 
  109 double MnUserTransformation::Int2extError(
unsigned int i, 
double val, 
double err)
 const {
 
  115    if(fParameters[fExtOfInt[i]].HasLimits()) {
 
  116       double ui = Int2ext(i, val);
 
  117       double du1 = Int2ext(i, val+dx) - ui;
 
  118       double du2 = Int2ext(i, val-dx) - ui;
 
  119       if(fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit()) {
 
  125          if(dx > 1.) du1 = fParameters[fExtOfInt[i]].UpperLimit() - fParameters[fExtOfInt[i]].LowerLimit();
 
  126          dx = 0.5*(fabs(du1) + fabs(du2));
 
  128          dx = 0.5*(fabs(du1) + fabs(du2));
 
  135 MnUserCovariance MnUserTransformation::Int2extCovariance(
const MnAlgebraicVector& vec, 
const MnAlgebraicSymMatrix& cov)
 const {
 
  140    MnUserCovariance result(cov.Nrow());
 
  141    for(
unsigned int i = 0; i < vec.size(); i++) {
 
  143       if(fParameters[fExtOfInt[i]].HasLimits()) {
 
  145          dxdi = DInt2Ext(i, vec(i));
 
  147       for(
unsigned int j = i; j < vec.size(); j++) {
 
  149          if(fParameters[fExtOfInt[j]].HasLimits()) {
 
  151             dxdj = DInt2Ext(j, vec(j));
 
  153          result(i,j) = dxdi*cov(i,j)*dxdj;
 
  162 double MnUserTransformation::Ext2int(
unsigned int i, 
double val)
 const {
 
  165    if(fParameters[i].HasLimits()) {
 
  166       if(fParameters[i].HasUpperLimit() && fParameters[i].HasLowerLimit())
 
  167          return fDoubleLimTrafo.Ext2int(val, fParameters[i].UpperLimit(), fParameters[i].LowerLimit(), Precision());
 
  168       else if(fParameters[i].HasUpperLimit() && !fParameters[i].HasLowerLimit())
 
  169          return fUpperLimTrafo.Ext2int(val, fParameters[i].UpperLimit(), Precision());
 
  171          return fLowerLimTrafo.Ext2int(val, fParameters[i].LowerLimit(), Precision());
 
  177 double MnUserTransformation::DInt2Ext(
unsigned int i, 
double val)
 const {
 
  182    if(fParameters[fExtOfInt[i]].HasLimits()) {
 
  183       if(fParameters[fExtOfInt[i]].HasUpperLimit() && fParameters[fExtOfInt[i]].HasLowerLimit())
 
  185          dd = fDoubleLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].UpperLimit(), fParameters[fExtOfInt[i]].LowerLimit());
 
  186       else if(fParameters[fExtOfInt[i]].HasUpperLimit() && !fParameters[fExtOfInt[i]].HasLowerLimit())
 
  187          dd = fUpperLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].UpperLimit());
 
  189          dd = fLowerLimTrafo.DInt2Ext(val, fParameters[fExtOfInt[i]].LowerLimit());
 
  213 unsigned int MnUserTransformation::IntOfExt(
unsigned int ext)
 const {
 
  215    assert(ext < fParameters.size());
 
  216    assert(!fParameters[ext].IsFixed());
 
  217    assert(!fParameters[ext].IsConst());
 
  218    std::vector<unsigned int>::const_iterator iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), ext);
 
  219    assert(iind != fExtOfInt.end());
 
  221    return (iind - fExtOfInt.begin());
 
  224 std::vector<double> MnUserTransformation::Params()
 const {
 
  226    unsigned int n = fParameters.size();
 
  227    std::vector<double> result(n);
 
  228    for(
unsigned int i = 0; i < n; ++i)
 
  229       result[i] = fParameters[i].Value();
 
  234 std::vector<double> MnUserTransformation::Errors()
 const {
 
  236    std::vector<double> result; result.reserve(fParameters.size());
 
  237    for(std::vector<MinuitParameter>::const_iterator ipar = Parameters().begin();
 
  238        ipar != Parameters().end(); ++ipar)
 
  239       result.push_back((*ipar).Error());
 
  244 const MinuitParameter& MnUserTransformation::Parameter(
unsigned int n)
 const {
 
  246    assert(n < fParameters.size());
 
  247    return fParameters[n];
 
  264 bool MnUserTransformation::Add(
const std::string & name, 
double val, 
double err) {
 
  267    if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end() )
 
  269    fExtOfInt.push_back(fParameters.size());
 
  270    fCache.push_back(val);
 
  271    fParameters.push_back(MinuitParameter(fParameters.size(), name, val, err));
 
  275 bool MnUserTransformation::Add(
const std::string & name, 
double val, 
double err, 
double low, 
double up) {
 
  278    if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end() )
 
  280    fExtOfInt.push_back(fParameters.size());
 
  281    fCache.push_back(val);
 
  282    fParameters.push_back(MinuitParameter(fParameters.size(), name, val, err, low, up));
 
  286 bool MnUserTransformation::Add(
const std::string & name, 
double val) {
 
  289    if (std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name)) != fParameters.end() )
 
  291    fCache.push_back(val);
 
  293    fParameters.push_back(MinuitParameter(fParameters.size(), name, val));
 
  297 void MnUserTransformation::Fix(
unsigned int n) {
 
  299    assert(n < fParameters.size());
 
  300    std::vector<unsigned int>::iterator iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), n);
 
  301    if (iind != fExtOfInt.end())
 
  302       fExtOfInt.erase(iind, iind+1);
 
  303    fParameters[n].Fix();
 
  306 void MnUserTransformation::Release(
unsigned int n) {
 
  308    assert(n < fParameters.size());
 
  309    std::vector<unsigned int>::const_iterator iind = std::find(fExtOfInt.begin(), fExtOfInt.end(), n);
 
  310    if (iind == fExtOfInt.end() ) {
 
  311       fExtOfInt.push_back(n);
 
  312       std::sort(fExtOfInt.begin(), fExtOfInt.end());
 
  314    fParameters[n].Release();
 
  317 void MnUserTransformation::SetValue(
unsigned int n, 
double val) {
 
  319    assert(n < fParameters.size());
 
  320    fParameters[n].SetValue(val);
 
  324 void MnUserTransformation::SetError(
unsigned int n, 
double err) {
 
  326    assert(n < fParameters.size());
 
  327    fParameters[n].SetError(err);
 
  330 void MnUserTransformation::SetLimits(
unsigned int n, 
double low, 
double up) {
 
  332    assert(n < fParameters.size());
 
  334    fParameters[n].SetLimits(low, up);
 
  337 void MnUserTransformation::SetUpperLimit(
unsigned int n, 
double up) {
 
  339    assert(n < fParameters.size());
 
  340    fParameters[n].SetUpperLimit(up);
 
  343 void MnUserTransformation::SetLowerLimit(
unsigned int n, 
double lo) {
 
  345    assert(n < fParameters.size());
 
  346    fParameters[n].SetLowerLimit(lo);
 
  349 void MnUserTransformation::RemoveLimits(
unsigned int n) {
 
  351    assert(n < fParameters.size());
 
  352    fParameters[n].RemoveLimits();
 
  355 void MnUserTransformation::SetName(
unsigned int n, 
const std::string & name) {
 
  357    assert(n < fParameters.size());
 
  358    fParameters[n].SetName(name);
 
  362 double MnUserTransformation::Value(
unsigned int n)
 const {
 
  364    assert(n < fParameters.size());
 
  365    return fParameters[n].Value();
 
  368 double MnUserTransformation::Error(
unsigned int n)
 const {
 
  370    assert(n < fParameters.size());
 
  371    return fParameters[n].Error();
 
  376 void MnUserTransformation::Fix(
const std::string & name) {
 
  381 void MnUserTransformation::Release(
const std::string & name) {
 
  383    Release(Index(name));
 
  386 void MnUserTransformation::SetValue(
const std::string & name, 
double val) {
 
  388    SetValue(Index(name), val);
 
  391 void MnUserTransformation::SetError(
const std::string & name, 
double err) {
 
  393    SetError(Index(name), err);
 
  396 void MnUserTransformation::SetLimits(
const std::string & name, 
double low, 
double up) {
 
  398    SetLimits(Index(name), low, up);
 
  401 void MnUserTransformation::SetUpperLimit(
const std::string & name, 
double up) {
 
  403    SetUpperLimit(Index(name), up);
 
  406 void MnUserTransformation::SetLowerLimit(
const std::string & name, 
double lo) {
 
  408    SetLowerLimit(Index(name), lo);
 
  411 void MnUserTransformation::RemoveLimits(
const std::string & name) {
 
  413    RemoveLimits(Index(name));
 
  416 double MnUserTransformation::Value(
const std::string & name)
 const {
 
  418    return Value(Index(name));
 
  421 double MnUserTransformation::Error(
const std::string & name)
 const {
 
  423    return Error(Index(name));
 
  426 unsigned int MnUserTransformation::Index(
const std::string & name)
 const {
 
  428    std::vector<MinuitParameter>::const_iterator ipar =
 
  429    std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name));
 
  430    assert(ipar != fParameters.end());
 
  432    return (*ipar).Number();
 
  435 int MnUserTransformation::FindIndex(
const std::string & name)
 const {
 
  437    std::vector<MinuitParameter>::const_iterator ipar =
 
  438    std::find_if(fParameters.begin(), fParameters.end(), MnParStr(name));
 
  439    if (ipar == fParameters.end() ) 
return -1;
 
  440    return (*ipar).Number();
 
  444 const std::string & MnUserTransformation::GetName(
unsigned int n)
 const {
 
  446    assert(n < fParameters.size());
 
  447    return fParameters[n].GetName();
 
  450 const char* MnUserTransformation::Name(
unsigned int n)
 const {
 
  452    return GetName(n).c_str();