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

new fit: partial residuals and plots

This commit is contained in:
Antonin Portelli 2016-04-04 19:09:18 +01:00
parent f82b20dc73
commit 07bacf0e4b
10 changed files with 335 additions and 99 deletions

View File

@ -4,6 +4,7 @@
#include <LatAnalyze/Io.hpp> #include <LatAnalyze/Io.hpp>
#include <LatAnalyze/MinuitMinimizer.hpp> #include <LatAnalyze/MinuitMinimizer.hpp>
#include <LatAnalyze/NloptMinimizer.hpp> #include <LatAnalyze/NloptMinimizer.hpp>
#include <LatAnalyze/Plot.hpp>
#include <LatAnalyze/RandGen.hpp> #include <LatAnalyze/RandGen.hpp>
#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
@ -11,7 +12,7 @@ using namespace std;
using namespace Latan; using namespace Latan;
const Index nPoint1 = 10, nPoint2 = 10; const Index nPoint1 = 10, nPoint2 = 10;
const double xErr = .1, yErr = .1; const double xErr = .1, yErr = .3;
const double exactPar[2] = {0.5,5.}; const double exactPar[2] = {0.5,5.};
const double dx1 = 10.0/static_cast<double>(nPoint1); const double dx1 = 10.0/static_cast<double>(nPoint1);
const double dx2 = 5.0/static_cast<double>(nPoint2); const double dx2 = 5.0/static_cast<double>(nPoint2);
@ -25,6 +26,7 @@ int main(void)
DoubleModel f([](const double *x, const double *p) DoubleModel f([](const double *x, const double *p)
{return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2); {return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2);
cout << "-- generating fake data..." << endl;
data.addXDim(nPoint1); data.addXDim(nPoint1);
data.addXDim(nPoint2); data.addXDim(nPoint2);
data.addYDim(); data.addYDim();
@ -36,7 +38,7 @@ int main(void)
{ {
xBuf[1] = i2*dx2; xBuf[1] = i2*dx2;
data.x(i2, 1) = xBuf[1]; data.x(i2, 1) = xBuf[1];
data.y(data.dataIndex(i1, i2)) = rg.gaussian(f(xBuf, exactPar), data.y(data.dataIndex(i1, i2), 0) = rg.gaussian(f(xBuf, exactPar),
yErr); yErr);
} }
} }
@ -52,7 +54,7 @@ int main(void)
vector<Minimizer *> min{&globalMin, &localMin}; vector<Minimizer *> min{&globalMin, &localMin};
globalMin.setVerbosity(Minimizer::Verbosity::Normal); globalMin.setVerbosity(Minimizer::Verbosity::Normal);
globalMin.setPrecision(0.01); globalMin.setPrecision(0.1);
globalMin.setMaxIteration(10000); globalMin.setMaxIteration(10000);
globalMin.useLowLimit(0); globalMin.useLowLimit(0);
globalMin.setLowLimit(0, 0.); globalMin.setLowLimit(0, 0.);
@ -65,10 +67,26 @@ int main(void)
localMin.setVerbosity(Minimizer::Verbosity::Normal); localMin.setVerbosity(Minimizer::Verbosity::Normal);
// fit // fit
cout << "-- fit..." << endl;
f.parName().setName(0, "m"); f.parName().setName(0, "m");
f.parName().setName(1, "A"); f.parName().setName(1, "A");
p = data.fit(min, init, f); p = data.fit(min, init, f);
p.print(); p.print();
// plot
Plot plot;
DVec ref(2);
XYStatData res;
cout << "-- generating plots..." << endl;
ref(1) = 0.;
res = data.getPartialResiduals(p, ref, 0);
plot << PlotRange(Axis::x, 0., 10.);
plot << Color("rgb 'blue'");
plot << PlotFunction(p.getModel().bind(0, ref), 0., 10.);
plot << Color("rgb 'red'");
plot << PlotData(res);
plot.display();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -3,6 +3,7 @@
#include <LatAnalyze/CompiledModel.hpp> #include <LatAnalyze/CompiledModel.hpp>
#include <LatAnalyze/MinuitMinimizer.hpp> #include <LatAnalyze/MinuitMinimizer.hpp>
#include <LatAnalyze/NloptMinimizer.hpp> #include <LatAnalyze/NloptMinimizer.hpp>
#include <LatAnalyze/Plot.hpp>
#include <LatAnalyze/RandGen.hpp> #include <LatAnalyze/RandGen.hpp>
#include <LatAnalyze/XYSampleData.hpp> #include <LatAnalyze/XYSampleData.hpp>
@ -11,7 +12,7 @@ using namespace Latan;
const Index nPoint1 = 10, nPoint2 = 10; const Index nPoint1 = 10, nPoint2 = 10;
const Index nSample = 1000; const Index nSample = 1000;
const double xErr = .1, yErr = .1; const double xErr = .1, yErr = .3;
const double exactPar[2] = {0.5,5.}; const double exactPar[2] = {0.5,5.};
const double dx1 = 10.0/static_cast<double>(nPoint1); const double dx1 = 10.0/static_cast<double>(nPoint1);
const double dx2 = 5.0/static_cast<double>(nPoint2); const double dx2 = 5.0/static_cast<double>(nPoint2);
@ -25,6 +26,7 @@ int main(void)
DoubleModel f([](const double *x, const double *p) DoubleModel f([](const double *x, const double *p)
{return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2); {return p[1]*exp(-x[0]*p[0])+x[1];}, 2, 2);
cout << "-- generating fake data..." << endl;
data.addXDim(nPoint1); data.addXDim(nPoint1);
data.addXDim(nPoint2); data.addXDim(nPoint2);
data.addYDim(); data.addYDim();
@ -38,7 +40,7 @@ int main(void)
{ {
xBuf[1] = i2*dx2; xBuf[1] = i2*dx2;
data.x(i2, 1)[s] = xBuf[1]; data.x(i2, 1)[s] = xBuf[1];
data.y(data.dataIndex(i1, i2))[s] = data.y(data.dataIndex(i1, i2), 0)[s] =
rg.gaussian(f(xBuf, exactPar), yErr); rg.gaussian(f(xBuf, exactPar), yErr);
} }
} }
@ -52,7 +54,7 @@ int main(void)
MinuitMinimizer localMin; MinuitMinimizer localMin;
vector<Minimizer *> min{&globalMin, &localMin}; vector<Minimizer *> min{&globalMin, &localMin};
globalMin.setPrecision(0.01); globalMin.setPrecision(0.1);
globalMin.setMaxIteration(10000); globalMin.setMaxIteration(10000);
globalMin.useLowLimit(0); globalMin.useLowLimit(0);
globalMin.setLowLimit(0, 0.); globalMin.setLowLimit(0, 0.);
@ -64,10 +66,28 @@ int main(void)
globalMin.setHighLimit(1, 20.); globalMin.setHighLimit(1, 20.);
// fit // fit
cout << "-- fit..." << endl;
f.parName().setName(0, "m"); f.parName().setName(0, "m");
f.parName().setName(1, "A"); f.parName().setName(1, "A");
p = data.fit(min, init, f); p = data.fit(min, init, f);
p.print(); p.print();
// plot
Plot plot;
DVec ref(2);
XYStatData res;
cout << "-- generating plots..." << endl;
ref(1) = 0.;
res = data.getPartialResiduals(p, ref, 0).getData();
plot << PlotRange(Axis::x, 0., 10.);
plot << Color("rgb 'blue'");
plot << PlotPredBand(p.getModel(_).bind(0, ref), 0., 10.);
plot << Color("rgb 'blue'");
plot << PlotFunction(p.getModel().bind(0, ref), 0., 10.);
plot << Color("rgb 'red'");
plot << PlotData(res);
plot.display();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -54,6 +54,7 @@ void FitInterface::addXDim(const Index nData, const string name,
maxDataIndex_ *= nData; maxDataIndex_ *= nData;
createXData(name, nData); createXData(name, nData);
scheduleLayoutInit(); scheduleLayoutInit();
scheduleDataCoordInit();
if (!name.empty()) if (!name.empty())
{ {
xName().setName(getNXDim(), name); xName().setName(getNXDim(), name);
@ -121,7 +122,7 @@ Index FitInterface::getYSize(const Index j) const
return static_cast<Index>(yDataIndex_[j].size()); return static_cast<Index>(yDataIndex_[j].size());
} }
Index FitInterface::getXFitSize(void) const Index FitInterface::getXFitSize(void)
{ {
Index size = 0; Index size = 0;
@ -133,7 +134,7 @@ Index FitInterface::getXFitSize(void) const
return size; return size;
} }
Index FitInterface::getXFitSize(const Index i) const Index FitInterface::getXFitSize(const Index i)
{ {
set<Index> fitCoord; set<Index> fitCoord;
vector<Index> v; vector<Index> v;
@ -185,6 +186,11 @@ Index FitInterface::getMaxDataIndex(void) const
return maxDataIndex_; return maxDataIndex_;
} }
const set<Index> & FitInterface::getDataIndexSet(void) const
{
return dataIndexSet_;
}
VarName & FitInterface::xName(void) VarName & FitInterface::xName(void)
{ {
return xName_; return xName_;
@ -221,22 +227,13 @@ Index FitInterface::dataIndex(const vector<Index> &v) const
return k; return k;
} }
vector<Index> FitInterface::dataCoord(const Index k) const const vector<Index> & FitInterface::dataCoord(const Index k)
{ {
vector<Index> v(getNXDim());
Index buf, dimProd;
checkDataIndex(k); checkDataIndex(k);
buf = k;
dimProd = 1;
for (Index d = getNXDim() - 1; d >= 0; --d)
{
v[d] = (buf/dimProd)%xSize_[d];
buf -= dimProd*v[d];
dimProd *= xSize_[d];
}
return v; updateDataCoord();
return dataCoord_.at(k);
} }
// enable fit points /////////////////////////////////////////////////////////// // enable fit points ///////////////////////////////////////////////////////////
@ -335,7 +332,12 @@ bool FitInterface::pointExists(const Index k, const Index j) const
return !(yDataIndex_[j].find(k) == yDataIndex_[j].end()); return !(yDataIndex_[j].find(k) == yDataIndex_[j].end());
} }
bool FitInterface::isXUsed(const Index r, const Index i, const bool inFit) const bool FitInterface::isXExact(const Index i) const
{
return xIsExact_[i];
}
bool FitInterface::isXUsed(const Index r, const Index i, const bool inFit)
{ {
vector<Index> v; vector<Index> v;
@ -418,9 +420,29 @@ void FitInterface::registerDataPoint(const Index k, const Index j)
{ {
checkYDim(j); checkYDim(j);
yDataIndex_[j][k] = true; yDataIndex_[j][k] = true;
dataIndexSet_.insert(k);
scheduleLayoutInit(); scheduleLayoutInit();
} }
// coordinate buffering ////////////////////////////////////////////////////////
void FitInterface::scheduleDataCoordInit(void)
{
initDataCoord_ = true;
}
void FitInterface::updateDataCoord(void)
{
if (initDataCoord_)
{
dataCoord_.clear();
for (auto k: getDataIndexSet())
{
dataCoord_[k] = rowMajToCoord(k);
}
initDataCoord_ = false;
}
}
// global layout management //////////////////////////////////////////////////// // global layout management ////////////////////////////////////////////////////
void FitInterface::scheduleLayoutInit(void) void FitInterface::scheduleLayoutInit(void)
{ {
@ -578,6 +600,25 @@ Index FitInterface::indY(const Index k, const Index j) const
return ind; return ind;
} }
// function to convert an row-major index into coordinates /////////////////////
vector<Index> FitInterface::rowMajToCoord(const Index k) const
{
vector<Index> v(getNXDim());
Index buf, dimProd;
checkDataIndex(k);
buf = k;
dimProd = 1;
for (Index d = getNXDim() - 1; d >= 0; --d)
{
v[d] = (buf/dimProd)%xSize_[d];
buf -= dimProd*v[d];
dimProd *= xSize_[d];
}
return v;
}
// IO ////////////////////////////////////////////////////////////////////////// // IO //////////////////////////////////////////////////////////////////////////
ostream & Latan::operator<<(ostream &out, FitInterface &f) ostream & Latan::operator<<(ostream &out, FitInterface &f)
{ {

View File

@ -71,11 +71,12 @@ public:
Index getXSize(const Index i) const; Index getXSize(const Index i) const;
Index getYSize(void) const; Index getYSize(void) const;
Index getYSize(const Index j) const; Index getYSize(const Index j) const;
Index getXFitSize(void) const; Index getXFitSize(void);
Index getXFitSize(const Index i) const; Index getXFitSize(const Index i);
Index getYFitSize(void) const; Index getYFitSize(void) const;
Index getYFitSize(const Index j) const; Index getYFitSize(const Index j) const;
Index getMaxDataIndex(void) const; Index getMaxDataIndex(void) const;
const std::set<Index> & getDataIndexSet(void) const;
VarName & xName(void); VarName & xName(void);
const VarName & xName(void) const; const VarName & xName(void) const;
VarName & yName(void); VarName & yName(void);
@ -84,7 +85,7 @@ public:
template <typename... Ts> template <typename... Ts>
Index dataIndex(const Ts... is) const; Index dataIndex(const Ts... is) const;
Index dataIndex(const std::vector<Index> &v) const; Index dataIndex(const std::vector<Index> &v) const;
std::vector<Index> dataCoord(const Index k) const; const std::vector<Index> & dataCoord(const Index k);
// enable fit points // enable fit points
void fitPoint(const bool isFitPoint, const Index k, const Index j = 0); void fitPoint(const bool isFitPoint, const Index k, const Index j = 0);
// variance interface // variance interface
@ -98,7 +99,8 @@ public:
// tests // tests
bool pointExists(const Index k) const; bool pointExists(const Index k) const;
bool pointExists(const Index k, const Index j) const; bool pointExists(const Index k, const Index j) const;
bool isXUsed(const Index r, const Index i, const bool inFit = true) const; bool isXExact(const Index i) const;
bool isXUsed(const Index r, const Index i, const bool inFit = true);
bool isFitPoint(const Index k, const Index j) const; bool isFitPoint(const Index k, const Index j) const;
// make correlation filter for fit variance matrix // make correlation filter for fit variance matrix
DMat makeCorrFilter(void); DMat makeCorrFilter(void);
@ -115,22 +117,31 @@ protected:
// abstract methods to create data containers // abstract methods to create data containers
virtual void createXData(const std::string name, const Index nData) = 0; virtual void createXData(const std::string name, const Index nData) = 0;
virtual void createYData(const std::string name) = 0; virtual void createYData(const std::string name) = 0;
// coordinate buffering
void scheduleDataCoordInit(void);
void updateDataCoord(void);
// global layout management // global layout management
void scheduleLayoutInit(void); void scheduleLayoutInit(void);
bool initVarMat(void); 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;
private:
// function to convert an row-major index into coordinates
std::vector<Index> rowMajToCoord(const Index k) const;
protected: protected:
Layout layout; Layout layout;
private: private:
VarName xName_, yName_; VarName xName_, yName_;
std::vector<Index> xSize_; std::vector<Index> xSize_;
std::vector<bool> xIsExact_; std::vector<bool> xIsExact_;
std::map<Index, std::vector<Index>> dataCoord_;
std::set<Index> dataIndexSet_;
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}, initVarMat_{true}; bool initLayout_{true}, initVarMat_{true};
bool initDataCoord_{true};
}; };
std::ostream & operator<<(std::ostream &out, FitInterface &f); std::ostream & operator<<(std::ostream &out, FitInterface &f);

View File

@ -167,20 +167,15 @@ PlotData::PlotData(const DMatSample &x, const DVec &y)
setCommand("'" + tmpFileName + "' u 1:3:2 w xerr"); setCommand("'" + tmpFileName + "' u 1:3:2 w xerr");
} }
//PlotData::PlotData(const XYStatData &data, const Index i, const Index j) PlotData::PlotData(XYStatData &data, const Index i, const Index j)
//{ {
// DMat d(data.getNData(), 4); string usingCmd, tmpFileName;
// string usingCmd, tmpFileName;
// usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr";
// d.col(0) = data.x(i); tmpFileName = dumpToTmpFile(data.getTable(i, j));
// d.col(2) = data.y(j); pushTmpFile(tmpFileName);
// d.col(1) = data.xxVar(i, i).diagonal().array().sqrt(); setCommand("'" + tmpFileName + "' " + usingCmd);
// d.col(3) = data.yyVar(j, j).diagonal().array().sqrt(); }
// usingCmd = (data.isXExact(i)) ? "u 1:3:4 w yerr" : "u 1:3:2:4 w xyerr";
// tmpFileName = dumpToTmpFile(d);
// pushTmpFile(tmpFileName);
// setCommand("'" + tmpFileName + "' " + usingCmd);
//}
// PlotHLine constructor /////////////////////////////////////////////////////// // PlotHLine constructor ///////////////////////////////////////////////////////
PlotHLine::PlotHLine(const double y) PlotHLine::PlotHLine(const double y)

