39 #include "Minuit2/FunctionMinimum.h"
40 #include "Minuit2/MnMigrad.h"
41 #include "Minuit2/MnMinos.h"
42 #include "Minuit2/MnPrint.h"
47 namespace afwMath = lsst::afw::math;
53 template<
typename ReturnT>
56 explicit MinimizerFunctionBase1(
58 std::vector<double>
const &measurementList,
59 std::vector<double>
const &varianceList,
60 std::vector<double>
const &xPositionList,
63 virtual ~MinimizerFunctionBase1() {};
65 virtual double Up()
const {
return _errorDef; }
66 virtual double operator() (
const std::vector<double>&)
const;
69 inline std::vector<double> getMeasurements()
const {
return _measurementList;}
70 inline std::vector<double> getVariances()
const {
return _varianceList;}
71 inline std::vector<double> getPositions()
const {
return _xPositionList;}
72 inline void setErrorDef(
double def) {_errorDef=def;}
75 boost::shared_ptr<afwMath::Function1<ReturnT> > _functionPtr;
76 std::vector<double> _measurementList;
77 std::vector<double> _varianceList;
78 std::vector<double> _xPositionList;
85 template<
typename ReturnT>
88 explicit MinimizerFunctionBase2(
90 std::vector<double>
const &measurementList,
91 std::vector<double>
const &varianceList,
92 std::vector<double>
const &xPositionList,
93 std::vector<double>
const &yPositionList,
96 virtual ~MinimizerFunctionBase2() {};
98 virtual double Up()
const {
return _errorDef; }
99 virtual double operator() (
const std::vector<double>& par)
const;
102 inline std::vector<double> getMeasurements()
const {
return _measurementList;}
103 inline std::vector<double> getVariances()
const {
return _varianceList;}
104 inline std::vector<double> getPosition1()
const {
return _xPositionList;}
105 inline std::vector<double> getPosition2()
const {
return _yPositionList;}
106 inline void setErrorDef(
double def) {_errorDef=def;}
109 boost::shared_ptr<afwMath::Function2<ReturnT> > _functionPtr;
110 std::vector<double> _measurementList;
111 std::vector<double> _varianceList;
112 std::vector<double> _xPositionList;
113 std::vector<double> _yPositionList;
118 template<
typename ReturnT>
119 MinimizerFunctionBase1<ReturnT>::MinimizerFunctionBase1(
121 std::vector<double>
const &measurementList,
122 std::vector<double>
const &varianceList,
123 std::vector<double>
const &xPositionList,
126 lsst::daf::base::Citizen(typeid(this)),
127 _functionPtr(function.clone()),
128 _measurementList(measurementList),
129 _varianceList(varianceList),
130 _xPositionList(xPositionList),
134 template<
typename ReturnT>
135 MinimizerFunctionBase2<ReturnT>::MinimizerFunctionBase2(
137 std::vector<double>
const &measurementList,
138 std::vector<double>
const &varianceList,
139 std::vector<double>
const &xPositionList,
140 std::vector<double>
const &yPositionList,
143 lsst::daf::base::Citizen(typeid(this)),
144 _functionPtr(function.clone()),
145 _measurementList(measurementList),
146 _varianceList(varianceList),
147 _xPositionList(xPositionList),
148 _yPositionList(yPositionList),
155 template<
typename ReturnT>
156 double MinimizerFunctionBase1<ReturnT>::operator() (
const std::vector<double>& par)
const {
158 this->_functionPtr->setParameters(par);
161 for (
unsigned int i = 0; i < this->_measurementList.size(); i++) {
162 double resid = (*(this->_functionPtr))(this->_xPositionList[i]) - this->_measurementList[i];
163 chi2 += resid * resid / this->_varianceList[i];
170 template<
typename ReturnT>
171 double MinimizerFunctionBase2<ReturnT>::operator() (
const std::vector<double>& par)
const {
173 this->_functionPtr->setParameters(par);
176 for (
unsigned int i = 0; i < this->_measurementList.size(); i++) {
177 double resid = (*(this->_functionPtr))(this->_xPositionList[i],
178 this->_yPositionList[i]) - this->_measurementList[i];
179 chi2 += resid * resid / this->_varianceList[i];
201 template<
typename ReturnT>
204 std::vector<double>
const &initialParameterList,
205 std::vector<double>
const &stepSizeList,
206 std::vector<double>
const &measurementList,
207 std::vector<double>
const &varianceList,
208 std::vector<double>
const &xPositionList,
211 unsigned int const nParameters =
function.getNParameters();
212 if (initialParameterList.size() != nParameters) {
213 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
214 "initialParameterList is the wrong length");
216 if (stepSizeList.size() != nParameters) {
217 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
218 "stepSizeList is the wrong length");
220 unsigned int const nMeasurements = measurementList.size();
221 if (varianceList.size() != nMeasurements) {
222 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
223 "varianceList is the wrong length");
225 if (xPositionList.size() != nMeasurements) {
226 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
227 "xPositionList is the wrong length");
230 MinimizerFunctionBase1<ReturnT> minimizerFunc(
238 ROOT::Minuit2::MnUserParameters fitPar;
239 std::vector<std::string> paramNames;
240 for (
unsigned int i = 0; i < nParameters; ++i) {
242 fitPar.Add(paramNames[i].c_str(), initialParameterList[i], stepSizeList[i]);
245 ROOT::Minuit2::MnMigrad migrad(minimizerFunc, fitPar);
246 ROOT::Minuit2::FunctionMinimum min = migrad();
247 ROOT::Minuit2::MnMinos minos(minimizerFunc, min);
249 FitResults fitResults;
250 fitResults.chiSq = min.Fval();
251 fitResults.isValid = min.IsValid() &&
std::isfinite(fitResults.chiSq);
252 if (!fitResults.isValid) {
256 for (
unsigned int i = 0; i < nParameters; ++i) {
257 fitResults.parameterList.push_back(min.UserState().Value(paramNames[i].c_str()));
258 if (fitResults.isValid) {
259 fitResults.parameterErrorList.push_back(minos(i));
261 double e = min.UserState().Error(paramNames[i].c_str());
262 std::pair<double,double> ep(-1 * e, e);
263 fitResults.parameterErrorList.push_back(ep);
285 template<
typename ReturnT>
288 std::vector<double>
const &initialParameterList,
289 std::vector<double>
const &stepSizeList,
290 std::vector<double>
const &measurementList,
291 std::vector<double>
const &varianceList,
292 std::vector<double>
const &xPositionList,
293 std::vector<double>
const &yPositionList,
296 unsigned int const nParameters =
function.getNParameters();
297 if (initialParameterList.size() != nParameters) {
298 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
299 "initialParameterList is the wrong length");
301 if (stepSizeList.size() != nParameters) {
302 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
303 "stepSizeList is the wrong length");
305 unsigned int const nMeasurements = measurementList.size();
306 if (varianceList.size() != nMeasurements) {
307 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
308 "varianceList is the wrong length");
310 if (xPositionList.size() != nMeasurements) {
311 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
312 "xPositionList is the wrong length");
314 if (yPositionList.size() != nMeasurements) {
315 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
316 "yPositionList is the wrong length");
319 MinimizerFunctionBase2<ReturnT> minimizerFunc(
328 ROOT::Minuit2::MnUserParameters fitPar;
329 std::vector<std::string> paramNames;
330 for (
unsigned int i = 0; i < nParameters; ++i) {
332 fitPar.Add(paramNames[i].c_str(), initialParameterList[i], stepSizeList[i]);
335 ROOT::Minuit2::MnMigrad migrad(minimizerFunc, fitPar);
336 ROOT::Minuit2::FunctionMinimum min = migrad();
337 ROOT::Minuit2::MnMinos minos(minimizerFunc, min);
339 FitResults fitResults;
340 fitResults.chiSq = min.Fval();
341 fitResults.isValid = min.IsValid() &&
std::isfinite(fitResults.chiSq);
342 if (!fitResults.isValid) {
346 for (
unsigned int i = 0; i < nParameters; ++i) {
347 fitResults.parameterList.push_back(min.UserState().Value(paramNames[i].c_str()));
348 if (fitResults.isValid) {
349 fitResults.parameterErrorList.push_back(minos(i));
351 double e = min.UserState().Error(paramNames[i].c_str());
352 std::pair<double,double> ep(-1 * e, e);
353 fitResults.parameterErrorList.push_back(ep);
362 #define minimizeFuncs(ReturnT) \
363 template afwMath::FitResults afwMath::minimize( \
364 afwMath::Function1<ReturnT> const &, \
365 std::vector<double> const &, \
366 std::vector<double> const &, \
367 std::vector<double> const &, \
368 std::vector<double> const &, \
369 std::vector<double> const &, \
372 template afwMath::FitResults afwMath::minimize( \
373 afwMath::Function2<ReturnT> const &, \
374 std::vector<double> const &, \
375 std::vector<double> const &, \
376 std::vector<double> const &, \
377 std::vector<double> const &, \
378 std::vector<double> const &, \
379 std::vector<double> const &, \
384 minimizeFuncs(
double)
definition of the Trace messaging facilities
FitResults minimize(lsst::afw::math::Function1< ReturnT > const &function, std::vector< double > const &initialParameterList, std::vector< double > const &stepSizeList, std::vector< double > const &measurementList, std::vector< double > const &varianceList, std::vector< double > const &xPositionList, double errorDef)
limited backward compatibility to the DC2 run-time trace facilities
A Function taking two arguments.
Results from minimizing a function.
A Function taking one argument.
#define LSST_EXCEPT(type,...)
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...