1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-11-10 00:45:36 +00:00

XYStatData: various fixes and improvement, fit is now working

This commit is contained in:
Antonin Portelli 2016-03-16 13:05:56 +00:00
parent 9f67ead605
commit 9bc9288dfb
5 changed files with 87 additions and 51 deletions

View File

@ -1,46 +1,51 @@
#include <iostream> #include <iostream>
#include <cmath>
#include <LatAnalyze/CompiledModel.hpp>
#include <LatAnalyze/MinuitMinimizer.hpp>
#include <LatAnalyze/RandGen.hpp>
#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
using namespace std; using namespace std;
using namespace Latan; using namespace Latan;
const Index nPoint = 30;
const double xErr = .01, yErr = .1;
const double exactPar[2] = {0.5,5.0}, dx = 10.0/static_cast<double>(nPoint);
int main(void) int main(void)
{ {
XYStatData f; // generate fake data
XYStatData data;
RandGen rg;
double x_k, y_k;
DoubleModel f([](const double *x, const double *p)
{return p[1]*exp(-x[0]*p[0]);}, 1, 2);
f.addYDim("q1"); data.addXDim("x", nPoint);
f.addYDim("q2"); data.addYDim("y");
f.addXDim("x1", 6); for (Index k = 0; k < nPoint; ++k)
f.addXDim("x2", 5); {
f.addXDim("x3", 5); x_k = k*dx + rg.gaussian(0.0, xErr);
f.y(f.dataIndex(0,0,0), 0) = 2; y_k = f(&x_k, exactPar) + rg.gaussian(0.0, yErr);
f.y(f.dataIndex(1,1,1), 0) = 4; printf("% 8e % 8e % 8e % 8e\n", x_k, xErr, y_k, yErr);
f.y(f.dataIndex(2,2,2), 0) = 5; data.x(k) = x_k;
f.y(f.dataIndex(2,3,3), 0) = 10; data.y(k) = y_k;
f.y(f.dataIndex(0,0,0), 1) = 1; }
f.y(f.dataIndex(1,1,1), 1) = 2; cout << endl;
f.y(f.dataIndex(2,2,3), 1) = 4; data.setXError(0, DVec::Constant(nPoint, xErr));
f.fitPoint(false, f.dataIndex(2,2,2), 0); data.setYError(0, DVec::Constant(nPoint, yErr));
f.fitPoint(false, f.dataIndex(1,1,1), 1); cout << data << endl;
f.assumeXXCorrelated(true, 0, 0, 1, 0);
f.assumeXXCorrelated(true, 0, 1, 1, 1); // fit
f.assumeXXCorrelated(true, 0, 2, 1, 2); DVec init = DVec::Constant(2, 0.5);
f.assumeXXCorrelated(true, 0, 0, 1, 2); FitResult p;
f.assumeXXCorrelated(true, 3, 2, 4, 2); MinuitMinimizer minimizer;
f.assumeYYCorrelated(true, f.dataIndex(0,0,0), 0, f.dataIndex(2,3,3), 0);
f.assumeYYCorrelated(true, f.dataIndex(0,0,0), 1, f.dataIndex(2,2,3), 1); minimizer.setVerbosity(MinuitMinimizer::Verbosity::Debug);
f.assumeXYCorrelated(true, 0, 0, f.dataIndex(1,1,1), 0); p = data.fit(minimizer, init, f);
f.assumeXExact(true, 0); cout << "a= " << p(0) << " b= " << p(1);
f.assumeXExact(true, 1); cout << " chi^2/ndof= " << p.getChi2PerDof();
f.assumeXExact(true, 2); cout << " p-value= " << p.getPValue() <<endl;
cout << f << endl;
f.setXXVar(0, 0, DMat::Identity(6, 6));
f.setXXVar(0, 2, DMat::Identity(6, 5));
f.setXXVar(1, 1, DMat::Identity(5, 5));
f.setXXVar(2, 2, DMat::Identity(5, 5));
DEBUG_MAT(f.makeCorrFilter());
DEBUG_MAT(f.getFitVar());
DEBUG_MAT(f.getFitVar().cwiseProduct(f.makeCorrFilter()));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -253,7 +253,7 @@ void FitInterface::assumeXXCorrelated(const bool isCorr, const Index r1,
{ {
addCorr(xxCorr_, isCorr, c); addCorr(xxCorr_, isCorr, c);
} }
scheduleLayoutInit(); scheduleFitVarMatInit();
} }
void FitInterface::assumeYYCorrelated(const bool isCorr, const Index k1, void FitInterface::assumeYYCorrelated(const bool isCorr, const Index k1,
@ -268,7 +268,7 @@ void FitInterface::assumeYYCorrelated(const bool isCorr, const Index k1,
{ {
addCorr(yyCorr_, isCorr, c); addCorr(yyCorr_, isCorr, c);
} }
scheduleLayoutInit(); scheduleFitVarMatInit();
} }
void FitInterface::assumeXYCorrelated(const bool isCorr, const Index r, void FitInterface::assumeXYCorrelated(const bool isCorr, const Index r,
@ -280,7 +280,7 @@ void FitInterface::assumeXYCorrelated(const bool isCorr, const Index r,
checkXIndex(r, i); checkXIndex(r, i);
checkPoint(k, j); checkPoint(k, j);
addCorr(xyCorr_, isCorr, c); addCorr(xyCorr_, isCorr, c);
scheduleLayoutInit(); scheduleFitVarMatInit();
} }
// tests /////////////////////////////////////////////////////////////////////// // tests ///////////////////////////////////////////////////////////////////////
@ -387,6 +387,17 @@ void FitInterface::registerDataPoint(const Index k, const Index j)
void FitInterface::scheduleLayoutInit(void) void FitInterface::scheduleLayoutInit(void)
{ {
initLayout_ = true; initLayout_ = true;
scheduleFitVarMatInit();
}
void FitInterface::scheduleFitVarMatInit(const bool init)
{
initVarMat_ = init;
}
bool FitInterface::initVarMat(void)
{
return initVarMat_;
} }
void FitInterface::updateLayout(void) void FitInterface::updateLayout(void)

View File

@ -105,6 +105,8 @@ protected:
virtual void createYData(void) = 0; virtual void createYData(void) = 0;
// global layout management // global layout management
void scheduleLayoutInit(void); void scheduleLayoutInit(void);
void scheduleFitVarMatInit(const bool init = true);
bool initVarMat(void);
void updateLayout(void); void updateLayout(void);
Index indX(const Index r, const Index i) const; Index indX(const Index r, const Index i) const;
Index indY(const Index k, const Index j) const; Index indY(const Index k, const Index j) const;
@ -118,7 +120,7 @@ private:
std::vector<std::map<Index, bool>> yDataIndex_; std::vector<std::map<Index, bool>> yDataIndex_;
std::set<std::array<Index, 4>> xxCorr_, yyCorr_, xyCorr_; std::set<std::array<Index, 4>> xxCorr_, yyCorr_, xyCorr_;
Index maxDataIndex_{1}; Index maxDataIndex_{1};
bool initLayout_{true}; bool initLayout_{true}, initVarMat_{true};
}; };
std::ostream & operator<<(std::ostream &out, FitInterface &f); std::ostream & operator<<(std::ostream &out, FitInterface &f);

View File

@ -205,6 +205,11 @@ FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
// check model consistency // check model consistency
checkModelVec(v); checkModelVec(v);
// buffering
updateLayout();
updateFitVarMat();
updateChi2DataVec();
// get number of parameters // get number of parameters
Index nPar = v[0]->getNPar(); Index nPar = v[0]->getNPar();
Index totalNPar = nPar + layout.totalXSize; Index totalNPar = nPar + layout.totalXSize;
@ -225,8 +230,6 @@ FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
FitResult result; FitResult result;
DVec totalInit(totalNPar); DVec totalInit(totalNPar);
updateFitVarMat();
updateChi2DataVec();
totalInit.segment(0, nPar) = init; totalInit.segment(0, nPar) = init;
totalInit.segment(nPar, layout.totalXSize) = totalInit.segment(nPar, layout.totalXSize) =
chi2DataVec_.segment(layout.totalYSize, layout.totalXSize); chi2DataVec_.segment(layout.totalYSize, layout.totalXSize);
@ -280,11 +283,6 @@ void XYStatData::resizeVarMat(void)
} }
// schedule buffer computation ///////////////////////////////////////////////// // schedule buffer computation /////////////////////////////////////////////////
void XYStatData::scheduleFitVarMatInit(void)
{
initVarMat_ = true;
}
void XYStatData::scheduleXMapInit(void) void XYStatData::scheduleXMapInit(void)
{ {
initXMap_ = true; initXMap_ = true;
@ -298,7 +296,7 @@ void XYStatData::scheduleChi2DataVecInit(void)
// buffer total fit variance matrix //////////////////////////////////////////// // buffer total fit variance matrix ////////////////////////////////////////////
void XYStatData::updateFitVarMat(void) void XYStatData::updateFitVarMat(void)
{ {
if (initVarMat_) if (initVarMat())
{ {
updateLayout(); updateLayout();
@ -378,8 +376,9 @@ void XYStatData::updateFitVarMat(void)
chi2DataVec_.resize(layout.totalSize); chi2DataVec_.resize(layout.totalSize);
chi2ModVec_.resize(layout.totalSize); chi2ModVec_.resize(layout.totalSize);
chi2Vec_.resize(layout.totalSize); chi2Vec_.resize(layout.totalSize);
fitVarInv_ = fitVar_.pInverse(); fitVar_ = fitVar_.cwiseProduct(makeCorrFilter());
initVarMat_ = false; fitVarInv_ = fitVar_.pInverse();
scheduleFitVarMatInit(false);
} }
} }
@ -419,6 +418,7 @@ void XYStatData::updateChi2DataVec(void)
{ {
Index a = 0, j, k, i, r; Index a = 0, j, k, i, r;
updateLayout();
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit) for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit) for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
{ {
@ -442,6 +442,8 @@ void XYStatData::updateChi2DataVec(void)
void XYStatData::updateChi2ModVec(const DVec p, void XYStatData::updateChi2ModVec(const DVec p,
const vector<const DoubleModel *> &v) const vector<const DoubleModel *> &v)
{ {
updateLayout();
Index nPar = v[0]->getNPar(), a = 0, j, k; Index nPar = v[0]->getNPar(), a = 0, j, k;
auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize); auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize);
@ -454,7 +456,7 @@ void XYStatData::updateChi2ModVec(const DVec p,
chi2ModVec_(a) = (*v[j])(xMap_[k].data(), par.data()); chi2ModVec_(a) = (*v[j])(xMap_[k].data(), par.data());
a++; a++;
} }
chi2ModVec_.segment(a, layout.totalSize) = xsi; chi2ModVec_.segment(a, layout.totalXSize) = xsi;
} }

View File

@ -83,6 +83,9 @@ public:
// fit // fit
FitResult fit(Minimizer &minimizer, const DVec &init, FitResult fit(Minimizer &minimizer, const DVec &init,
const std::vector<const DoubleModel *> &v); const std::vector<const DoubleModel *> &v);
template <typename... Ts>
FitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models);
protected: protected:
// create data // create data
virtual void createXData(const Index nData); virtual void createXData(const Index nData);
@ -90,7 +93,6 @@ protected:
void resizeVarMat(void); void resizeVarMat(void);
private: private:
// schedule buffer computation // schedule buffer computation
void scheduleFitVarMatInit(void);
void scheduleXMapInit(void); void scheduleXMapInit(void);
void scheduleChi2DataVecInit(void); void scheduleChi2DataVecInit(void);
// buffer total fit variance matrix // buffer total fit variance matrix
@ -108,11 +110,25 @@ private:
Mat<DMat> xxVar_, yyVar_, xyVar_; Mat<DMat> xxVar_, yyVar_, xyVar_;
DMat fitVar_, fitVarInv_; DMat fitVar_, fitVarInv_;
DVec chi2DataVec_, chi2ModVec_, chi2Vec_; DVec chi2DataVec_, chi2ModVec_, chi2Vec_;
bool initVarMat_{true};
bool initXMap_{true}; bool initXMap_{true};
bool initChi2DataVec_{true}; bool initChi2DataVec_{true};
}; };
/******************************************************************************
* XYStatData template implementation *
******************************************************************************/
template <typename... Ts>
FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models)
{
static_assert(static_or<std::is_assignable<DoubleModel &, Ts>::value...>::value,
"model arguments are not compatible with DoubleModel");
std::vector<const DoubleModel *> modelVector{&model, &models...};
return fit(minimizer, init, modelVector);
}
/****************************************************************************** /******************************************************************************
* error check macros * * error check macros *
******************************************************************************/ ******************************************************************************/