View File

@ -25,7 +25,7 @@
#include <LatAnalyze/Mat.hpp> #include <LatAnalyze/Mat.hpp>
#include <LatAnalyze/MatSample.hpp> #include <LatAnalyze/MatSample.hpp>
#include <LatAnalyze/Histogram.hpp> #include <LatAnalyze/Histogram.hpp>
//#include <LatAnalyze/XYStatData.hpp> #include <LatAnalyze/XYStatData.hpp>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
@ -94,7 +94,7 @@ public:
PlotData(const DMatSample &x, const DMatSample &y); PlotData(const DMatSample &x, const DMatSample &y);
PlotData(const DVec &x, const DMatSample &y); PlotData(const DVec &x, const DMatSample &y);
PlotData(const DMatSample &x, const DVec &y); PlotData(const DMatSample &x, const DVec &y);
//PlotData(const XYStatData &data, const Index i = 0, const Index j = 0); PlotData(XYStatData &data, const Index i = 0, const Index j = 0);
// destructor // destructor
virtual ~PlotData(void) = default; virtual ~PlotData(void) = default;
}; };

View File

@ -138,6 +138,15 @@ const DSample & XYSampleData::x(const Index r, const Index i) const
return xData_[i][r]; return xData_[i][r];
} }
const DMatSample & XYSampleData::x(const Index k)
{
checkDataIndex(k);
updateXMap();
return xMap_.at(k);
}
DSample & XYSampleData::y(const Index k, const Index j) DSample & XYSampleData::y(const Index k, const Index j)
{ {
checkYDim(j); checkYDim(j);
@ -299,6 +308,74 @@ SampleFitResult XYSampleData::fit(Minimizer &minimizer,
return fit(mv, init, v); return fit(mv, init, v);
} }
// residuals ///////////////////////////////////////////////////////////////////
XYSampleData XYSampleData::getResiduals(const SampleFitResult &fit)
{
XYSampleData res(*this);
for (Index j = 0; j < getNYDim(); ++j)
{
const DoubleFunctionSample &f = fit.getModel(_, j);
for (auto &p: yData_[j])
{
res.y(p.first, j) -= f(x(p.first));
}
}
return res;
}
XYSampleData XYSampleData::getPartialResiduals(const SampleFitResult &fit,
const DVec &ref, const Index i)
{
XYSampleData res(*this);
DMatSample buf(nSample_);
buf.fill(ref);
for (Index j = 0; j < getNYDim(); ++j)
{
const DoubleFunctionSample &f = fit.getModel(_, j);
for (auto &p: yData_[j])
{
FOR_STAT_ARRAY(buf, s)
{
buf[s](i) = x(p.first)[s](i);
}
res.y(p.first, j) -= f(x(p.first)) - f(buf);
}
}
return res;
}
// buffer list of x vectors ////////////////////////////////////////////////////
void XYSampleData::scheduleXMapInit(void)
{
initXMap_ = true;
}
void XYSampleData::updateXMap(void)
{
if (initXMap_)
{
for (Index s = central; s < nSample_; ++s)
{
setDataToSample(s);
for (auto k: getDataIndexSet())
{
if (s == central)
{
xMap_[k].resize(nSample_);
}
xMap_[k][s] = data_.x(k);
}
}
initXMap_ = false;
}
}
// schedule data initilization from samples //////////////////////////////////// // schedule data initilization from samples ////////////////////////////////////
void XYSampleData::scheduleDataInit(void) void XYSampleData::scheduleDataInit(void)
{ {

View File

@ -75,10 +75,11 @@ public:
// destructor // destructor
virtual ~XYSampleData(void) = default; virtual ~XYSampleData(void) = default;
// data access // data access
DSample & x(const Index r, const Index i = 0); DSample & x(const Index r, const Index i);
const DSample & x(const Index r, const Index i = 0) const; const DSample & x(const Index r, const Index i) const;
DSample & y(const Index k, const Index j = 0); const DMatSample & x(const Index k);
const DSample & y(const Index k, const Index j = 0) const; DSample & y(const Index k, const Index j);
const DSample & y(const Index k, const Index j) const;
const DMat & getXXVar(const Index i1, const Index i2); const DMat & getXXVar(const Index i1, const Index i2);
const DMat & getYYVar(const Index j1, const Index j2); const DMat & getYYVar(const Index j1, const Index j2);
const DMat & getXYVar(const Index i, const Index j); const DMat & getXYVar(const Index i, const Index j);
@ -102,7 +103,14 @@ public:
template <typename... Ts> template <typename... Ts>
SampleFitResult fit(Minimizer &minimizer, const DVec &init, SampleFitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models); const DoubleModel &model, const Ts... models);
// residuals
XYSampleData getResiduals(const SampleFitResult &fit);
XYSampleData getPartialResiduals(const SampleFitResult &fit, const DVec &x,
const Index i);
private: private:
// buffer list of x vectors
void scheduleXMapInit(void);
void updateXMap(void);
// schedule data initilization from samples // schedule data initilization from samples
void scheduleDataInit(void); void scheduleDataInit(void);
// variance matrix computation // variance matrix computation
@ -114,9 +122,11 @@ private:
private: private:
std::vector<std::map<Index, DSample>> yData_; std::vector<std::map<Index, DSample>> yData_;
std::vector<std::vector<DSample>> xData_; std::vector<std::vector<DSample>> xData_;
std::map<Index, DMatSample> xMap_;
XYStatData data_; XYStatData data_;
Index nSample_, dataSample_{central}; Index nSample_, dataSample_{central};
bool initData_{true}, computeVarMat_{true}; bool initData_{true}, computeVarMat_{true};
bool initXMap_{true};
}; };
/****************************************************************************** /******************************************************************************

View File

@ -96,6 +96,15 @@ const double & XYStatData::x(const Index r, const Index i) const
return xData_[i](r); return xData_[i](r);
} }
const DVec & XYStatData::x(const Index k)
{
checkDataIndex(k);
updateXMap();
return xMap_.at(k);
}
double & XYStatData::y(const Index k, const Index j) double & XYStatData::y(const Index k, const Index j)
{ {
checkYDim(j); checkYDim(j);
@ -206,6 +215,29 @@ DVec XYStatData::getYError(const Index j) const
return yyVar_(j, j).diagonal().cwiseSqrt(); return yyVar_(j, j).diagonal().cwiseSqrt();
} }
DMat XYStatData::getTable(const Index i, const Index j)
{
checkXDim(i);
checkYDim(j);
DMat table(getYSize(j), 4);
Index row = 0;
for (auto &p: yData_[j])
{
Index k = p.first;
Index r = dataCoord(k)[i];
table(row, 0) = x(k)(i);
table(row, 2) = p.second;
table(row, 1) = xxVar_(i, i).diagonal().cwiseSqrt()(r);
table(row, 3) = yyVar_(j, j).diagonal().cwiseSqrt()(row);
row++;
}
return table;
}
// get total fit variance matrix /////////////////////////////////////////////// // get total fit variance matrix ///////////////////////////////////////////////
const DMat & XYStatData::getFitVarMat(void) const DMat & XYStatData::getFitVarMat(void)
{ {
@ -308,6 +340,44 @@ FitResult XYStatData::fit(Minimizer &minimizer, const DVec &init,
return fit(mv, init, v); return fit(mv, init, v);
} }
// residuals ///////////////////////////////////////////////////////////////////
XYStatData XYStatData::getResiduals(const FitResult &fit)
{
XYStatData res(*this);
for (Index j = 0; j < getNYDim(); ++j)
{
const DoubleFunction &f = fit.getModel(j);
for (auto &p: yData_[j])
{
res.y(p.first, j) -= f(x(p.first));
}
}
return res;
}
XYStatData XYStatData::getPartialResiduals(const FitResult &fit,
const DVec &ref, const Index i)
{
XYStatData res(*this);
DVec buf(ref);
for (Index j = 0; j < res.getNYDim(); ++j)
{
const DoubleFunction &f = fit.getModel(j);
for (auto &p: yData_[j])
{
buf(i) = x(p.first)(i);
res.y(p.first, j) -= f(x(p.first)) - f(buf);
}
}
return res;
}
// create data ///////////////////////////////////////////////////////////////// // create data /////////////////////////////////////////////////////////////////
void XYStatData::createXData(const std::string name __dumb, const Index nData) void XYStatData::createXData(const std::string name __dumb, const Index nData)
{ {
@ -450,24 +520,13 @@ void XYStatData::updateXMap(void)
{ {
if (initXMap_) 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(); xMap_.clear();
for (auto k: indSet) for (auto k: getDataIndexSet())
{ {
xMap_[k] = DVec(getNXDim()); xMap_[k] = DVec(getNXDim());
v = dataCoord(k);
for (Index i = 0; i < getNXDim(); ++i) for (Index i = 0; i < getNXDim(); ++i)
{ {
xMap_[k](i) = xData_[i](v[i]); xMap_[k](i) = xData_[i](dataCoord(k)[i]);
} }
} }
initXMap_ = false; initXMap_ = false;
@ -510,7 +569,6 @@ void XYStatData::updateChi2ModVec(const DVec p,
Index nPar = v[0]->getNPar(), a = 0, j, k, ind; Index nPar = v[0]->getNPar(), a = 0, j, k, ind;
auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize); auto &par = p.segment(0, nPar), &xsi = p.segment(nPar, layout.totalXSize);
updateXMap();
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)
{ {
@ -519,7 +577,7 @@ void XYStatData::updateChi2ModVec(const DVec p,
for (Index i = 0; i < getNXDim(); ++i) for (Index i = 0; i < getNXDim(); ++i)
{ {
ind = layout.xIndFromData[k][i] - layout.totalYSize; ind = layout.xIndFromData[k][i] - layout.totalYSize;
xBuf_(i) = (ind >= 0) ? xsi(ind) : xMap_[k](i); xBuf_(i) = (ind >= 0) ? xsi(ind) : x(k)(i);
} }
chi2ModVec_(a) = (*v[j])(xBuf_.data(), par.data()); chi2ModVec_(a) = (*v[j])(xBuf_.data(), par.data());
a++; a++;

View File

@ -69,10 +69,11 @@ public:
// destructor // destructor
virtual ~XYStatData(void) = default; virtual ~XYStatData(void) = default;
// data access // data access
double & x(const Index r, const Index i = 0); double & x(const Index r, const Index);
const double & x(const Index r, const Index i = 0) const; const double & x(const Index r, const Index) const;
double & y(const Index k, const Index j = 0); const DVec & x(const Index k);
const double & y(const Index k, const Index j = 0) const; double & y(const Index k, const Index);
const double & y(const Index k, const Index) const;
void setXXVar(const Index i1, const Index i2, const DMat &m); void setXXVar(const Index i1, const Index i2, const DMat &m);
void setYYVar(const Index j1, const Index j2, const DMat &m); void setYYVar(const Index j1, const Index j2, const DMat &m);
void setXYVar(const Index i, const Index j, const DMat &m); void setXYVar(const Index i, const Index j, const DMat &m);
@ -83,6 +84,7 @@ public:
const DMat & getXYVar(const Index i, const Index j) const; const DMat & getXYVar(const Index i, const Index j) const;
DVec getXError(const Index i) const; DVec getXError(const Index i) const;
DVec getYError(const Index j) const; DVec getYError(const Index j) const;
DMat getTable(const Index i, const Index j);
// get total fit variance matrix and its pseudo-inverse // get total fit variance matrix and its pseudo-inverse
const DMat & getFitVarMat(void); const DMat & getFitVarMat(void);
const DMat & getFitVarMatPInv(void); const DMat & getFitVarMatPInv(void);
@ -97,6 +99,10 @@ public:
template <typename... Ts> template <typename... Ts>
FitResult fit(Minimizer &minimizer, const DVec &init, FitResult fit(Minimizer &minimizer, const DVec &init,
const DoubleModel &model, const Ts... models); const DoubleModel &model, const Ts... models);
// residuals
XYStatData getResiduals(const FitResult &fit);
XYStatData getPartialResiduals(const FitResult &fit, const DVec &ref,
const Index i);
protected: protected:
// create data // create data
virtual void createXData(const std::string name, const Index nData); virtual void createXData(const std::string name, const Index nData);