mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2024-11-10 00:45:36 +00:00
229 lines
9.3 KiB
C++
229 lines
9.3 KiB
C++
/*
|
|
* FitInterface.hpp, part of LatAnalyze 3
|
|
*
|
|
* Copyright (C) 2013 - 2020 Antonin Portelli
|
|
*
|
|
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* LatAnalyze 3 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef Latan_FitInterface_hpp_
|
|
#define Latan_FitInterface_hpp_
|
|
|
|
#include <LatAnalyze/Global.hpp>
|
|
#include <LatAnalyze/Core/Mat.hpp>
|
|
|
|
BEGIN_LATAN_NAMESPACE
|
|
|
|
/******************************************************************************
|
|
* FitInterface *
|
|
******************************************************************************/
|
|
class FitInterface
|
|
{
|
|
private:
|
|
typedef struct
|
|
{
|
|
Index nXFitDim, nYFitDim;
|
|
// X/Y block sizes
|
|
Index totalSize, totalXSize, totalYSize;
|
|
// size of each X/Y dimension
|
|
std::vector<Index> xSize, ySize;
|
|
// set of active data indices
|
|
std::set<Index> dataIndexSet;
|
|
// lookup tables
|
|
// xDim : x fit dim ifit -> x dim i
|
|
// x : x fit point ifit,rfit -> x point r
|
|
// xFitDim : x dim i -> x fit dim ifit (-1 if empty)
|
|
// xFit : x point i,r -> x fit point rfit (-1 if empty)
|
|
// data : y fit point jfit,sfit -> y point index k
|
|
// yFitFromData: y point index k,j -> y fit point sfit (-1 if empty)
|
|
// xIndFromData: data index k -> index of coordinates of associated x
|
|
std::vector<Index> xDim, yDim, xFitDim, yFitDim;
|
|
std::vector<std::vector<Index>> x, y, data, xFit, yFit;
|
|
std::vector<std::map<Index, Index>> yFitFromData;
|
|
// no map here for fit performance
|
|
std::vector<std::vector<Index>> xIndFromData;
|
|
} Layout;
|
|
public:
|
|
// constructor
|
|
FitInterface(void);
|
|
// destructor
|
|
virtual ~FitInterface(void) = default;
|
|
// copy object (not as a constructor to be accessed from derived class)
|
|
void copyInterface(const FitInterface &d);
|
|
// add dimensions
|
|
void addXDim(const Index nData, const std::string name = "",
|
|
const bool isExact = false);
|
|
void addYDim(const std::string name = "");
|
|
// access
|
|
Index getNXDim(void) const;
|
|
Index getNYDim(void) const;
|
|
Index getXSize(void) const;
|
|
Index getXSize(const Index i) const;
|
|
Index getYSize(void) const;
|
|
Index getYSize(const Index j) const;
|
|
Index getXFitSize(void) const;
|
|
Index getXFitSize(const Index i) const;
|
|
Index getYFitSize(void) const;
|
|
Index getYFitSize(const Index j) const;
|
|
Index getMaxDataIndex(void) const;
|
|
const std::set<Index> & getDataIndexSet(void) const;
|
|
double getSvdTolerance(void) const;
|
|
void setSvdTolerance(const double &tol);
|
|
VarName & xName(void);
|
|
const VarName & xName(void) const;
|
|
VarName & yName(void);
|
|
const VarName & yName(void) const;
|
|
|
|
// Y dimension index helper
|
|
template <typename... Ts>
|
|
Index dataIndex(const Ts... is) const;
|
|
Index dataIndex(const std::vector<Index> &v) const;
|
|
const std::vector<Index> & dataCoord(const Index k) const;
|
|
// enable fit points
|
|
void fitPoint(const bool isFitPoint, const Index k, const Index j = 0);
|
|
// variance interface
|
|
void assumeXExact(const bool isExact, const Index i);
|
|
void assumeXXCorrelated(const bool isCorr, const Index r1, const Index i1,
|
|
const Index r2, const Index i2);
|
|
void assumeXXCorrelated(const bool isCorr, const Index i1, const Index i2);
|
|
void assumeYYCorrelated(const bool isCorr, const Index k1, const Index j1,
|
|
const Index k2, const Index j2);
|
|
void assumeYYCorrelated(const bool isCorr, const Index j1, const Index j2);
|
|
void assumeXYCorrelated(const bool isCorr, const Index r, const Index i,
|
|
const Index k, const Index j);
|
|
void assumeXYCorrelated(const bool isCorr, const Index i, const Index j);
|
|
// tests
|
|
bool pointExists(const Index k) const;
|
|
bool pointExists(const Index k, const Index j) const;
|
|
bool isXExact(const Index i) const;
|
|
bool isXUsed(const Index r, const Index i, const bool inFit = true) const;
|
|
bool isFitPoint(const Index k, const Index j) const;
|
|
bool isXXCorrelated(const Index r1, const Index i1, const Index r2,
|
|
const Index i2) const;
|
|
bool isYYCorrelated(const Index k1, const Index j1, const Index k2,
|
|
const Index j2) const;
|
|
bool isXYCorrelated(const Index r, const Index i, const Index k,
|
|
const Index j) const;
|
|
bool hasCorrelations(void) const;
|
|
// make correlation filter for fit variance matrix
|
|
DMat makeCorrFilter(void);
|
|
// schedule variance matrix initialization
|
|
void scheduleFitVarMatInit(const bool init = true);
|
|
// IO
|
|
friend std::ostream & operator<<(std::ostream &out, FitInterface &f);
|
|
protected:
|
|
// register a data point
|
|
void registerDataPoint(const Index k, const Index j = 0);
|
|
// add correlation to a set
|
|
static void addCorr(std::set<std::array<Index, 4>> &s, const bool isCorr,
|
|
const std::array<Index, 4> &c);
|
|
// abstract methods to create data containers
|
|
virtual void createXData(const std::string name, const Index nData) = 0;
|
|
virtual void createYData(const std::string name) = 0;
|
|
// coordinate buffering
|
|
void scheduleDataCoordInit(void);
|
|
void updateDataCoord(void) const;
|
|
// global layout management
|
|
void scheduleLayoutInit(void);
|
|
bool initVarMat(void) const;
|
|
void updateLayout(void) const;
|
|
Index indX(const Index r, const Index i) 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:
|
|
Layout layout;
|
|
private:
|
|
VarName xName_, yName_;
|
|
std::vector<Index> xSize_;
|
|
std::vector<bool> xIsExact_;
|
|
std::map<Index, std::vector<Index>> dataCoord_;
|
|
std::set<Index> dataIndexSet_;
|
|
std::vector<std::map<Index, bool>> yDataIndex_;
|
|
std::set<std::array<Index, 4>> xxCorr_, yyCorr_, xyCorr_;
|
|
Index maxDataIndex_{1};
|
|
bool initLayout_{true};
|
|
bool initVarMat_{true};
|
|
bool initDataCoord_{true};
|
|
double svdTol_{1.e-10};
|
|
};
|
|
|
|
std::ostream & operator<<(std::ostream &out, FitInterface &f);
|
|
|
|
/******************************************************************************
|
|
* FitInterface template implementation *
|
|
******************************************************************************/
|
|
// Y dimension index helper ////////////////////////////////////////////////////
|
|
template <typename... Ts>
|
|
Index FitInterface::dataIndex(const Ts... coords) const
|
|
{
|
|
static_assert(static_or<std::is_convertible<Index, Ts>::value...>::value,
|
|
"fitPoint arguments are not compatible with Index");
|
|
|
|
const std::vector<Index> coord = {coords...};
|
|
|
|
return dataIndex(coord);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* error check macros *
|
|
******************************************************************************/
|
|
#define checkXDim(i)\
|
|
if ((i) >= getNXDim())\
|
|
{\
|
|
LATAN_ERROR(Range, "X dimension " + strFrom(i) + " out of range");\
|
|
}
|
|
|
|
#define checkXIndex(vi, i)\
|
|
if ((vi) >= getXSize(i))\
|
|
{\
|
|
LATAN_ERROR(Range, "index " + strFrom(vi) + " in X dimension "\
|
|
+ strFrom(i) + " out of range");\
|
|
}
|
|
|
|
#define checkYDim(j)\
|
|
if ((j) >= getNYDim())\
|
|
{\
|
|
LATAN_ERROR(Range, "Y dimension " + strFrom(j) + " out of range");\
|
|
}
|
|
|
|
#define checkDataIndex(k)\
|
|
if ((k) >= getMaxDataIndex())\
|
|
{\
|
|
LATAN_ERROR(Range, "data point index " + strFrom(k) + " invalid");\
|
|
}
|
|
|
|
#define checkDataCoord(v)\
|
|
if (static_cast<Index>((v).size()) != getNXDim())\
|
|
{\
|
|
LATAN_ERROR(Size, "number of coordinates and number of X dimensions "\
|
|
"mismatch");\
|
|
}\
|
|
for (unsigned int i_ = 0; i_ < (v).size(); ++i_)\
|
|
{\
|
|
checkXIndex((v)[i_], i_);\
|
|
}
|
|
|
|
#define checkPoint(k, j)\
|
|
if (!pointExists(k, j))\
|
|
{\
|
|
LATAN_ERROR(Range, "no data point in Y dimension " + strFrom(j)\
|
|
+ " with index " + strFrom(k));\
|
|
}
|
|
|
|
END_LATAN_NAMESPACE
|
|
|
|
#endif // Latan_FitInterface_hpp_
|