LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
SimpleFits.h
Go to the documentation of this file.
1 
13 #ifndef SIMPLEFITS_H
14 #define SIMPLEFITS_H 1
15 
16 // C/C++ standard libraries
17 #include <algorithm> // std::for_each()
18 #include <array>
19 #include <cmath> // std::sqrt()
20 #include <iterator> // std::begin(), std::end()
21 #include <ostream> // std::endl
22 #include <stdexcept> // std::range_error
23 #include <tuple>
24 #include <type_traits> // std::enable_if<>, std::is_const<>
25 
26 #include "lardata/Utilities/FastMatrixMathHelper.h" // lar::util::details::FastMatrixOperations
27 #include "lardataalg/Utilities/StatCollector.h" // lar::util::identity
28 
29 namespace lar {
30  namespace util {
31 
32  namespace details {
33 
35  template <typename T, unsigned int D>
37 
55  template <unsigned int Power, unsigned int N>
56  struct SumExtractor {
57  static T Sum(WeightTracker<T> const&, DataTracker<Power, T> const& sums)
58  {
59  return sums.template SumN<N>();
60  }
61  }; // SumExtractor
62 
63  // specialization
64  template <unsigned int Power>
65  struct SumExtractor<Power, 0U> {
67  {
68  return weight.Weights();
69  }
70  }; // SumExtractor<>
71 
72  public:
74  static constexpr unsigned int Degree = D;
75  static constexpr unsigned int NParams = Degree + 1;
76 
77  using Data_t = T;
78 
80  using Measurement_t = std::tuple<Data_t, Data_t>;
81 
83  using MeasurementAndUncertainty_t = std::tuple<Data_t, Data_t, Data_t>;
84 
85  // default constructor, destructor and all the rest
86 
89 
99  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0));
100 
110  {
111  return add(std::get<0>(value), std::get<1>(value), sy);
112  }
113 
122  {
123  return add(std::get<0>(value), std::get<1>(value), std::get<2>(value));
124  }
125 
135  template <typename Iter>
137  {
138  add_without_uncertainty(begin, end, identity());
139  }
140 
154  template <typename Iter, typename Pred>
155  void add_without_uncertainty(Iter begin, Iter end, Pred extractor);
156 
171  template <typename Cont, typename Pred>
172  void add_without_uncertainty(Cont cont, Pred extractor)
173  {
174  add_without_uncertainty(std::begin(cont), std::end(cont), extractor);
175  }
176 
187  template <typename Cont>
188  void add_without_uncertainty(Cont cont)
189  {
191  }
192 
219  template <typename VIter, typename UIter, typename VPred, typename UPred = identity>
220  unsigned int add_with_uncertainty(VIter begin_value,
221  VIter end_value,
222  UIter begin_uncertainty,
223  VPred value_extractor,
224  UPred uncertainty_extractor = UPred());
225 
240  template <typename Iter>
241  unsigned int add_with_uncertainty(Iter begin, Iter end);
242 
254  template <typename Cont>
255  unsigned int add_with_uncertainty(Cont cont)
256  {
257  return add_with_uncertainty(std::begin(cont), std::end(cont));
258  }
259 
261 
263  void clear();
264 
267 
269  int N() const { return s2.N(); }
270 
281 
283  template <typename V>
284  static constexpr V sqr(V const& v)
285  {
286  return v * v;
287  }
288 
290  Data_t XN(unsigned int n) const { return (n == 0) ? s2.Weights() : x.Sum(n); }
291 
293  Data_t XNY(unsigned int n) const { return (n == 0) ? y.Weights() : xy.Sum(n); }
294 
296  template <unsigned int N>
297  Data_t XN() const
298  {
300  }
301 
303  template <unsigned int N>
304  Data_t XNY() const
305  {
307  }
308 
310  Data_t Y2() const { return y2.template SumN<1>(); }
311 
313 
315  template <typename Stream>
316  void Print(Stream& out) const;
317 
319  static Data_t UncertaintyToWeight(Data_t s) { return Data_t(1.) / sqr(s); }
320 
322  static Data_t WeightToUncertainty(Data_t w) { return Data_t(1.) / std::sqrt(w); }
323 
324  protected:
330 
331  }; // class FitDataCollector<>
332 
333  template <typename T, unsigned int D>
334  inline std::ostream& operator<<(std::ostream& out, FitDataCollector<T, D> const& stats)
335  {
336  stats.Print(out);
337  return out;
338  }
339 
341  template <typename T, unsigned int D>
344 
345  public:
347  static constexpr unsigned int Degree = Collector_t::Degree;
348 
349  using Data_t = typename Collector_t::Data_t;
350 
353 
356 
357  // default constructor, destructor and all the rest
358 
362 
363  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0)) { return stats.add(x, y, sy); }
364 
365  bool add(Measurement_t value, Data_t sy = Data_t(1.0)) { return stats.add(value, sy); }
366 
367  bool add(MeasurementAndUncertainty_t value) { return stats.add(value); }
368 
369  template <typename Iter>
371  {
372  stats.add_without_uncertainty(begin, end);
373  }
374 
375  template <typename Iter, typename Pred>
376  void add_without_uncertainty(Iter begin, Iter end, Pred extractor)
377  {
378  stats.add_without_uncertainty(begin, end, extractor);
379  }
380 
381  template <typename Cont, typename Pred>
382  void add_without_uncertainty(Cont cont, Pred extractor)
383  {
384  stats.add_without_uncertainty(cont, extractor);
385  }
386 
387  template <typename Cont>
388  void add_without_uncertainty(Cont cont)
389  {
390  stats.add_without_uncertainty(cont);
391  }
392 
393  template <typename VIter, typename UIter, typename VPred, typename UPred = identity>
394  unsigned int add_with_uncertainty(VIter begin_value,
395  VIter end_value,
396  UIter begin_uncertainty,
397  VPred value_extractor,
398  UPred uncertainty_extractor = UPred())
399  {
400  return stats.add_with_uncertainty(
401  begin_value, end_value, begin_uncertainty, value_extractor, uncertainty_extractor);
402  }
403 
404  template <typename Iter>
405  unsigned int add_with_uncertainty(Iter begin, Iter end)
406  {
407  return stats.add_with_uncertainty(begin, end);
408  }
409 
410  template <typename Cont>
411  unsigned int add_with_uncertainty(Cont cont)
412  {
413  return stats.add_with_uncertainty(cont);
414  }
415 
417 
419  void clear() { stats.clear(); }
420 
424 
425  int N() const { return stats.N(); }
426 
427  Data_t AverageUncertainty() const { return stats.AverageUncertainty(); }
428 
430 
432  template <typename Stream>
433  void PrintStats(Stream& out) const
434  {
435  stats.Print(out);
436  }
437 
439  template <typename V>
440  static constexpr V sqr(V const& v)
441  {
442  return Collector_t::sqr(v);
443  }
444 
445  protected:
447 
449  Data_t XN(unsigned int n) const { return stats.XN(n); }
450 
452  Data_t XNY(unsigned int n) const { return stats.XNY(n); }
453 
454  }; // class SimplePolyFitterDataBase<>
455 
457  template <typename T, unsigned int N>
459  public:
461  static constexpr unsigned int NParams = N;
462 
463  using Data_t = T;
464 
466 
468  using FitParameters_t = std::array<Data_t, NParams>;
469 
472 
474  virtual ~SimpleFitterInterface() = default;
475 
486  virtual bool isValid() const = 0;
487 
490 
496  virtual FitParameters_t FitParameters() const = 0;
497 
503  virtual FitParameters_t FitParameterErrors() const = 0;
504 
513  virtual FitMatrix_t FitParameterCovariance() const = 0;
514 
521  virtual Data_t FitParameter(unsigned int n) const { return FitParameters()[n]; }
522 
529  virtual Data_t FitParameterError(unsigned int n) const
530  {
531  return std::sqrt(FitParameterCovariance()[n * (NParams + 1)]);
532  }
533 
538  virtual Data_t ChiSquare() const = 0;
539 
547  virtual int NDF() const = 0;
548 
550 
559  virtual bool FillResults(FitParameters_t& params,
560  FitMatrix_t& Xmat,
561  Data_t& det,
562  FitMatrix_t& Smat) const = 0;
563 
573  virtual bool FillResults(FitParameters_t& params,
574  FitParameters_t& paramerrors,
575  FitMatrix_t& Xmat,
576  Data_t& det,
577  FitMatrix_t& Smat) const = 0;
578 
585  virtual bool FillResults(FitParameters_t& params, FitParameters_t& paramerrors) const = 0;
586 
594  virtual Data_t Evaluate(Data_t x) const = 0;
595 
597  Data_t operator()(Data_t x) const { return Evaluate(x); }
598 
600  static constexpr Data_t sqr(Data_t v) { return v * v; }
601 
603  static constexpr Data_t cube(Data_t v) { return v * v * v; }
604 
605  protected:
607  virtual Data_t Determinant(FitMatrix_t const& mat) const
608  {
609  return MatrixOps::Determinant(mat);
610  }
611 
613  virtual FitMatrix_t InvertMatrix(FitMatrix_t const& mat, Data_t det) const
614  {
615  return MatrixOps::InvertSymmetricMatrix(mat, det);
616  }
617 
619  virtual FitMatrix_t InvertMatrix(FitMatrix_t const& mat) const
620  {
621  return MatrixOps::InvertSymmetricMatrix(mat);
622  }
623 
626  FitParameters_t const& vec) const
627  {
628  return MatrixOps::MatrixVectorProduct(mat, vec);
629  }
630 
631  }; // class SimpleFitterInterface<>
632 
634  template <typename T, unsigned int D>
635  class SimplePolyFitterBase : public SimpleFitterInterface<T, D + 1>,
636  public SimplePolyFitterDataBase<T, D> {
639 
640  public:
641  using Base_t::sqr;
642 
644  static constexpr unsigned int Degree = Base_t::Degree;
645 
647  static constexpr unsigned int NParams = Interface_t::NParams;
648 
649  using Data_t = typename Base_t::Data_t;
650 
653 
656 
667  virtual bool isValid() const override;
668 
671 
677  virtual FitParameters_t FitParameters() const override;
678 
684  virtual FitParameters_t FitParameterErrors() const override;
685 
694  virtual FitMatrix_t FitParameterCovariance() const override;
695 
702  virtual Data_t FitParameter(unsigned int n) const override;
703 
710  virtual Data_t FitParameterError(unsigned int n) const override;
711 
716  virtual Data_t ChiSquare() const override;
717 
725  virtual int NDF() const override { return Base_t::N() - NParams; }
726 
728 
737  bool FillResults(FitParameters_t& params,
738  FitMatrix_t& Xmat,
739  Data_t& det,
740  FitMatrix_t& Smat) const override;
741 
751  bool FillResults(FitParameters_t& params,
752  FitParameters_t& paramerrors,
753  FitMatrix_t& Xmat,
754  Data_t& det,
755  FitMatrix_t& Smat) const override;
756 
763  bool FillResults(FitParameters_t& params, FitParameters_t& paramerrors) const override;
764 
772  virtual Data_t Evaluate(Data_t x) const override;
773 
775  static FitParameters_t ExtractParameterErrors(FitMatrix_t const& Smat);
776 
777  protected:
779  virtual FitMatrix_t MakeMatrixX() const;
780 
782  virtual FitParameters_t MakeMatrixY() const;
783 
785  virtual FitParameters_t FitParameterErrors(FitMatrix_t const& Smat) const
786  {
787  return ExtractParameterErrors(Smat);
788  }
789 
791  virtual FitParameters_t FitParameters(FitMatrix_t const& Xmat) const;
793 
794  virtual FitParameters_t FitParameters(FitMatrix_t const& Smat, Data_t /* det */) const;
796 
798  virtual Data_t Param(unsigned int n, FitMatrix_t const& Xmat) const;
800  virtual Data_t Param(unsigned int n, FitMatrix_t const& Xmat, Data_t detXmat) const;
802 
803  // import the declaration from the interface
804  using Interface_t::Determinant;
805  using Interface_t::InvertMatrix;
806  using Interface_t::MatrixProduct;
807 
808  }; // class SimplePolyFitterBase<>
809 
810  } // namespace details
811 
832  template <typename T>
833  class LinearFit : public details::SimplePolyFitterBase<T, 1U> {
835 
836  public:
837  using Base_t::Degree;
838  using Base_t::NParams;
839  using typename Base_t::Data_t;
840 
842  using typename Base_t::Measurement_t;
843 
846 
847  using Base_t::sqr;
848 
850  using FitParameters_t = std::array<Data_t, NParams>;
851  using FitMatrix_t = std::array<Data_t, sqr(NParams)>;
852 
853  // default constructor, destructor and all the rest
854 
860  Data_t Intercept() const { return this->FitParameter(0); }
861 
867  Data_t Slope() const { return this->FitParameter(1); }
868 
874  Data_t InterceptError() const { return this->FitParameterError(0); }
875 
881  Data_t SlopeError() const { return this->FitParameterError(1); }
882 
889  {
890  return this->FitParameterCovariance()[0 * NParams + 1];
891  }
892 
897  virtual Data_t ChiSquare() const override;
898 
899  protected:
901  Data_t I() const { return Base_t::stats.template XN<0>(); }
903  Data_t X() const { return Base_t::stats.template XN<1>(); }
904  Data_t X2() const { return Base_t::stats.template XN<2>(); }
905  Data_t Y() const { return Base_t::stats.template XNY<0>(); }
906  Data_t XY() const { return Base_t::stats.template XNY<1>(); }
907  Data_t Y2() const { return Base_t::stats.Y2(); }
909 
910  }; // class LinearFit<>
911 
932  template <typename T>
935 
936  public:
937  using Base_t::Degree;
938  using Base_t::NParams;
939  using typename Base_t::Data_t;
940 
942  using typename Base_t::Measurement_t;
943 
946 
947  using Base_t::sqr;
948 
950  using FitParameters_t = std::array<Data_t, NParams>;
951  using FitMatrix_t = std::array<Data_t, sqr(NParams)>;
952 
953  // default constructor, destructor and all the rest
954 
959  virtual Data_t ChiSquare() const override;
960 
961  protected:
963  Data_t I() const { return Base_t::stats.template XN<0>(); }
965  Data_t X() const { return Base_t::stats.template XN<1>(); }
966  Data_t X2() const { return Base_t::stats.template XN<2>(); }
967  Data_t X3() const { return Base_t::stats.template XN<3>(); }
968  Data_t X4() const { return Base_t::stats.template XN<4>(); }
969  Data_t Y() const { return Base_t::stats.template XNY<0>(); }
970  Data_t XY() const { return Base_t::stats.template XNY<1>(); }
971  Data_t X2Y() const { return Base_t::stats.template XNY<2>(); }
972  Data_t Y2() const { return Base_t::stats.Y2(); }
974 
975  }; // class QuadraticFit<>
976 
992  template <typename T>
996 
997  public:
999  static constexpr unsigned int NParams = Base_t::NParams;
1000 
1001  using Data_t = typename Base_t::Data_t;
1002 
1005 
1008 
1011 
1012  using Base_t::cube;
1013  using Base_t::sqr;
1014 
1015  // default constructor, destructor and all the rest
1016 
1020 
1021  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0));
1022 
1024  {
1025  return add(std::get<0>(value), std::get<1>(value), sy);
1026  }
1027 
1029  {
1030  return add(std::get<0>(value), std::get<1>(value), std::get<2>(value));
1031  }
1032 
1033  template <typename Iter>
1035  {
1036  add_without_uncertainty(begin, end, identity());
1037  }
1038 
1039  template <typename Iter, typename Pred>
1040  void add_without_uncertainty(Iter begin, Iter end, Pred extractor);
1041 
1042  template <typename Cont, typename Pred>
1043  void add_without_uncertainty(Cont cont, Pred extractor)
1044  {
1045  add_without_uncertainty(std::begin(cont), std::end(cont), extractor);
1046  }
1047 
1048  template <typename Cont>
1049  void add_without_uncertainty(Cont cont)
1050  {
1052  }
1053 
1054  template <typename VIter, typename UIter, typename VPred, typename UPred = identity>
1055  unsigned int add_with_uncertainty(VIter begin_value,
1056  VIter end_value,
1057  UIter begin_uncertainty,
1058  VPred value_extractor,
1059  UPred uncertainty_extractor = UPred());
1060 
1061  template <typename Iter>
1062  unsigned int add_with_uncertainty(Iter begin, Iter end);
1063 
1064  template <typename Cont>
1065  unsigned int add_with_uncertainty(Cont cont)
1066  {
1067  return add_with_uncertainty(std::begin(cont), std::end(cont));
1068  }
1069 
1071  void clear() { fitter.clear(); }
1072 
1074  int N() const { return fitter.N(); }
1075 
1077  template <typename Stream>
1078  void PrintStats(Stream& out) const
1079  {
1080  fitter.PrintStats(out);
1081  }
1082 
1084 
1087 
1097  virtual bool isValid() const override { return fitter.isValid(); }
1098 
1101 
1107  virtual FitParameters_t FitParameters() const override;
1108 
1114  virtual FitParameters_t FitParameterErrors() const override;
1115 
1125  virtual FitMatrix_t FitParameterCovariance() const override;
1126 
1135  virtual Data_t ChiSquare() const override { return fitter.ChiSquare(); }
1136 
1144  virtual int NDF() const override { return fitter.NDF(); }
1145 
1147 
1159  virtual bool FillResults(FitParameters_t& params,
1160  FitMatrix_t& Xmat,
1161  Data_t& det,
1162  FitMatrix_t& Smat) const override;
1174  virtual bool FillResults(FitParameters_t& params,
1175  FitParameters_t& paramerrors,
1176  FitMatrix_t& Xmat,
1177  Data_t& det,
1178  FitMatrix_t& Smat) const override;
1179 
1188  virtual bool FillResults(FitParameters_t& params,
1189  FitParameters_t& paramerrors) const override;
1190 
1198  virtual Data_t Evaluate(Data_t x) const override
1199  {
1200  return Evaluate(x, FitParameters().data());
1201  }
1202 
1204  virtual Fitter_t const& Fitter() const { return fitter; }
1205 
1212  static Data_t Evaluate(Data_t x, Data_t const* params);
1213 
1214  protected:
1216 
1219 
1221  struct Value_t : public std::tuple<Data_t, Data_t> {
1222  using Base_t = std::tuple<Data_t, Data_t>;
1223 
1224  Value_t(Data_t v, Data_t e) : Base_t(v, e) {}
1225  Value_t(MeasurementAndUncertainty_t meas) : Base_t(std::get<1>(meas), std::get<2>(meas)) {}
1226 
1227  constexpr Data_t value() const { return std::get<0>(*this); }
1228  constexpr Data_t error() const { return std::get<1>(*this); }
1229 
1230  Data_t& value() { return std::get<0>(*this); }
1231  Data_t& error() { return std::get<1>(*this); }
1232 
1233  }; // Value_t
1234 
1237  static Data_t EncodeValue(Data_t value) { return std::log(value); }
1238 
1240  static Data_t DecodeValue(Data_t value) { return std::exp(value); }
1241 
1244  {
1245  return {std::log(value), error / std::abs(value)};
1246  }
1247 
1249  static Value_t EncodeValue(Value_t const& value)
1250  {
1251  return EncodeValue(value.value(), value.error());
1252  }
1253 
1255  static Value_t DecodeValue(Value_t const& value)
1256  {
1257  const Data_t v = std::exp(value.value());
1258  return {v, v * value.error()};
1259  } // DecodeValue()
1260 
1263  {
1264  return Measurement_t(std::get<0>(meas), EncodeValue(std::get<1>(meas)));
1265  }
1266 
1269  {
1270  Value_t value = EncodeValue(Value_t(meas));
1271  return {std::get<0>(meas), value.value(), value.error()};
1272  } // EncodeValue(MeasurementAndUncertainty_t)
1273 
1276  {
1277  Value_t value = EncodeValue(Value_t(std::get<1>(meas), error));
1278  return {std::get<0>(meas), value.value(), value.error()};
1279  } // EncodeValue(Measurement_t, Data_t)
1280 
1283  template <typename VPred, typename UPred = void>
1285  EncodeExtractor(VPred& vpred, UPred& upred) : value_extractor(vpred), error_extractor(upred)
1286  {}
1287 
1288  // extractor takes whatever dereferencing Iter gives and returns
1289  // Measurement_t or MeasurementAndUncertainty_t,
1290  // the one the extractor returns
1291  template <typename Elem>
1292  auto operator()(Elem elem)
1293  {
1294  // use explicit casts to make sure we know what we are doing
1295  return EncodeValue(static_cast<Measurement_t&&>(value_extractor(elem)),
1296  static_cast<Data_t&&>(error_extractor(elem)));
1297  } // operator()
1298 
1301  }; // struct EncodeExtractor
1302 
1305  template <typename Pred>
1306  struct EncodeExtractor<Pred, void> {
1307  EncodeExtractor(Pred& pred) : extractor(pred) {}
1308 
1309  // extractor takes whatever dereferencing Iter gives and returns
1310  // Measurement_t or MeasurementAndUncertainty_t,
1311  // the one the extractor returns;
1312  // as usual with enable_if, I am not sure it makes sense
1314  auto operator()(Elem elem) const
1315  {
1316  return EncodeValue(extractor(elem));
1317  }
1318 
1320  auto operator()(Elem elem)
1321  {
1322  return EncodeValue(extractor(elem));
1323  }
1324 
1325  Pred& extractor;
1326  }; // struct EncodeExtractor<Pred>
1327 
1328  template <typename Pred>
1329  static EncodeExtractor<Pred> Encoder(Pred& pred)
1330  {
1331  return {pred};
1332  }
1333 
1334  template <typename VPred, typename UPred>
1335  static EncodeExtractor<VPred, UPred> Encoder(VPred& vpred, UPred& upred)
1336  {
1337  return {vpred, upred};
1338  }
1339 
1341 
1347  static FitParameters_t ConvertParameters(FitParameters_t const& qpars);
1348 
1356  static void ConvertParametersAndErrors(FitParameters_t const& qpars,
1357  FitMatrix_t const& qparerrmat,
1358  FitParameters_t& params,
1359  FitParameters_t& paramerrors);
1360 
1368  static void ConvertParametersAndVariances(FitParameters_t const& qpars,
1369  FitMatrix_t const& qparerrmat,
1370  FitParameters_t& params,
1371  FitParameters_t& paramvariances);
1372 
1380  static void ConvertParametersAndErrorMatrix(FitParameters_t const& qpars,
1381  FitMatrix_t const& qparerrmat,
1382  FitParameters_t& params,
1383  FitMatrix_t& Smat);
1384 
1391  static bool isValid(FitParameters_t const& params, FitParameters_t const& qpars);
1392 
1393  static void ThrowNotImplemented [[noreturn]] (std::string method)
1394  {
1395  throw std::logic_error("Method " + method + "() not implemented");
1396  }
1397 
1398  }; // class GaussianFit<>
1399 
1400  } // namespace util
1401 } // namespace lar
1402 
1403 //==============================================================================
1404 //=== template implementation
1405 //==============================================================================
1406 
1407 //******************************************************************************
1408 //*** FitDataCollector<>
1409 //***
1410 
1411 template <typename T, unsigned int D>
1413  Data_t y_value,
1414  Data_t sy /* = Data_t(1.0) */)
1415 {
1417  if (!std::isnormal(w)) return false;
1418  // the x section has a 1/s^2 weight; we track that weight separately
1419  s2.add(w);
1420  x.add(x_value, w);
1421  // we treat the y section as if it were a x section with a y/s^2 weight;
1422  // we track that weight separately
1423  Data_t yw = y_value * w;
1424  y.add(yw);
1425  y2.add(sqr(y_value), w); // used only for chi^2
1426  xy.add(x_value, yw);
1427 
1428  return true; // we did add the value
1429 } // FitDataCollector<>::add()
1430 
1431 template <typename T, unsigned int D>
1432 template <typename Iter, typename Pred>
1434  Iter end,
1435  Pred extractor)
1436 {
1437  std::for_each(begin, end, [this, extractor](auto item) { this->add(extractor(item)); });
1438 } // FitDataCollector<>::add_without_uncertainty(Iter, Pred)
1439 
1440 template <typename T, unsigned int D>
1441 template <typename VIter, typename UIter, typename VPred, typename UPred>
1443  VIter begin_value,
1444  VIter end_value,
1445  UIter begin_uncertainty,
1446  VPred value_extractor,
1447  UPred uncertainty_extractor /* = UPred() */
1448 )
1449 {
1450  unsigned int n = 0;
1451  while (begin_value != end_value) {
1452  if (add(value_extractor(*begin_value), uncertainty_extractor(*begin_uncertainty))) ++n;
1453  ++begin_value;
1454  ++begin_uncertainty;
1455  } // while
1456  return n;
1457 } // FitDataCollector<>::add_with_uncertainty(VIter, VIter, UIter, VPred, UPred)
1458 
1459 template <typename T, unsigned int D>
1460 template <typename Iter>
1462 {
1463  unsigned int old_n = N();
1464  std::for_each(begin, end, [this](auto p) { this->add(p); });
1465  return N() - old_n;
1466 } // FitDataCollector<>::add_with_uncertainty(Iter, Iter)
1467 
1468 template <typename T, unsigned int D>
1470 {
1471  s2.clear();
1472  x.clear();
1473  y.clear();
1474  y2.clear();
1475  xy.clear();
1476 } // FitDataCollector<>::clear()
1477 
1478 template <typename T, unsigned int D>
1479 template <typename Stream>
1481 {
1482 
1483  out << "Sums 1/s^2=" << s2.Weights() << "\n x/s^2=" << x.template SumN<1>();
1484  for (unsigned int degree = 2; degree <= x.Power; ++degree)
1485  out << "\n x^" << degree << "/s^2=" << x.Sum(degree);
1486  out << "\n y/s^2=" << y.Weights() << "\n y^2/s^2=" << y2.Sum();
1487  if (xy.Power >= 1) out << "\n xy/s^2=" << xy.template SumN<1>();
1488  for (unsigned int degree = 2; degree <= xy.Power; ++degree)
1489  out << "\n x^" << degree << "y/s^2=" << xy.Sum(degree);
1490  out << std::endl;
1491 } // FitDataCollector<>::Print()
1492 
1493 //******************************************************************************
1494 //*** SimplePolyFitterBase<>
1495 //***
1496 template <typename T, unsigned int D>
1498 {
1499  return (Base_t::N() > (int)Degree) && std::isnormal(Determinant(MakeMatrixX()));
1500 } // SimplePolyFitterBase<>::isValid()
1501 
1502 template <typename T, unsigned int D>
1504  -> Data_t
1505 {
1506  return Param(n, MakeMatrixX());
1507 } // SimplePolyFitterBase<>::FitParameter(unsigned int)
1508 
1509 template <typename T, unsigned int D>
1511  -> Data_t
1512 {
1513  if (n > Degree) return Data_t(0); // no parameter, no error
1514  return std::sqrt(FitParameterCovariance()[n * (NParams + 1)]);
1515 } // SimplePolyFitterBase<>::FitParameterError()
1516 
1517 template <typename T, unsigned int D>
1519 {
1520  FitMatrix_t Xmat = MakeMatrixX();
1521  FitParameters_t fit_params;
1522  for (unsigned int iParam = 0; iParam < NParams; ++iParam)
1523  fit_params[iParam] = Param(iParam, Xmat);
1524  return fit_params;
1525 } // SimplePolyFitterBase<>::FitParameters()
1526 
1527 template <typename T, unsigned int D>
1529 {
1530  return FitParameterErrors(FitParameterCovariance());
1531 } // SimplePolyFitterBase<>::FitParameterErrors()
1532 
1533 template <typename T, unsigned int D>
1535 {
1536  FitMatrix_t Xmat = MakeMatrixX();
1537  Data_t det = Determinant(Xmat);
1538  if (!std::isnormal(det)) {
1539  throw std::range_error(
1540  "SimplePolyFitterBase::FitParameterCovariance(): determinant 0 while fitting");
1541  }
1542  return InvertMatrix(Xmat, det);
1543 } // SimplePolyFitterBase<>::FitParameterCovariance()
1544 
1545 template <typename T, unsigned int D>
1547  FitMatrix_t& Xmat,
1548  Data_t& det,
1549  FitMatrix_t& Smat) const
1550 {
1551 
1552  Xmat = MakeMatrixX();
1553  det = Determinant(Xmat);
1554  if (!std::isnormal(det)) {
1555  Smat.fill(Data_t(0));
1556  params.fill(Data_t(0));
1557  return false;
1558  }
1559  Smat = InvertMatrix(Xmat, det);
1560  params = FitParameters(Smat, det);
1561  return true;
1562 } // SimplePolyFitterBase<>::FillResults(params, matrices, determinant)
1563 
1564 template <typename T, unsigned int D>
1566  FitParameters_t& paramerrors,
1567  FitMatrix_t& Xmat,
1568  Data_t& det,
1569  FitMatrix_t& Smat) const
1570 {
1571 
1572  if (!this->FillResults(params, Xmat, det, Smat)) return false;
1573  paramerrors = ExtractParameterErrors(Smat);
1574  return true;
1575 } // SimplePolyFitterBase<>::FillResults(params, errors, matrices, determinant)
1576 
1577 template <typename T, unsigned int D>
1579  FitParameters_t& paramerrors) const
1580 {
1581  // to compute the parameters, we need all the stuff;
1582  // we just keep it local and discard it in the end. Such a waste.
1583  FitMatrix_t Xmat, Smat;
1584  Data_t det;
1585  return FillResults(params, paramerrors, Xmat, det, Smat);
1586 } // SimplePolyFitterBase<>::FillResults(params, errors)
1587 
1588 template <typename T, unsigned int D>
1590 {
1591  FitParameters_t params = FitParameters();
1592  unsigned int iParam = NParams - 1; // point to last parameter (highest degree)
1593  Data_t v = params[iParam];
1594  while (iParam > 0)
1595  v = v * x + params[--iParam];
1596  return v;
1597 } // SimplePolyFitterBase<>::Evaluate()
1598 
1599 // --- protected methods follow ---
1600 template <typename T, unsigned int D>
1602 {
1603  FitMatrix_t Xmat;
1604  for (unsigned int i = 0; i < NParams; ++i) { // row
1605  for (unsigned int j = i; j < NParams; ++j) { // column
1606  Xmat[j * NParams + i] = Xmat[i * NParams + j] = Base_t::XN(i + j);
1607  } // for j
1608  } // for i
1609  return Xmat;
1610 } // SimplePolyFitterBase<>::MakeMatrixX()
1611 
1612 template <typename T, unsigned int D>
1614 {
1615  FitParameters_t Ymat;
1616  for (unsigned int i = 0; i < NParams; ++i)
1617  Ymat[i] = Base_t::XNY(i);
1618  return Ymat;
1619 } // SimplePolyFitterBase<>::MakeMatrixY()
1620 
1621 template <typename T, unsigned int D>
1623  -> FitParameters_t
1624 {
1625  FitParameters_t fit_params;
1626  for (unsigned int iParam = 0; iParam < NParams; ++iParam)
1627  fit_params[iParam] = Param(iParam, Xmat);
1628  return fit_params;
1629 } // SimplePolyFitterBase<>::FitParameters(FitMatrix_t)
1630 
1631 template <typename T, unsigned int D>
1633  Data_t /* det */) const
1634  -> FitParameters_t
1635 {
1636  return MatrixProduct(Smat, MakeMatrixY());
1637 } // SimplePolyFitterBase<>::FitParameters(FitMatrix_t)
1638 
1639 template <typename T, unsigned int D>
1641  FitMatrix_t const& Xmat) const -> Data_t
1642 {
1643  if (n > Degree) return Data_t(0); // no such a degree, its coefficient is 0
1644 
1645  Data_t detXmat = Determinant(Xmat);
1646  if (!std::isnormal(detXmat)) {
1647  throw std::range_error("SimplePolyFitterBase::Param(): Determinant 0 while fitting");
1648  }
1649  return Param(n, Xmat, detXmat);
1650 } // SimplePolyFitterBase<>::Param(unsigned int, FitMatrix_t)
1651 
1652 template <typename T, unsigned int D>
1654  -> FitParameters_t
1655 {
1656  FitParameters_t fit_errors;
1657  for (unsigned int iParam = 0; iParam <= Degree; ++iParam)
1658  fit_errors[iParam] = std::sqrt(Smat[iParam * (NParams + 1)]);
1659  return fit_errors;
1660 } // SimplePolyFitterBase<>::FitParameterErrors(FitMatrix_t)
1661 
1662 template <typename T, unsigned int D>
1664  FitMatrix_t const& Xmat,
1665  Data_t detXmat) const -> Data_t
1666 {
1667  if (n > Degree) return Data_t(0); // no such a degree, its coefficient is 0
1668  // XYmat is as Xmat...
1669  FitMatrix_t XYmat(Xmat);
1670  // ... except that the N-th column is replaced with { sum x^i y }
1671  for (unsigned int i = 0; i < NParams; ++i)
1672  XYmat[i * NParams + n] = Base_t::XNY(i);
1673 
1674  return Determinant(XYmat) / detXmat;
1675 } // SimplePolyFitterBase<>::Param(unsigned int, FitMatrix_t, Data_t)
1676 
1677 template <typename T, unsigned int D>
1679 {
1680  // the generic implementation of ChiSquare from sums is complex enough that
1681  // I freaked out
1682  throw std::logic_error("SimplePolyFitterBase::ChiSquare() not implemented for generic fit");
1683 } // SimplePolyFitterBase<>::ChiSquare()
1684 
1685 //******************************************************************************
1686 //*** LinearFit<>
1687 //***
1688 
1689 template <typename T>
1691 {
1692  FitParameters_t fit_params = this->FitParameters();
1693  const Data_t b = fit_params[0];
1694  const Data_t a = fit_params[1];
1695  return Y2() + sqr(a) * X2() + sqr(b) * I() + Data_t(2) * (a * b * X2() - a * XY() - b * Y());
1696 } // LinearFit<T>::ChiSquare()
1697 
1698 //******************************************************************************
1699 //*** QuadraticFit<>
1700 //***
1701 
1702 template <typename T>
1704 {
1705  FitParameters_t a = this->FitParameters();
1706  return Y2() - Data_t(2) * (a[0] * Y() + a[1] * XY() + a[2] * X2Y()) + sqr(a[0]) * I() +
1707  Data_t(2) * a[0] * (a[1] * X() + a[2] * X2()) + sqr(a[1]) * X2() +
1708  Data_t(2) * a[1] * (a[2] * X3()) + sqr(a[2]) * X4();
1709 } // QuadraticFit<T>::ChiSquare()
1710 
1711 //******************************************************************************
1712 //*** GaussianFit<>
1713 //***
1714 
1715 //
1716 // data interface
1717 //
1718 template <typename T>
1719 bool lar::util::GaussianFit<T>::add(Data_t x, Data_t y, Data_t sy /* = Data_t(1.0) */)
1720 {
1721  if (y <= Data_t(0)) return false; // ignore the non-positive values
1722  Value_t value = EncodeValue(Value_t(y, sy));
1723  return fitter.add(x, value.value(), value.error());
1724 } // GaussianFit<T>::add(Data_t, Data_t, Data_t)
1725 
1726 template <typename T>
1727 template <typename Iter, typename Pred>
1729 {
1730  return fitter.add_without_uncertainty(begin, end, Encoder(extractor));
1731 } // GaussianFit<>::add_without_uncertainty(Iter, Iter, Pred)
1732 
1733 template <typename T>
1734 template <typename VIter, typename UIter, typename VPred, typename UPred>
1736  VIter begin_value,
1737  VIter end_value,
1738  UIter begin_uncertainty,
1739  VPred value_extractor,
1740  UPred uncertainty_extractor /* = UPred() */
1741 )
1742 {
1743  return add_with_uncertainty(
1744  begin_value, end_value, begin_uncertainty, Encoder(value_extractor, uncertainty_extractor));
1745 } // GaussianFit<T>::add_with_uncertainty()
1746 
1747 template <typename T>
1748 template <typename Iter>
1750 {
1751  unsigned int old_n = N();
1752  std::for_each(begin, end, [this](auto p) { this->add(p); });
1753  return N() - old_n;
1754 } // GaussianFit<T>::add_with_uncertainty()
1755 
1756 //
1757 // fitting interface
1758 //
1759 template <typename T>
1761 {
1762  return ConvertParameters(fitter.FitParameters());
1763 } // GaussianFit<>::FitParameters()
1764 
1765 template <typename T>
1767 {
1768  FitParameters_t qpars, qparerrors;
1769  if (!FillResults(qpars, qparerrors)) {
1770  throw std::runtime_error("GaussianFit::FitParameterErrors() yielded invalid results");
1771  }
1772  return qparerrors;
1773 } // GaussianFit<>::FitParameterErrors()
1774 
1775 template <typename T>
1777 {
1778  // we need to go through the whole chain to get the error matrix
1779  FitParameters_t params;
1780  FitMatrix_t Xmat;
1781  Data_t det;
1782  FitMatrix_t Smat;
1783  if (!FillResults(params, Xmat, det, Smat)) {
1784  throw std::runtime_error("GaussianFit::FitParameterCovariance() yielded invalid results");
1785  }
1786  return Smat;
1787 } // SimplePolyFitterBase<>::FitParameterCovariance()
1788 
1789 template <typename T>
1791  FitParameters_t& paramerrors) const
1792 {
1793  FitParameters_t qpars;
1794  FitMatrix_t qparerrmat;
1795  FitMatrix_t Xmat; // not used
1796  Data_t det; // not used
1797  if (!fitter.FillResults(qpars, Xmat, det, qparerrmat)) return false;
1798  ConvertParametersAndErrors(qpars, qparerrmat, params, paramerrors);
1799  return isValid(params, qpars);
1800 } // GaussianFit<>::FillResults()
1801 
1802 template <typename T>
1804  FitMatrix_t& Xmat,
1805  Data_t& det,
1806  FitMatrix_t& Smat) const
1807 {
1808  FitParameters_t qpars;
1809  FitMatrix_t qparerrmat;
1810  if (!fitter.FillResults(qpars, Xmat, det, qparerrmat)) return false;
1811  ConvertParametersAndErrorMatrix(qpars, qparerrmat, params, Smat);
1812  return isValid(params, qpars);
1813 } // GaussianFit::FillResults()
1814 
1815 template <typename T>
1817  FitParameters_t& paramerrors,
1818  FitMatrix_t& Xmat,
1819  Data_t& det,
1820  FitMatrix_t& Smat) const
1821 {
1822  if (!FillResults(params, Xmat, det, Smat)) return false;
1823  paramerrors = fitter.ExtractParameterErrors(Smat);
1824  return true;
1825 } // GaussianFit::FillResults()
1826 
1827 template <typename T>
1829 {
1830  Data_t z = (x - params[1]) / params[2];
1831  return params[0] * std::exp(-0.5 * sqr(z));
1832 } // GaussianFit<>::Evaluate()
1833 
1834 template <typename T>
1836 {
1837  FitParameters_t params;
1838 
1839  Data_t sigma2 = -0.5 / qpars[2]; // sigma^2 = -1 / (2 a2)
1840  params[2] = std::sqrt(sigma2); // sigma
1841 
1842  params[1] = sigma2 * qpars[1]; // mean = sigma2 a1
1843 
1844  params[0] = std::exp(qpars[0] - 0.25 * sqr(qpars[1]) / qpars[2]);
1845 
1846  return params;
1847 } // GaussianFit<>::ConvertParameters()
1848 
1849 template <typename T>
1851  FitMatrix_t const& qparerrmat,
1852  FitParameters_t& params,
1853  FitParameters_t& paramvariances)
1854 {
1855  params = ConvertParameters(qpars);
1856 
1857  FitParameters_t const& a = qpars;
1858  Data_t const& A = params[0];
1859  Data_t const& mu = params[1];
1860  Data_t const& sigma = params[2];
1861 
1862  // error on sigma
1863  paramvariances[2] = qparerrmat[3 * 2 + 2] / sqr(cube(sigma));
1864 
1865  // error on mu
1866  paramvariances[1] =
1867  sqr(mu * (+qparerrmat[3 * 1 + 1] / sqr(a[1]) - 2. * qparerrmat[3 * 2 + 1] / (a[1] * a[2]) +
1868  qparerrmat[3 * 2 + 2] / sqr(a[2])));
1869 
1870  // error on A
1871  paramvariances[0] =
1872  sqr(A * (+qparerrmat[3 * 0 + 0] + 2. * qparerrmat[3 * 0 + 1] * mu +
1873  (qparerrmat[3 * 1 + 1] + 2. * qparerrmat[3 * 0 + 2]) * sqr(mu) +
1874  2. * qparerrmat[3 * 1 + 2] * cube(mu) + qparerrmat[3 * 2 + 2] * sqr(sqr(mu))));
1875 
1876 } // GaussianFit<>::ConvertParametersAndVariances()
1877 
1878 template <typename T>
1880  FitMatrix_t const& qparerrmat,
1881  FitParameters_t& params,
1882  FitParameters_t& paramerrors)
1883 {
1884  ConvertParametersAndVariances(qpars, qparerrmat, params, paramerrors);
1885  // paramerrors actually stores the square of the error; fix it:
1886  for (Data_t& paramerror : paramerrors)
1887  paramerror = std::sqrt(paramerror);
1888 } // GaussianFit<>::ConvertParametersAndErrors()
1889 
1890 template <typename T>
1892  FitMatrix_t const& qparerrmat,
1893  FitParameters_t& params,
1894  FitMatrix_t& Smat)
1895 {
1896  FitParameters_t paramvariances;
1897  ConvertParametersAndVariances(qpars, qparerrmat, params, paramvariances);
1898 
1899  // let's call things with their names
1900  FitParameters_t const& a = qpars;
1901  Data_t const& A = params[0];
1902  Data_t const& mu = params[1];
1903  Data_t const& sigma = params[2];
1904 
1905  // variance on sigma
1906  Smat[3 * 2 + 2] = paramvariances[2];
1907 
1908  // variance on mu
1909  Smat[3 * 1 + 1] = paramvariances[1];
1910 
1911  // variance on A
1912  Smat[3 * 0 + 0] = paramvariances[0];
1913 
1914  // covariance on sigma and mu
1915  Smat[3 * 1 + 2] = Smat[3 * 2 + 1] =
1916  (qparerrmat[3 * 1 + 2] + 2 * mu * qparerrmat[3 * 2 + 2]) / sigma;
1917 
1918  // this is the sum of the derivatives of A vs. all a parameters, each one
1919  // multiplied by the covariance of that parameter with a2
1920  const Data_t dA_dak_cov_aka2 =
1921  A * (qparerrmat[3 * 0 + 2] + qparerrmat[3 * 1 + 2] * mu + qparerrmat[3 * 2 + 2] * sqr(mu));
1922  // covariance on A and sigma
1923  Smat[3 * 0 + 2] = Smat[3 * 2 + 0] = dA_dak_cov_aka2 / cube(sigma);
1924 
1925  // this other is the same as dA_dak_cov_aka2, but for a1
1926  const Data_t dA_dak_cov_aka1 =
1927  A * (qparerrmat[3 * 0 + 1] + qparerrmat[3 * 1 + 1] * mu + qparerrmat[3 * 2 + 1] * sqr(mu));
1928 
1929  // covariance on A and mu
1930  Smat[3 * 0 + 1] = Smat[3 * 1 + 0] = mu * (dA_dak_cov_aka1 / a[1] - dA_dak_cov_aka2 / a[2]);
1931 
1932 } // GaussianFit<>::ConvertParametersAndErrors()
1933 
1934 template <typename T>
1936 {
1937  return (qpars[2] < Data_t(0)) && (params[0] >= Data_t(0));
1938 } // GaussianFit<>::isValid(FitParameters_t)
1939 
1940 //******************************************************************************
1941 
1942 #endif // SIMPLEFITS_H
static constexpr Data_t cube(Data_t v)
Returns the cube of the specified data value.
Definition: SimpleFits.h:603
Weight_t Weights() const
Returns the sum of the weights.
Definition: StatCollector.h:66
void add(Data_t v, Weight_t w)
Adds the specified weight to the statistics.
void add_without_uncertainty(Iter begin, Iter end)
Adds measurements from a sequence, with no uncertainty.
Definition: SimpleFits.h:136
static constexpr unsigned int NParams
Definition: SimpleFits.h:75
virtual Data_t Evaluate(Data_t x) const override
Evaluates the fitted function at the specified point.
Definition: SimpleFits.h:1589
Data_t X4() const
Aliases.
Definition: SimpleFits.h:968
bool add(MeasurementAndUncertainty_t value)
Definition: SimpleFits.h:367
int N() const
Returns the number of entries added.
Definition: StatCollector.h:63
Data_t InterceptError() const
Returns the error on intercept of the fit.
Definition: SimpleFits.h:874
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
unsigned int add_with_uncertainty(Iter begin, Iter end)
Definition: SimpleFits.h:405
unsigned int add_with_uncertainty(VIter begin_value, VIter end_value, UIter begin_uncertainty, VPred value_extractor, UPred uncertainty_extractor=UPred())
Adds measurements with uncertainties from a sequence.
Definition: SimpleFits.h:1442
void add_without_uncertainty(Iter begin, Iter end)
Definition: SimpleFits.h:370
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Clears all the input statistics.
Definition: SimpleFits.h:1719
typename Base_t::Data_t Data_t
type of the data
Definition: SimpleFits.h:1001
unsigned int add_with_uncertainty(VIter begin_value, VIter end_value, UIter begin_uncertainty, VPred value_extractor, UPred uncertainty_extractor=UPred())
Definition: SimpleFits.h:394
virtual FitMatrix_t InvertMatrix(FitMatrix_t const &mat, Data_t det) const
Computes the inverse of a matrix (using provided determinant)
Definition: SimpleFits.h:613
Data_t XN(unsigned int n) const
Returns the weighted sum of x^n.
Definition: SimpleFits.h:449
constexpr Data_t error() const
Definition: SimpleFits.h:1228
Data_t operator()(Data_t x) const
Evaluates the fitted function; alias of Evaluate()
Definition: SimpleFits.h:597
virtual Data_t FitParameterError(unsigned int n) const
Returns the error on parameter n of the fit result.
Definition: SimpleFits.h:529
Data_t XN(unsigned int n) const
Returns the weighted sum of x^n.
Definition: SimpleFits.h:290
virtual FitParameters_t FitParameterErrors() const override
Computes and returns all the parameter errors of the fit result.
Definition: SimpleFits.h:1766
Data_t XN() const
Returns the weighted sum of x^N.
Definition: SimpleFits.h:297
typename Collector_t::Data_t Data_t
type of the data
Definition: SimpleFits.h:349
Weight_t AverageWeight() const
Returns the arithmetic average of the weights.
Double_t z
Definition: plot.C:276
Float_t Y
Definition: plot.C:37
unsigned int add_with_uncertainty(Cont cont)
Clears all the input statistics.
Definition: SimpleFits.h:1065
std::array< Data_t, sqr(NParams)> FitMatrix_t
Definition: SimpleFits.h:951
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
Definition: SimpleFits.h:725
unsigned int add_with_uncertainty(VIter begin_value, VIter end_value, UIter begin_uncertainty, VPred value_extractor, UPred uncertainty_extractor=UPred())
Clears all the input statistics.
Definition: SimpleFits.h:1735
static MeasurementAndUncertainty_t EncodeValue(MeasurementAndUncertainty_t const &meas)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1268
constexpr auto abs(T v)
Returns the absolute value of the argument.
EncodeExtractor(VPred &vpred, UPred &upred)
Definition: SimpleFits.h:1285
static Data_t UncertaintyToWeight(Data_t s)
Transforms an uncertainty into a weight ( )
Definition: SimpleFits.h:319
< type of value and error
Definition: SimpleFits.h:1221
static constexpr Data_t sqr(Data_t v)
Returns the square of the specified data value.
Definition: SimpleFits.h:600
STL namespace.
WeightTracker< Data_t > y
accumulator for y
Definition: SimpleFits.h:327
static void ConvertParametersAndVariances(FitParameters_t const &qpars, FitMatrix_t const &qparerrmat, FitParameters_t &params, FitParameters_t &paramvariances)
Converts the specified quadratic fit parameters and errors.
Definition: SimpleFits.h:1850
Data_t Y2() const
Aliases.
Definition: SimpleFits.h:972
virtual Data_t Param(unsigned int n, FitMatrix_t const &Xmat) const
Computes a single fit parameter using the given information.
Definition: SimpleFits.h:1640
virtual Data_t Evaluate(Data_t x) const override
Evaluates the fitted function at the specified point.
Definition: SimpleFits.h:1198
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Clears all the input statistics.
Definition: SimpleFits.h:1023
static Value_t EncodeValue(Data_t value, Data_t error)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1243
Class providing data collection for the simple polynomial fitters.
Definition: SimpleFits.h:36
typename Fitter_t::FitMatrix_t FitMatrix_t
Definition: SimpleFits.h:1010
static constexpr V sqr(V const &v)
Returns the square of the specified value.
Definition: SimpleFits.h:284
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1703
void add(Weight_t weight)
Adds the specified weight to the statistics.
Definition: StatCollector.h:49
std::tuple< Data_t, Data_t > Base_t
Definition: SimpleFits.h:1222
Classes gathering simple statistics.
std::array< Data_t, sqr(NParams)> FitMatrix_t
Definition: SimpleFits.h:851
DataTracker< 1, Data_t > y2
accumulator for y2
Definition: SimpleFits.h:328
virtual FitParameters_t FitParameters() const override
Computes and returns all the parameters of the fit result.
Definition: SimpleFits.h:1760
int N() const
Returns the number of (valid) points added.
Definition: SimpleFits.h:1074
Double_t X2
Definition: plot.C:263
Value_t(Data_t v, Data_t e)
Definition: SimpleFits.h:1224
bool add(MeasurementAndUncertainty_t value)
Adds one entry with specified x, y and uncertainty.
Definition: SimpleFits.h:121
Performs a linear regression of data.
Definition: SimpleFits.h:833
static Measurement_t EncodeValue(Measurement_t const &meas)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1262
Weight_t Sum(unsigned int n) const
Returns the sum of the values to the power n (1 <= n <= 2, no check)
Data_t XNY(unsigned int n) const
Returns the weighted sum of x^n y.
Definition: SimpleFits.h:452
virtual FitMatrix_t MakeMatrixX() const
Fills and returns the matrix of x^n sum coefficients ( { x^(i+j) } )
Definition: SimpleFits.h:1601
virtual FitMatrix_t FitParameterCovariance() const override
Computes and returns all the covariance matrix of the fit result.
Definition: SimpleFits.h:1776
typename Collector_t::MeasurementAndUncertainty_t MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:355
UPred & error_extractor
uncertainty extractor
Definition: SimpleFits.h:1300
Data_t XNY() const
Returns the weighted sum of x^N y.
Definition: SimpleFits.h:304
virtual FitParameters_t FitParameterErrors() const override
Computes and returns all the parameter errors of the fit result.
Definition: SimpleFits.h:1528
void clear()
Resets the count.
Definition: StatCollector.h:56
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
typename Base_t::Data_t Data_t
type of the data
Definition: SimpleFits.h:649
Classes with hard-coded (hence "fast") matrix math.
Data_t Slope() const
Returns the slope of the fit.
Definition: SimpleFits.h:867
void add_without_uncertainty(Cont cont)
Clears all the input statistics.
Definition: SimpleFits.h:1049
static Value_t DecodeValue(Value_t const &value)
Converts a value from the quadratic fit into a proper value.
Definition: SimpleFits.h:1255
virtual bool FillResults(FitParameters_t &params, FitMatrix_t &Xmat, Data_t &det, FitMatrix_t &Smat) const override
Fills the specified parameters.
Definition: SimpleFits.h:1803
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1690
virtual FitMatrix_t InvertMatrix(FitMatrix_t const &mat) const
Computes the inverse of a matrix.
Definition: SimpleFits.h:619
unsigned int add_with_uncertainty(Cont cont)
Adds measurements with uncertainties from a container.
Definition: SimpleFits.h:255
static FitParameters_t ConvertParameters(FitParameters_t const &qpars)
Converts the specified quadratic fit parameters into Gaussian.
Definition: SimpleFits.h:1835
Provides "fast" matrix operations.
constexpr Data_t value() const
Definition: SimpleFits.h:1227
WeightTracker< Data_t > s2
accumulator for uncertainty
Definition: SimpleFits.h:325
Data_t InterceptSlopeCovariance() const
Returns the covariance between intercept and slope of the fit.
Definition: SimpleFits.h:888
Data_t Intercept() const
Returns the intercept of the fit.
Definition: SimpleFits.h:860
Data_t X2() const
Aliases.
Definition: SimpleFits.h:904
virtual FitMatrix_t FitParameterCovariance() const override
Computes and returns all the covariance matrix of the fit result.
Definition: SimpleFits.h:1534
DataTracker< Degree *2, Data_t > x
accumulator for variable x^k
Definition: SimpleFits.h:326
constexpr T sqr(T v)
static T Sum(WeightTracker< T > const &, DataTracker< Power, T > const &sums)
Definition: SimpleFits.h:57
A unary functor returning its own argument (any type)
Definition: StatCollector.h:31
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:950
void add_without_uncertainty(Cont cont, Pred extractor)
Definition: SimpleFits.h:382
void add_without_uncertainty(Cont cont, Pred extractor)
Clears all the input statistics.
Definition: SimpleFits.h:1043
bool FillResults(FitParameters_t &params, FitMatrix_t &Xmat, Data_t &det, FitMatrix_t &Smat) const override
Fills the specified parameters.
Definition: SimpleFits.h:1546
static void ConvertParametersAndErrors(FitParameters_t const &qpars, FitMatrix_t const &qparerrmat, FitParameters_t &params, FitParameters_t &paramerrors)
Converts the specified quadratic fit parameters and errors.
Definition: SimpleFits.h:1879
typename Interface_t::FitParameters_t FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:652
static Data_t WeightToUncertainty(Data_t w)
Transforms a weight back to an uncertainty ( )
Definition: SimpleFits.h:322
int N() const
Returns the number of entries added.
Definition: SimpleFits.h:269
void add_without_uncertainty(Cont cont, Pred extractor)
Adds all measurements from a container, with no uncertainty.
Definition: SimpleFits.h:172
void PrintStats(Stream &out) const
Prints the collected statistics into a stream.
Definition: SimpleFits.h:433
void clear()
Clears all the statistics.
Definition: SimpleFits.h:419
Data_t X() const
Aliases.
Definition: SimpleFits.h:903
Float_t mat
Definition: plot.C:38
void add_without_uncertainty(Iter begin, Iter end)
Clears all the input statistics.
Definition: SimpleFits.h:1034
"Fast" Gaussian fit
Definition: SimpleFits.h:993
virtual FitParameters_t MatrixProduct(FitMatrix_t const &mat, FitParameters_t const &vec) const
Computes the product of a FitMatrix_t and a FitParameters_t.
Definition: SimpleFits.h:625
Class tracking sums of variables up to a specified power.
Definition: StatCollector.h:98
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
Definition: SimpleFits.h:1144
VPred & value_extractor
value extractor
Definition: SimpleFits.h:1299
Data_t SlopeError() const
Returns the error in slope of the fit.
Definition: SimpleFits.h:881
virtual Data_t FitParameterError(unsigned int n) const override
Returns the error on parameter n of the fit result.
Definition: SimpleFits.h:1510
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Definition: SimpleFits.h:365
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:850
virtual FitParameters_t FitParameterErrors(FitMatrix_t const &Smat) const
Computes and returns all the parameter errors of the fit result.
Definition: SimpleFits.h:785
double value
Definition: spectrum.C:18
Value_t(MeasurementAndUncertainty_t meas)
Definition: SimpleFits.h:1225
Data_t AverageUncertainty() const
Returns an average of the uncertainties.
Definition: SimpleFits.h:280
static Value_t EncodeValue(Value_t const &value)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1249
Data_t XNY(unsigned int n) const
Returns the weighted sum of x^n y.
Definition: SimpleFits.h:293
Performs a second-degree fit of data.
Definition: SimpleFits.h:933
typename Interface_t::FitMatrix_t FitMatrix_t
type of matrix for covariance (a std::array)
Definition: SimpleFits.h:655
void clear()
Resets the count.
typename MatrixOps::Matrix_t FitMatrix_t
type of matrix for covariance (a std::array)
Definition: SimpleFits.h:471
Data_t Y() const
Aliases.
Definition: SimpleFits.h:969
void Print(Stream &out) const
Prints the statistics into a stream.
Definition: SimpleFits.h:1480
static constexpr unsigned int Power
Fitter_t fitter
the actual fitter and data holder
Definition: SimpleFits.h:1215
virtual FitParameters_t FitParameters() const override
Computes and returns all the parameters of the fit result.
Definition: SimpleFits.h:1518
static constexpr V sqr(V const &v)
Returns the square of the specified value.
Definition: SimpleFits.h:440
std::tuple< Data_t, Data_t > Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:80
static FitParameters_t ExtractParameterErrors(FitMatrix_t const &Smat)
Extracts parameter errors from diagonal of the covarriance matrix.
Definition: SimpleFits.h:1653
Data_t X2Y() const
Aliases.
Definition: SimpleFits.h:971
double weight
Definition: plottest35.C:25
virtual Fitter_t const & Fitter() const
Returns the internal fitter (mostly for debugging)
Definition: SimpleFits.h:1204
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
DataTracker< Degree, Data_t > xy
accumulator for variable xy
Definition: SimpleFits.h:329
Base class providing virtual fitting interface for polynomial fitters.
Definition: SimpleFits.h:635
static T Sum(WeightTracker< T > const &weight, DataTracker< Power, T > const &)
Definition: SimpleFits.h:66
bool add(MeasurementAndUncertainty_t value)
Clears all the input statistics.
Definition: SimpleFits.h:1028
static MeasurementAndUncertainty_t EncodeValue(Measurement_t const &meas, Data_t error)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1275
LArSoft-specific namespace.
Base class providing data collection for the simple polynomial fitters.
Definition: SimpleFits.h:342
typename Fitter_t::Measurement_t Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:1004
Data_t XY() const
Aliases.
Definition: SimpleFits.h:906
Simple fitter abstract interface.
Definition: SimpleFits.h:458
typename Fitter_t::MeasurementAndUncertainty_t MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:1007
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Adds one entry with specified x, y and uncertainty.
Definition: SimpleFits.h:109
virtual FitParameters_t MakeMatrixY() const
Fills and returns the matrix (vector) of x^n y sum coefficients.
Definition: SimpleFits.h:1613
void clear()
Clears all the statistics.
Definition: SimpleFits.h:1469
static EncodeExtractor< VPred, UPred > Encoder(VPred &vpred, UPred &upred)
Definition: SimpleFits.h:1335
static constexpr unsigned int Degree
Degree of the fit.
Definition: SimpleFits.h:74
virtual Data_t Determinant(FitMatrix_t const &mat) const
Computes the determinant of a matrix.
Definition: SimpleFits.h:607
void add_without_uncertainty(Cont cont)
Adds all measurements from a container, with no uncertainty.
Definition: SimpleFits.h:188
void clear()
Clears all the input statistics.
Definition: SimpleFits.h:1071
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1678
unsigned int add_with_uncertainty(Cont cont)
Definition: SimpleFits.h:411
Data_t XY() const
Aliases.
Definition: SimpleFits.h:970
virtual bool isValid() const override
Returns if the fit has valid results.
Definition: SimpleFits.h:1497
Char_t n[5]
void add_without_uncertainty(Iter begin, Iter end, Pred extractor)
Definition: SimpleFits.h:376
static void ConvertParametersAndErrorMatrix(FitParameters_t const &qpars, FitMatrix_t const &qparerrmat, FitParameters_t &params, FitMatrix_t &Smat)
Converts the specified quadratic fit parameters and errors.
Definition: SimpleFits.h:1891
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
Data_t X() const
Aliases.
Definition: SimpleFits.h:965
typename Collector_t::Measurement_t Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:352
virtual Data_t ChiSquare() const override
Returns the of the original fit.
Definition: SimpleFits.h:1135
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:468
typename Fitter_t::FitParameters_t FitParameters_t
Definition: SimpleFits.h:1009
Data_t Y() const
Aliases.
Definition: SimpleFits.h:905
static Data_t DecodeValue(Data_t value)
Converts a value from the quadratic fit into a proper value.
Definition: SimpleFits.h:1240
static Data_t EncodeValue(Data_t value)
Definition: SimpleFits.h:1237
Float_t e
Definition: plot.C:35
virtual Data_t FitParameter(unsigned int n) const
Returns the parameter n of the fit result.
Definition: SimpleFits.h:521
Float_t X
Definition: plot.C:37
Data_t X2() const
Aliases.
Definition: SimpleFits.h:966
Float_t w
Definition: plot.C:20
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Definition: SimpleFits.h:363
static EncodeExtractor< Pred > Encoder(Pred &pred)
Definition: SimpleFits.h:1329
Data_t X3() const
Aliases.
Definition: SimpleFits.h:967
Collector_t stats
statistics collected from fit data input
Definition: SimpleFits.h:446
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Adds one entry with specified x, y and uncertainty.
Definition: SimpleFits.h:1412
virtual Data_t FitParameter(unsigned int n) const override
Returns the parameter n of the fit result.
Definition: SimpleFits.h:1503
void PrintStats(Stream &out) const
Prints the collected statistics into a stream.
Definition: SimpleFits.h:1078
Data_t Y2() const
Aliases.
Definition: SimpleFits.h:907
Data_t Y2() const
Returns the weighted sum of y^2.
Definition: SimpleFits.h:310
std::tuple< Data_t, Data_t, Data_t > MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:83
virtual bool isValid() const override
Returns if the fit has valid results.
Definition: SimpleFits.h:1097