25 #ifndef LEAST_SQ_FITTER_1D
26 #define LEAST_SQ_FITTER_1D
63 template <
class FittingFunc>
81 double func1d(
double value,
int exponent);
87 Eigen::JacobiSVD<Eigen::MatrixXd> _svd;
103 template <
class FittingFunc>
106 : _x(
x), _y(
y), _s(s), _order(order) {
112 if (_nData !=
static_cast<int>(_y.
size())) {
115 if (_nData !=
static_cast<int>(_s.
size())) {
119 if (_nData < _order) {
125 Eigen::MatrixXd design(_nData, _order);
126 Eigen::VectorXd rhs(_nData);
127 for (
int i = 0; i < _nData; ++i) {
128 rhs[i] =
y[i] / _s[i];
129 for (
int j = 0; j < _order; ++j) {
130 design(i, j) = func1d(_x[i], j) / _s[i];
133 _svd.compute(design, Eigen::ComputeThinU | Eigen::ComputeThinV);
134 _par = _svd.solve(rhs);
138 template <
class FittingFunc>
140 Eigen::VectorXd vec = Eigen::VectorXd::Zero(_order);
141 for (
int i = 0; i < _order; ++i) {
148 template <
class FittingFunc>
151 for (
int i = 0; i < _order; ++i) {
152 variance[i] = _svd.matrixV().row(i).dot(
153 (_svd.singularValues().array().inverse().square() * _svd.matrixV().col(i).array()).matrix());
159 template <
class FittingFunc>
163 FittingFunc func(_order - 1);
165 for (
int i = 0; i < _order; ++i) {
166 func.setParameter(i, _par(i));
172 template <
class FittingFunc>
174 FittingFunc f = getBestFitFunction();
181 template <
class FittingFunc>
186 FittingFunc f = getBestFitFunction();
188 for (
int i = 0; i < _nData; ++i) {
198 template <
class FittingFunc>
200 FittingFunc f = getBestFitFunction();
203 for (
int i = 0; i < _nData; ++i) {
204 double val = _y[i] - f(_x[i]);
206 chisq += pow(
val, 2);
217 template <
class FittingFunc>
219 return getChiSq() / (double)(_nData - _order);
224 template <
class FittingFunc>
226 _funcArray.reserve(_order);
229 coeff.reserve(_order);
231 coeff.push_back(1.0);
232 for (
int i = 0; i < _order; ++i) {
234 _funcArray.push_back(p);
236 coeff.push_back(1.0);
240 template <
class FittingFunc>
241 double LeastSqFitter1d<FittingFunc>::func1d(
double value,
int exponent) {
242 return (*_funcArray[
exponent])(value);