AmpTools
MinuitParameterManager.cc
Go to the documentation of this file.
1 
2 // This file is a part of MinuitInterface - a front end for the Minuit minimization
3 // package (Minuit itself was authored by Fred James, of CERN)
4 //
5 //
6 // Copyright Cornell University 1993, 1996, All Rights Reserved.
7 //
8 // This software written by Lawrence Gibbons, Cornell University.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions
12 // are met:
13 // 1. Redistributions of source code must retain the above copyright
14 // notice and author attribution, this list of conditions and the
15 // following disclaimer.
16 // 2. Redistributions in binary form must reproduce the above copyright
17 // notice and author attribution, this list of conditions and the
18 // following disclaimer in the documentation and/or other materials
19 // provided with the distribution.
20 // 3. Neither the name of the University nor the names of its contributors
21 // may be used to endorse or promote products derived from this software
22 // without specific prior written permission.
23 //
24 // Creation of derivative forms of this software for commercial
25 // utilization may be subject to restriction; written permission may be
26 // obtained from Cornell University.
27 //
28 // CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way
29 // of example, but not limitation, CORNELL MAKES NO REPRESENTATIONS OR
30 // WARRANTIES OF MERCANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
31 // THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS,
32 // COPYRIGHTS, TRADEMARKS, OR OTHER RIGHTS. Cornell University shall not be
33 // held liable for any liability with respect to any claim by the user or any
34 // other party arising from use of the program.
35 //
36 
37 #include <string>
38 #include <vector>
39 #include <sstream>
40 #include <algorithm>
41 #include <ios>
42 #include <iomanip>
43 #include <cmath>
44 
49 
50 using namespace std;
51 
52 typedef list<MinuitParameter*>::iterator ListIter;
53 typedef list<MinuitParameter*>::const_iterator ConstListIter;
55 
57  list<MinuitParameter*>(),
58  m_minimizationManager( aManager ),
59  m_fitInProgress( false )
60 {}
61 
63 {}
64 
65 void
67 {
68  for ( ParamIter parameter = begin(); parameter != end(); ++parameter )
69  {
70  int minuitId = parameter->minuitId();
71  const vector<double>& minuitValues = m_minimizationManager.minuitWorkingValues();
72 // cout << "Updating param " << parameter->name()
73 // << " with new value " << minuitValues[minuitId] << endl;
74  parameter->setValue( minuitValues[minuitId] );
75  parameter->invalidateErrors();
76  }
77 }
78 
79 void
81 {
82  if ( m_fitInProgress ||
83  m_minimizationManager.status() != MinuitMinimizationManager::kNormal)
84  {
85  return;
86  }
87 
88  URMinuit& theMinimizer = m_minimizationManager.minuitMinimizer();
89  for ( ParamIter parameter = begin(); parameter != end(); ++parameter )
90  {
91  int minuitId = parameter->minuitId();
92  double upwardsError;
93  double downwardsError;
94  double parabolicError;
95  double correlationCoefficient;
96 // cout << "querying minuit about error for param: " << parameter->name()
97 // << " MinuitId " << minuitId << endl;
98  theMinimizer.mnerrs( minuitId, upwardsError, downwardsError,
99  parabolicError, correlationCoefficient );
100  parameter->setAsymmetricErrors( std::pair<double,double>(downwardsError,
101  upwardsError) );
102  parameter->setGlobalCorrelation( correlationCoefficient );
103  parameter->validateErrors();
104  // hmm design problem? Must have validateErrors set before we can do
105  // the updateError with a notify...
106  parameter->setError( parabolicError, true );
107  }
108 }
109 
110 void
112 {
113  // we'll need the minuitMinimizer to check/modify parameter status
114  URMinuit& theMinimizer = m_minimizationManager.minuitMinimizer();
115 
116  m_numFloatingPars = 0;
117 
118  // check that minuit has each parameter's status correct
119  for ( ParamIter parameter = begin(); parameter != end(); ++parameter )
120  {
121  int minuitId = parameter->minuitId();
122 
123  // get the current values from minuit
124  string name;
125  double value;
126  double error;
127  double lowerLimit;
128  double upperLimit;
129  int minuitVariableId;
130  theMinimizer.mnpout( minuitId, name, value, error,
131  lowerLimit, upperLimit, minuitVariableId );
132 
133  // force the minuit value to the current value of the parameter
134  if ( value != parameter->value() )
135  {
136  double commandParameters[] = { static_cast<double>(minuitId), parameter->value() };
137  int status;
138  theMinimizer.mnexcm( "SET PAR", commandParameters, 2, status );
139  }
140 
141  // make sure that minuit has all of its parameters held fixed as necessary
142  // Note: a positive minuitVariableId => minuit considers the parameter floating
143  if ( ! parameter->floating() ) {
144  cout << "Need to fix parameter " << minuitId << " MinuitVariableId = "
145  << minuitVariableId << endl;
146  if ( minuitVariableId > 0 ) {
147  theMinimizer.FixParameter( minuitId );
148  }
149  }
150  else{
151 
152  // we'll need this to dimension the error matrix
153  ++m_numFloatingPars;
154  }
155 
156  // check any bounds that are set on the parameter, or unbound if necessary
157  bool updateLimits =
158  (lowerLimit != parameter->lowerBound()) ||
159  (upperLimit != parameter->upperBound());
160  if ( updateLimits )
161  {
162  int status;
163  string limCommand = "SET LIM";
164  if ( ! parameter->bounded() )
165  {
166  double commandParameter = minuitId;
167  theMinimizer.mnexcm( limCommand, &commandParameter, 1, status );
168  }
169  else
170  {
171  double commandParameters[] = {static_cast<double>(minuitId), parameter->lowerBound(),
172  parameter->upperBound()};
173  theMinimizer.mnexcm( limCommand, commandParameters, 3, status );
174  }
175  }
176 
177  } // end of loop over parameters
178 }
179 
180 bool
182 {
183 
184 
185  // the minuit user Id for this parameter
186  unsigned int newParameterMinuitId = size();
187  ++newParameterMinuitId;
188 
189  // the place to insert the parameter into the list
190  ListIter insertPosition = end();
191 
192  // check to see if the list is fully populated. If not, look for the
193  // first unused id, and the parameter before which the new parameter
194  // will be inserted
195  if ( size() && ! (back()->minuitId() == size()) )
196  {
197  newParameterMinuitId = 1;
198  insertPosition = begin();
199  for ( ParamIter iter = begin(); iter != end(); ++iter )
200  {
201  if ( newParameterMinuitId == iter->minuitId() )
202  {
203  ++newParameterMinuitId;
204  ++insertPosition;
205  }
206  }
207  }
208 
209  insert( insertPosition, newParameter );
210  newParameter->setMinuitId( newParameterMinuitId );
211 
212  // inform minuit of the parameter, with bounds as defined
213  // in MinuitParameter
214  double lowerBound = 0;
215  double upperBound = 0;
216  if( newParameter->bounded() )
217  {
218  lowerBound = newParameter->lowerBound();
219  upperBound = newParameter->upperBound();
220  }
221 
222  double initialStepSize = 0.1 * fabs(newParameter->value());
223  // Make sure the initial step size is reasonable
224  if ( initialStepSize == 0 )
225  {
226  initialStepSize = 0.1;
227  }
228  if ( ( (newParameter->value()-initialStepSize) <= lowerBound ) ||
229  ( (newParameter->value()+initialStepSize) >= upperBound ) )
230  {
231  initialStepSize *= 0.1;
232  }
233  URMinuit& theMinimizer = m_minimizationManager.minuitMinimizer();
234  int error = theMinimizer.DefineParameter( newParameter->minuitId(),
235  newParameter->name(),
236  newParameter->value(),
237  initialStepSize,
238  lowerBound,
239  upperBound );
240 
241  return error == 0;
242 }
243 
244 vector< vector< double > >
246 
247  // allocate space for a square matrix of doubles with
248  // dimension equal to the number of parameters
249  double* emat = (double*)malloc( m_numFloatingPars * m_numFloatingPars *
250  sizeof( double ) );
251 
252  m_minimizationManager.minuitMinimizer().mnemat( emat, m_numFloatingPars );
253 
254  vector< vector< double > > errorMatrix;
255 
256  for( unsigned int i = 0; i < m_numFloatingPars; ++i ){
257 
258  errorMatrix.push_back( vector< double >( 0 ) );
259  for( unsigned int j = 0; j < m_numFloatingPars; ++j ){
260 
261  errorMatrix[i].push_back( emat[i+j*m_numFloatingPars] );
262  }
263  }
264 
265  free( emat );
266 
267  return errorMatrix;
268 }
269 
270 vector< vector< double > >
272 
273 
274  vector< vector< double > > covMatrix = covarianceMatrix();
275  vector< vector< double > > corrMatrix = covMatrix;
276 
277  for( unsigned int i = 0; i < corrMatrix.size(); ++i ){
278  for( unsigned int j = 0; j < corrMatrix[i].size(); ++j ){
279 
280  corrMatrix[i][j] /= sqrt( covMatrix[i][i] * covMatrix[j][j] );
281  }
282  }
283 
284  return corrMatrix;
285 }
286 
287 void
289  remove( aParameter );
290  cout << " Warning: UpRootMinuit class does not yet support parameter removal!" << endl;
291 }
292 
293 std::ostream&
294 MinuitParameterManager::dump( std::ostream& aStream ) const
295 {
296 
297  unsigned int maxLength = 0;
298  for ( ConstListIter itParam = begin(); itParam != end(); ++itParam )
299  {
300  maxLength = (maxLength < (*itParam)->name().size()) ?
301  (*itParam)->name().size() : maxLength;
302  }
303  aStream << "\n\n" << setw(maxLength) << "name" << setw(9)
304  << "value" << setw(9) << "error"
305  << setw(9) << "-error" << setw(9) << "+error" << '\n';
306  for ( ConstListIter itParam = begin(); itParam != end(); ++itParam )
307  {
308  aStream << **itParam << '\n';
309  }
310 
311  return aStream;
312 }
double lowerBound() const
const std::vector< double > & minuitWorkingValues() const
virtual Int_urt FixParameter(Int_urt parNo)
Definition: URMinuit.cc:433
void removeParameter(MinuitParameter *aParameter)
virtual void mnemat(Double_urt *emat, Int_urt ndim)
Definition: URMinuit.cc:2232
virtual void mnpout(Int_urt iuext, std::string &chnam, Double_urt &val, Double_urt &err, Double_urt &xlolim, Double_urt &xuplim, Int_urt &iuint) const
Definition: URMinuit.cc:6151
MinuitParameterManager(MinuitMinimizationManager &aManager)
double value() const
Definition: Parameter.h:54
virtual void mnexcm(const std::string &command, Double_urt *plist, Int_urt llist, Int_urt &ierflg)
Definition: URMinuit.cc:2393
virtual Int_urt DefineParameter(Int_urt parNo, const std::string &name, Double_urt initVal, Double_urt initErr, Double_urt lowerLimit, Double_urt upperLimit)
Definition: URMinuit.cc:288
std::ostream & dump(std::ostream &s) const
MIPointerListIterator< ListIter, MinuitParameter, MinuitParameter > ParamIter
bool bounded() const
vector< vector< double > > correlationMatrix()
void setMinuitId(unsigned int minuitId)
double sqrt(double)
double upperBound() const
list< MinuitParameter * >::iterator ListIter
virtual void mnerrs(Int_urt number, Double_urt &eplus, Double_urt &eminus, Double_urt &eparab, Double_urt &gcc)
Definition: URMinuit.cc:2309
list< MinuitParameter * >::const_iterator ConstListIter
const std::string & name() const
Definition: Parameter.cc:80
vector< vector< double > > covarianceMatrix()
unsigned int minuitId() const
bool registerParameter(MinuitParameter *newParameter)