mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2024-11-10 00:45:36 +00:00
XYStatData (new): fit implemented (TO BE TESTED)
This commit is contained in:
parent
b165a98a93
commit
9f67ead605
@ -395,6 +395,8 @@ void FitInterface::updateLayout(void)
|
||||
{
|
||||
Index size, ifit;
|
||||
|
||||
layout.nXFitDim = 0;
|
||||
layout.nYFitDim = 0;
|
||||
layout.totalSize = 0;
|
||||
layout.totalXSize = 0;
|
||||
layout.totalYSize = 0;
|
||||
@ -413,6 +415,7 @@ void FitInterface::updateLayout(void)
|
||||
{
|
||||
if (!xIsExact_[i])
|
||||
{
|
||||
layout.nXFitDim++;
|
||||
size = getXFitSize(i);
|
||||
layout.xSize.push_back(size);
|
||||
layout.totalXSize += size;
|
||||
@ -448,6 +451,7 @@ void FitInterface::updateLayout(void)
|
||||
{
|
||||
Index s = 0;
|
||||
|
||||
layout.nYFitDim++;
|
||||
size = getYFitSize(j);
|
||||
layout.ySize.push_back(size);
|
||||
layout.totalYSize += size;
|
||||
|
@ -19,63 +19,49 @@
|
||||
|
||||
#include <LatAnalyze/XYStatData.hpp>
|
||||
#include <LatAnalyze/includes.hpp>
|
||||
#include <LatAnalyze/Math.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Latan;
|
||||
|
||||
/******************************************************************************
|
||||
* FitResult implementation *
|
||||
******************************************************************************/
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
double FitResult::getChi2(void) const
|
||||
{
|
||||
return chi2_;
|
||||
}
|
||||
|
||||
double FitResult::getChi2PerDof(void) const
|
||||
{
|
||||
return chi2_/getNDof();
|
||||
}
|
||||
|
||||
double FitResult::getNDof(void) const
|
||||
{
|
||||
return static_cast<double>(nDof_);
|
||||
}
|
||||
|
||||
double FitResult::getPValue(void) const
|
||||
{
|
||||
return Math::chi2PValue(getChi2(), getNDof());;
|
||||
}
|
||||
|
||||
const DoubleFunction & FitResult::getModel(const Index j) const
|
||||
{
|
||||
return model_[static_cast<unsigned int>(j)];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* XYStatData implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
XYStatData::XYStatData(void)
|
||||
{}
|
||||
|
||||
// schedule fit var matrix update //////////////////////////////////////////////
|
||||
void XYStatData::scheduleFitVarMatInit(void)
|
||||
{
|
||||
initVarMat_ = true;
|
||||
}
|
||||
|
||||
// create data /////////////////////////////////////////////////////////////////
|
||||
void XYStatData::createXData(const Index nData)
|
||||
{
|
||||
xData_.push_back(DVec::Zero(nData));
|
||||
resizeVarMat();
|
||||
}
|
||||
|
||||
void XYStatData::createYData(void)
|
||||
{
|
||||
yData_.push_back(map<Index, double>());
|
||||
resizeVarMat();
|
||||
}
|
||||
|
||||
void XYStatData::resizeVarMat(void)
|
||||
{
|
||||
xxVar_.conservativeResize(getNXDim(), getNXDim());
|
||||
for (Index i1 = 0; i1 < getNXDim(); ++i1)
|
||||
for (Index i2 = 0; i2 < getNXDim(); ++i2)
|
||||
{
|
||||
xxVar_(i1, i2).conservativeResize(getXSize(i1), getXSize(i2));
|
||||
}
|
||||
yyVar_.conservativeResize(getNYDim(), getNYDim());
|
||||
for (Index j1 = 0; j1 < getNYDim(); ++j1)
|
||||
for (Index j2 = 0; j2 < getNYDim(); ++j2)
|
||||
{
|
||||
yyVar_(j1, j2).conservativeResize(getYSize(j1), getYSize(j2));
|
||||
}
|
||||
xyVar_.conservativeResize(getNXDim(), getNYDim());
|
||||
for (Index i = 0; i < getNXDim(); ++i)
|
||||
for (Index j = 0; j < getNYDim(); ++j)
|
||||
{
|
||||
xyVar_(i, j).conservativeResize(getXSize(i), getYSize(j));
|
||||
}
|
||||
}
|
||||
|
||||
// data access /////////////////////////////////////////////////////////////////
|
||||
double & XYStatData::x(const Index vi, const Index i)
|
||||
{
|
||||
checkXIndex(vi, i);
|
||||
scheduleFitVarMatInit();
|
||||
scheduleXMapInit();
|
||||
scheduleChi2DataVecInit();
|
||||
|
||||
return xData_[i](vi);
|
||||
}
|
||||
@ -94,8 +80,9 @@ double & XYStatData::y(const Index k, const Index j)
|
||||
{
|
||||
registerDataPoint(k, j);
|
||||
resizeVarMat();
|
||||
scheduleFitVarMatInit();
|
||||
}
|
||||
scheduleXMapInit();
|
||||
scheduleChi2DataVecInit();
|
||||
|
||||
return yData_[j][k];
|
||||
}
|
||||
@ -107,15 +94,6 @@ const double & XYStatData::y(const Index k, const Index j) const
|
||||
return yData_[j].at(k);
|
||||
}
|
||||
|
||||
#define checkVarMat(m, var)\
|
||||
if (((m).rows() != (var).rows()) or ((m).cols() != (var).cols()))\
|
||||
{\
|
||||
LATAN_ERROR(Size, "provided variance matrix has a wrong size"\
|
||||
" (expected " + strFrom((var).rows()) + "x"\
|
||||
+ strFrom((var).cols()) + ", got " + strFrom((m).rows())\
|
||||
+ "x" + strFrom((m).cols()) + ")");\
|
||||
}
|
||||
|
||||
void XYStatData::setXXVar(const Index i1, const Index i2, const DMat &m)
|
||||
{
|
||||
checkXDim(i1);
|
||||
@ -151,14 +129,6 @@ void XYStatData::setXYVar(const Index i, const Index j, const DMat &m)
|
||||
scheduleFitVarMatInit();
|
||||
}
|
||||
|
||||
#define checkErrVec(err, var)\
|
||||
if ((err).size() != (var).rows())\
|
||||
{\
|
||||
LATAN_ERROR(Size, "provided error vector has a wrong size"\
|
||||
" (expected " + strFrom((var).rows()) + ", got "\
|
||||
+ strFrom((err).size()) + ")");\
|
||||
}
|
||||
|
||||
void XYStatData::setXError(const Index i, const DVec &err)
|
||||
{
|
||||
checkXDim(i);
|
||||
@ -214,14 +184,118 @@ DVec XYStatData::getYError(const Index j) const
|
||||
}
|
||||
|
||||
// get total fit variance matrix ///////////////////////////////////////////////
|
||||
const DMat & XYStatData::getFitVar(void)
|
||||
const DMat & XYStatData::getFitVarMat(void)
|
||||
{
|
||||
updateFitVarMat();
|
||||
|
||||
return fitVar_;
|
||||
}
|
||||
|
||||
// make total fit variance matrix //////////////////////////////////////////////
|
||||
const DMat & XYStatData::getFitVarMatPInv(void)
|
||||
{
|
||||
updateFitVarMat();
|
||||
|
||||
return fitVarInv_;
|
||||
}
|
||||
|
||||
// fit /////////////////////////////////////////////////////////////////////////
|
||||
FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
|
||||
const vector<const DoubleModel *> &v)
|
||||
{
|
||||
// check model consistency
|
||||
checkModelVec(v);
|
||||
|
||||
// get number of parameters
|
||||
Index nPar = v[0]->getNPar();
|
||||
Index totalNPar = nPar + layout.totalXSize;
|
||||
|
||||
// chi^2 function
|
||||
auto chi2Func = [this, totalNPar, &v](const double *x)->double
|
||||
{
|
||||
ConstMap<DVec> p(x, totalNPar);
|
||||
|
||||
updateChi2ModVec(p, v);
|
||||
chi2Vec_ = (chi2ModVec_ - chi2DataVec_);
|
||||
|
||||
return (chi2Vec_.transpose()*fitVarInv_).dot(chi2Vec_);
|
||||
};
|
||||
DoubleFunction chi2(chi2Func, totalNPar);
|
||||
|
||||
// minimization
|
||||
FitResult result;
|
||||
DVec totalInit(totalNPar);
|
||||
|
||||
updateFitVarMat();
|
||||
updateChi2DataVec();
|
||||
totalInit.segment(0, nPar) = init;
|
||||
totalInit.segment(nPar, layout.totalXSize) =
|
||||
chi2DataVec_.segment(layout.totalYSize, layout.totalXSize);
|
||||
minimizer.setInit(totalInit);
|
||||
result = minimizer(chi2);
|
||||
result.chi2_ = chi2(result);
|
||||
result.nDof_ = layout.totalYSize - nPar;
|
||||
result.model_.resize(v.size());
|
||||
for (unsigned int j = 0; j < v.size(); ++j)
|
||||
{
|
||||
result.model_[j] = v[j]->fixPar(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// create data /////////////////////////////////////////////////////////////////
|
||||
void XYStatData::createXData(const Index nData)
|
||||
{
|
||||
xData_.push_back(DVec::Zero(nData));
|
||||
resizeVarMat();
|
||||
}
|
||||
|
||||
void XYStatData::createYData(void)
|
||||
{
|
||||
yData_.push_back(map<Index, double>());
|
||||
resizeVarMat();
|
||||
}
|
||||
|
||||
void XYStatData::resizeVarMat(void)
|
||||
{
|
||||
xxVar_.conservativeResize(getNXDim(), getNXDim());
|
||||
for (Index i1 = 0; i1 < getNXDim(); ++i1)
|
||||
for (Index i2 = 0; i2 < getNXDim(); ++i2)
|
||||
{
|
||||
xxVar_(i1, i2).conservativeResize(getXSize(i1), getXSize(i2));
|
||||
}
|
||||
yyVar_.conservativeResize(getNYDim(), getNYDim());
|
||||
for (Index j1 = 0; j1 < getNYDim(); ++j1)
|
||||
for (Index j2 = 0; j2 < getNYDim(); ++j2)
|
||||
{
|
||||
yyVar_(j1, j2).conservativeResize(getYSize(j1), getYSize(j2));
|
||||
}
|
||||
xyVar_.conservativeResize(getNXDim(), getNYDim());
|
||||
for (Index i = 0; i < getNXDim(); ++i)
|
||||
for (Index j = 0; j < getNYDim(); ++j)
|
||||
{
|
||||
xyVar_(i, j).conservativeResize(getXSize(i), getYSize(j));
|
||||
}
|
||||
scheduleFitVarMatInit();
|
||||
}
|
||||
|
||||
// schedule buffer computation /////////////////////////////////////////////////
|
||||
void XYStatData::scheduleFitVarMatInit(void)
|
||||
{
|
||||
initVarMat_ = true;
|
||||
}
|
||||
|
||||
void XYStatData::scheduleXMapInit(void)
|
||||
{
|
||||
initXMap_ = true;
|
||||
}
|
||||
|
||||
void XYStatData::scheduleChi2DataVecInit(void)
|
||||
{
|
||||
initChi2DataVec_ = true;
|
||||
}
|
||||
|
||||
// buffer total fit variance matrix ////////////////////////////////////////////
|
||||
void XYStatData::updateFitVarMat(void)
|
||||
{
|
||||
if (initVarMat_)
|
||||
@ -301,6 +375,86 @@ void XYStatData::updateFitVarMat(void)
|
||||
}
|
||||
roffs += layout.xSize[ifit];
|
||||
}
|
||||
chi2DataVec_.resize(layout.totalSize);
|
||||
chi2ModVec_.resize(layout.totalSize);
|
||||
chi2Vec_.resize(layout.totalSize);
|
||||
fitVarInv_ = fitVar_.pInverse();
|
||||
initVarMat_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// buffer list of x vectors ////////////////////////////////////////////////////
|
||||
void XYStatData::updateXMap(void)
|
||||
{
|
||||
if (initXMap_)
|
||||
{
|
||||
vector<Index> v;
|
||||
set<Index> indSet;
|
||||
|
||||
for (Index j = 0; j < getNYDim(); ++j)
|
||||
{
|
||||
for (auto &p: yData_[j])
|
||||
{
|
||||
indSet.insert(p.first);
|
||||
}
|
||||
}
|
||||
xMap_.clear();
|
||||
for (auto k: indSet)
|
||||
{
|
||||
xMap_[k] = DVec(getNXDim());
|
||||
v = dataCoord(k);
|
||||
for (Index i = 0; i < getNXDim(); ++i)
|
||||
{
|
||||
xMap_[k](i) = xData_[i](v[i]);
|
||||
}
|
||||
}
|
||||
initXMap_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
// buffer chi^2 vectors ////////////////////////////////////////////////////////
|
||||
void XYStatData::updateChi2DataVec(void)
|
||||
{
|
||||
if (initChi2DataVec_)
|
||||
{
|
||||
Index a = 0, j, k, i, r;
|
||||
|
||||
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
|
||||
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
|
||||
{
|
||||
j = layout.yDim[jfit];
|
||||
k = layout.data[jfit][sfit];
|
||||
chi2DataVec_(a) = yData_[j][k];
|
||||
a++;
|
||||
}
|
||||
for (Index ifit = 0; ifit < layout.nXFitDim; ++ifit)
|
||||
for (Index rfit = 0; rfit < layout.xSize[ifit]; ++rfit)
|
||||
{
|
||||
i = layout.xDim[ifit];
|
||||
r = layout.x[ifit][rfit];
|
||||
chi2DataVec_(a) = xData_[i](r);
|
||||
a++;
|
||||
}
|
||||
initChi2DataVec_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void XYStatData::updateChi2ModVec(const DVec p,
|
||||
const vector<const DoubleModel *> &v)
|
||||
{
|
||||
Index nPar = v[0]->getNPar(), a = 0, j, k;
|
||||
auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize);
|
||||
|
||||
updateXMap();
|
||||
for (Index jfit = 0; jfit < layout.nYFitDim; ++jfit)
|
||||
for (Index sfit = 0; sfit < layout.ySize[jfit]; ++sfit)
|
||||
{
|
||||
j = layout.yDim[jfit];
|
||||
k = layout.data[jfit][sfit];
|
||||
chi2ModVec_(a) = (*v[j])(xMap_[k].data(), par.data());
|
||||
a++;
|
||||
}
|
||||
chi2ModVec_.segment(a, layout.totalSize) = xsi;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,9 +22,36 @@
|
||||
|
||||
#include <LatAnalyze/Global.hpp>
|
||||
#include <LatAnalyze/FitInterface.hpp>
|
||||
#include <LatAnalyze/Minimizer.hpp>
|
||||
#include <LatAnalyze/Model.hpp>
|
||||
|
||||
BEGIN_LATAN_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* object for fit result *
|
||||
******************************************************************************/
|
||||
class FitResult: public DVec
|
||||
{
|
||||
friend class XYStatData;
|
||||
friend class SampleFitResult;
|
||||
public:
|
||||
// constructors
|
||||
FitResult(void) = default;
|
||||
EIGEN_EXPR_CTOR(FitResult, FitResult, Base, MatExpr)
|
||||
// destructor
|
||||
virtual ~FitResult(void) = default;
|
||||
// access
|
||||
double getChi2(void) const;
|
||||
double getChi2PerDof(void) const;
|
||||
double getNDof(void) const;
|
||||
double getPValue(void) const;
|
||||
const DoubleFunction & getModel(const Index j = 0) const;
|
||||
private:
|
||||
double chi2_{0.0};
|
||||
Index nDof_{0};
|
||||
std::vector<DoubleFunction> model_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* class for X vs. Y statistical data *
|
||||
******************************************************************************/
|
||||
@ -32,11 +59,9 @@ class XYStatData: public FitInterface
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
XYStatData(void);
|
||||
XYStatData(void) = default;
|
||||
// destructor
|
||||
virtual ~XYStatData(void) = default;
|
||||
// schedule fit var matrix update
|
||||
void scheduleFitVarMatInit(void);
|
||||
// data access
|
||||
double & x(const Index vi, const Index i = 0);
|
||||
const double & x(const Index vi, const Index i = 0) const;
|
||||
@ -52,24 +77,92 @@ public:
|
||||
const DMat & getXYVar(const Index i, const Index j) const;
|
||||
DVec getXError(const Index i) const;
|
||||
DVec getYError(const Index j) const;
|
||||
// get total fit variance matrix
|
||||
const DMat & getFitVar(void);
|
||||
// get total fit variance matrix and its pseudo-inverse
|
||||
const DMat & getFitVarMat(void);
|
||||
const DMat & getFitVarMatPInv(void);
|
||||
// fit
|
||||
FitResult fit(Minimizer &minimizer, const DVec &init,
|
||||
const std::vector<const DoubleModel *> &v);
|
||||
protected:
|
||||
// create data
|
||||
virtual void createXData(const Index nData);
|
||||
virtual void createYData(void);
|
||||
void resizeVarMat(void);
|
||||
private:
|
||||
// make total fit variance matrix
|
||||
// schedule buffer computation
|
||||
void scheduleFitVarMatInit(void);
|
||||
void scheduleXMapInit(void);
|
||||
void scheduleChi2DataVecInit(void);
|
||||
// buffer total fit variance matrix
|
||||
void updateFitVarMat(void);
|
||||
// buffer list of x vectors
|
||||
void updateXMap(void);
|
||||
// buffer chi^2 vectors
|
||||
void updateChi2DataVec(void);
|
||||
void updateChi2ModVec(const DVec p,
|
||||
const std::vector<const DoubleModel *> &v);
|
||||
private:
|
||||
std::vector<std::map<Index, double>> yData_;
|
||||
std::vector<DVec> xData_;
|
||||
std::map<Index, DVec> xMap_;
|
||||
Mat<DMat> xxVar_, yyVar_, xyVar_;
|
||||
DMat fitVar_;
|
||||
DMat fitVar_, fitVarInv_;
|
||||
DVec chi2DataVec_, chi2ModVec_, chi2Vec_;
|
||||
bool initVarMat_{true};
|
||||
bool initXMap_{true};
|
||||
bool initChi2DataVec_{true};
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* error check macros *
|
||||
******************************************************************************/
|
||||
#define checkVarMat(m, var)\
|
||||
if (((m).rows() != (var).rows()) or ((m).cols() != (var).cols()))\
|
||||
{\
|
||||
LATAN_ERROR(Size, "provided variance matrix has a wrong size"\
|
||||
" (expected " + strFrom((var).rows()) + "x"\
|
||||
+ strFrom((var).cols()) + ", got " + strFrom((m).rows())\
|
||||
+ "x" + strFrom((m).cols()) + ")");\
|
||||
}
|
||||
|
||||
|
||||
#define checkErrVec(err, var)\
|
||||
if ((err).size() != (var).rows())\
|
||||
{\
|
||||
LATAN_ERROR(Size, "provided error vector has a wrong size"\
|
||||
" (expected " + strFrom((var).rows()) + ", got "\
|
||||
+ strFrom((err).size()) + ")");\
|
||||
}
|
||||
|
||||
#define checkModelVec(v)\
|
||||
if (static_cast<Index>((v).size()) != getNYDim())\
|
||||
{\
|
||||
LATAN_ERROR(Size, "provided model vector has a wrong size"\
|
||||
" (expected " + strFrom(getNYDim()) + ", got "\
|
||||
+ strFrom((v).size()) + ")");\
|
||||
}\
|
||||
for (unsigned int _i = 1; _i < (v).size(); ++_i)\
|
||||
{\
|
||||
if ((v)[_i]->getNArg() != getNXDim())\
|
||||
{\
|
||||
LATAN_ERROR(Size, "model " + strFrom(_i) + " has a wrong"\
|
||||
+ " number of argument (expected " + strFrom(getNXDim())\
|
||||
+ ", got " + strFrom((v)[_i]->getNArg()));\
|
||||
}\
|
||||
}\
|
||||
{\
|
||||
Index _nPar = (v)[0]->getNPar();\
|
||||
for (unsigned int _i = 1; _i < (v).size(); ++_i)\
|
||||
{\
|
||||
if ((v)[_i]->getNPar() != _nPar)\
|
||||
{\
|
||||
LATAN_ERROR(Size, "model " + strFrom(_i) + " has a wrong"\
|
||||
+ " number of parameter (expected " + strFrom(_nPar)\
|
||||
+ ", got " + strFrom((v)[_i]->getNPar()));\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
END_LATAN_NAMESPACE
|
||||
|
||||
#endif // Latan_XYStatData_hpp_
|
||||
|
Loading…
Reference in New Issue
Block a user