1 #ifndef NPSTAT_ABSUNFOLD1D_HH_
2 #define NPSTAT_ABSUNFOLD1D_HH_
22 #include "npstat/wrap/NumpyTypecode.hh"
26 class LocalPolyFilter1D;
42 {
return responseMatrix_;}
44 inline const Matrix<double>& transposedResponseMatrix()
const
45 {
return responseMatrixT_;}
47 inline const std::vector<double>& efficiency()
const
56 std::pair<double, double> responseNDoF()
const;
57 std::pair<double, double> smoothedResponseNDoF()
const;
69 const double* approx,
unsigned lenApprox);
107 virtual bool unfold(
const double* observed,
unsigned lenObserved,
109 double* unfolded,
unsigned lenUnfolded,
116 static double probDelta(
const double* prev,
const double* next,
124 const double* yhat,
unsigned lenObserved,
bool isMultinomial);
129 void buildUniformInitialApproximation(
const double* observed,
130 unsigned lenObserved,
131 std::vector<double>* result)
const;
136 void validateDimensions(
unsigned lenObserved,
unsigned lenUnfold)
const;
141 static void validateDensity(
const double* observ,
142 unsigned lenObserved);
153 std::vector<double> efficiency_;
154 std::vector<double> initialApproximation_;
156 bool useConvolutions_;
164 static inline double probDelta2(
const double* prev,
unsigned prevlen,
165 const double* next,
unsigned nextlen)
167 if (prevlen != nextlen)
throw std::runtime_error(
168 "In npstat::AbsUnfold1D::probDelta2: incompatible inputs");
171 inline PyObject* unfold2(
const double* observed,
unsigned lenObserved,
172 Matrix<double>* covMatOut)
175 const int typenum = NumpyTypecode<double>::code;
176 npy_intp sh = responseMatrix_.nColumns();
177 PyObject* array = PyArray_SimpleNew(1, &sh, typenum);
178 double* result = (
double*)PyArray_DATA((PyArrayObject*)array);
181 const bool status = this->
unfold(observed, lenObserved, 0,
182 result, sh, covMatOut);
183 if (!status)
throw std::runtime_error(
184 "In npstat::AbsUnfold1D::unfold2: "
185 "expectation-maximization iterations failed to converge");
187 catch (
const std::exception& e)
194 inline PyObject* unfold2(
const double* observed,
unsigned lenObserved,
195 const Matrix<double>& observationCovMat,
196 Matrix<double>* covMatOut)
199 const int typenum = NumpyTypecode<double>::code;
200 npy_intp sh = responseMatrix_.nColumns();
201 PyObject* array = PyArray_SimpleNew(1, &sh, typenum);
202 double* result = (
double*)PyArray_DATA((PyArrayObject*)array);
205 const bool status = this->
unfold(observed, lenObserved,
207 result, sh, covMatOut);
208 if (!status)
throw std::runtime_error(
209 "In npstat::AbsUnfold1D::unfold2: "
210 "expectation-maximization iterations failed to converge");
212 catch (
const std::exception& e)
219 inline PyObject* unfoldNoCov(
const double* observed,
unsigned lenObserved)
221 const int typenum = NumpyTypecode<double>::code;
222 npy_intp sh = responseMatrix_.nColumns();
223 PyObject* array = PyArray_SimpleNew(1, &sh, typenum);
224 double* result = (
double*)PyArray_DATA((PyArrayObject*)array);
227 const bool status = this->
unfold(observed, lenObserved, 0,
229 if (!status)
throw std::runtime_error(
230 "In npstat::AbsUnfold1D::unfoldNoCov: "
231 "expectation-maximization iterations failed to converge");
233 catch (
const std::exception& e)
240 inline PyObject* unfoldNoCov(
const double* observed,
unsigned lenObserved,
241 const Matrix<double>& observationCovMat)
243 const int typenum = NumpyTypecode<double>::code;
244 npy_intp sh = responseMatrix_.nColumns();
245 PyObject* array = PyArray_SimpleNew(1, &sh, typenum);
246 double* result = (
double*)PyArray_DATA((PyArrayObject*)array);
249 const bool status = this->
unfold(observed, lenObserved,
252 if (!status)
throw std::runtime_error(
253 "In npstat::AbsUnfold1D::unfoldNoCov: "
254 "expectation-maximization iterations failed to converge");
256 catch (
const std::exception& e)
263 inline PyObject* fold(
const double* unfolded,
unsigned lenUnfolded)
const
265 if (lenUnfolded != responseMatrix_.nColumns())
throw std::invalid_argument(
266 "In npstat::AbsUnfold1D::fold: incompatible input array size");
267 const int typenum = NumpyTypecode<double>::code;
268 npy_intp sh = responseMatrix_.
nRows();
269 PyObject* array = PyArray_SimpleNew(1, &sh, typenum);
270 double* result = (
double*)PyArray_DATA((PyArrayObject*)array);
271 responseMatrix_.
timesVector(unfolded, lenUnfolded, result, sh);
Definition: AbsUnfold1D.hh:29
bool usingConvolutions() const
Definition: AbsUnfold1D.hh:92
static Matrix< double > observationCovariance(const double *yhat, unsigned lenObserved, bool isMultinomial)
virtual void useConvolutions(const bool b)
Definition: AbsUnfold1D.hh:89
virtual void setFilter(const LocalPolyFilter1D *f)
virtual void setInitialApproximation(const double *approx, unsigned lenApprox)
virtual bool unfold(const double *observed, unsigned lenObserved, const Matrix< double > *observationCovarianceMatrix, double *unfolded, unsigned lenUnfolded, Matrix< double > *unfoldedCovarianceMatrix)=0
virtual void clearInitialApproximation()
std::pair< double, double > smoothingNDoF() const
virtual const std::vector< double > & getInitialApproximation() const
AbsUnfold1D(const Matrix< double > &responseMatrix)
virtual const LocalPolyFilter1D * getFilter(bool throwIfNull=false) const
static double probDelta(const double *prev, const double *next, const unsigned len)
std::pair< double, double > modelNDoF()
Definition: LocalPolyFilter1D.hh:38
unsigned nRows() const
Definition: Matrix.hh:155
Matrix timesVector(const Num2 *data, unsigned dataLen) const
Definition: AbsArrayProjector.hh:14