LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 <cmath> // std::sqrt()
18 #include <tuple>
19 #include <array>
20 #include <iterator> // std::begin(), std::end()
21 #include <algorithm> // std::for_each()
22 #include <type_traits> // std::enable_if<>, std::is_const<>
23 #include <stdexcept> // std::range_error
24 #include <ostream> // std::endl
25 
26 
27 #include "lardata/Utilities/StatCollector.h" // lar::util::identity
28 #include "lardata/Utilities/FastMatrixMathHelper.h" // lar::util::details::FastMatrixOperations
29 
30 namespace lar {
31  namespace util {
32 
33  namespace details {
34 
36  template <typename T, unsigned int D>
38 
56  template <unsigned int Power, unsigned int N>
57  struct SumExtractor {
58  static T Sum
60  { return sums.template SumN<N>(); }
61  }; // SumExtractor
62 
63  // specialization
64  template <unsigned int Power>
65  struct SumExtractor<Power, 0U> {
66  static T Sum
68  { return weight.Weights(); }
69  }; // SumExtractor<>
70 
71  public:
73  static constexpr unsigned int Degree = D;
74  static constexpr unsigned int NParams = Degree + 1;
75 
76  using Data_t = T;
77 
79  using Measurement_t = std::tuple<Data_t, Data_t>;
80 
82  using MeasurementAndUncertainty_t = std::tuple<Data_t, Data_t, Data_t>;
83 
84  // default constructor, destructor and all the rest
85 
88 
98  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0));
99 
109  { return add(std::get<0>(value), std::get<1>(value), sy); }
110 
119  {
120  return
121  add(std::get<0>(value), std::get<1>(value), std::get<2>(value));
122  }
123 
124 
134  template <typename Iter>
136  { add_without_uncertainty(begin, end, identity()); }
137 
151  template <typename Iter, typename Pred>
152  void add_without_uncertainty(Iter begin, Iter end, Pred extractor);
153 
168  template <typename Cont, typename Pred>
169  void add_without_uncertainty(Cont cont, Pred extractor)
170  { add_without_uncertainty(std::begin(cont), std::end(cont), extractor); }
171 
182  template <typename Cont>
183  void add_without_uncertainty(Cont cont)
184  { add_without_uncertainty(std::begin(cont), std::end(cont)); }
185 
186 
213  template <
214  typename VIter, typename UIter,
215  typename VPred, typename UPred = identity
216  >
217  unsigned int add_with_uncertainty(
218  VIter begin_value, VIter end_value,
219  UIter begin_uncertainty,
220  VPred value_extractor,
221  UPred uncertainty_extractor = UPred()
222  );
223 
224 
239  template <typename Iter>
240  unsigned int add_with_uncertainty(Iter begin, Iter end);
241 
253  template <typename Cont>
254  unsigned int add_with_uncertainty(Cont cont)
255  { return add_with_uncertainty(std::begin(cont), std::end(cont)); }
256 
258 
260  void clear();
261 
264 
266  int N() const { return s2.N(); }
267 
278  { return WeightToUncertainty(s2.AverageWeight()); }
279 
280 
282  template <typename V>
283  static constexpr V sqr(V const& v) { return v*v; }
284 
285 
287  Data_t XN(unsigned int n) const
288  { return (n == 0)? s2.Weights(): x.Sum(n); }
289 
291  Data_t XNY(unsigned int n) const
292  { return (n == 0)? y.Weights(): xy.Sum(n); }
293 
294 
296  template <unsigned int N>
297  Data_t XN() const
299 
301  template <unsigned int N>
302  Data_t XNY() const
304 
305 
307  Data_t Y2() const { return y2.template SumN<1>(); }
308 
309 
311 
313  template <typename Stream>
314  void Print(Stream& out) const;
315 
318  { return Data_t(1.)/sqr(s); }
319 
322  { return Data_t(1.)/std::sqrt(w); }
323 
324 
325  protected:
326 
332 
333  }; // class FitDataCollector<>
334 
335 
336  template <typename T, unsigned int D>
337  inline std::ostream& operator<<
338  (std::ostream& out, FitDataCollector<T, D> const& stats)
339  { stats.Print(out); return out; }
340 
341 
343  template <typename T, unsigned int D>
346 
347  public:
349  static constexpr unsigned int Degree = Collector_t::Degree;
350 
351  using Data_t = typename Collector_t::Data_t;
352 
355 
359 
360  // default constructor, destructor and all the rest
361 
365 
366  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0))
367  { return stats.add(x, y, sy); }
368 
370  { return stats.add(value, sy); }
371 
373  { return stats.add(value); }
374 
375 
376  template <typename Iter>
378  { stats.add_without_uncertainty(begin, end); }
379 
380  template <typename Iter, typename Pred>
381  void add_without_uncertainty(Iter begin, Iter end, Pred extractor)
382  { stats.add_without_uncertainty(begin, end, extractor); }
383 
384  template <typename Cont, typename Pred>
385  void add_without_uncertainty(Cont cont, Pred extractor)
386  { stats.add_without_uncertainty(cont, extractor); }
387 
388  template <typename Cont>
389  void add_without_uncertainty(Cont cont)
390  { stats.add_without_uncertainty(cont); }
391 
392 
393  template <
394  typename VIter, typename UIter,
395  typename VPred, typename UPred = identity
396  >
397  unsigned int add_with_uncertainty(
398  VIter begin_value, VIter end_value,
399  UIter begin_uncertainty,
400  VPred value_extractor,
401  UPred uncertainty_extractor = UPred()
402  )
403  {
404  return stats.add_with_uncertainty(
405  begin_value, end_value, begin_uncertainty,
406  value_extractor, uncertainty_extractor);
407  }
408 
409 
410  template <typename Iter>
411  unsigned int add_with_uncertainty(Iter begin, Iter end)
412  { return stats.add_with_uncertainty(begin, end); }
413 
414  template <typename Cont>
415  unsigned int add_with_uncertainty(Cont cont)
416  { return stats.add_with_uncertainty(cont); }
417 
419 
421  void clear() { stats.clear(); }
422 
426 
427  int N() const { return stats.N(); }
428 
429  Data_t AverageUncertainty() const { return stats.AverageUncertainty(); }
430 
432 
433 
435  template <typename Stream>
436  void PrintStats(Stream& out) const { stats.Print(out); }
437 
438 
440  template <typename V>
441  static constexpr V sqr(V const& v) { return Collector_t::sqr(v); }
442 
443  protected:
445 
447  Data_t XN(unsigned int n) const { return stats.XN(n); }
448 
450  Data_t XNY(unsigned int n) const { return stats.XNY(n); }
451 
452  }; // class SimplePolyFitterDataBase<>
453 
454 
455 
457  template <typename T, unsigned int N>
459  public:
460 
462  static constexpr unsigned int NParams = N;
463 
464  using Data_t = T;
465 
467 
469  using FitParameters_t = std::array<Data_t, NParams>;
470 
473 
474 
476  virtual ~SimpleFitterInterface() = default;
477 
478 
489  virtual bool isValid() const = 0;
490 
493 
499  virtual FitParameters_t FitParameters() const = 0;
500 
506  virtual FitParameters_t FitParameterErrors() const = 0;
507 
516  virtual FitMatrix_t FitParameterCovariance() const = 0;
517 
524  virtual Data_t FitParameter(unsigned int n) const
525  { return FitParameters()[n]; }
526 
533  virtual Data_t FitParameterError(unsigned int n) const
534  { return std::sqrt(FitParameterCovariance()[n * (NParams + 1)]); }
535 
536 
541  virtual Data_t ChiSquare() const = 0;
542 
550  virtual int NDF() const = 0;
551 
553 
554 
563  virtual bool FillResults(
564  FitParameters_t& params,
565  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
566  ) const = 0;
567 
577  virtual bool FillResults(
578  FitParameters_t& params, FitParameters_t& paramerrors,
579  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
580  ) const = 0;
581 
588  virtual bool FillResults
589  (FitParameters_t& params, FitParameters_t& paramerrors) const = 0;
590 
591 
599  virtual Data_t Evaluate(Data_t x) const = 0;
600 
601 
603  Data_t operator() (Data_t x) const { return Evaluate(x); }
604 
605 
607  static constexpr Data_t sqr(Data_t v) { return v*v; }
608 
610  static constexpr Data_t cube(Data_t v) { return v*v*v; }
611 
612  protected:
613 
615  virtual Data_t Determinant(FitMatrix_t const& mat) const
616  { return MatrixOps::Determinant(mat); }
617 
619  virtual FitMatrix_t InvertMatrix
620  (FitMatrix_t const& mat, Data_t det) const
621  { return MatrixOps::InvertSymmetricMatrix(mat, det); }
622 
624  virtual FitMatrix_t InvertMatrix(FitMatrix_t const& mat) const
625  { return MatrixOps::InvertSymmetricMatrix(mat); }
626 
628  virtual FitParameters_t MatrixProduct
629  (FitMatrix_t const& mat, FitParameters_t const& vec) const
630  { return MatrixOps::MatrixVectorProduct(mat, vec); }
631 
632  }; // class SimpleFitterInterface<>
633 
634 
636  template <typename T, unsigned int D>
638  public SimpleFitterInterface<T, D + 1>,
639  public SimplePolyFitterDataBase<T, D>
640  {
643 
644  public:
645  using Base_t::sqr;
646 
648  static constexpr unsigned int Degree = Base_t::Degree;
649 
651  static constexpr unsigned int NParams = Interface_t::NParams;
652 
653  using Data_t = typename Base_t::Data_t;
654 
657 
660 
661 
672  virtual bool isValid() const override;
673 
676 
682  virtual FitParameters_t FitParameters() const override;
683 
689  virtual FitParameters_t FitParameterErrors() const override;
690 
699  virtual FitMatrix_t FitParameterCovariance() const override;
700 
707  virtual Data_t FitParameter(unsigned int n) const override;
708 
715  virtual Data_t FitParameterError(unsigned int n) const override;
716 
717 
722  virtual Data_t ChiSquare() const override;
723 
731  virtual int NDF() const override { return Base_t::N() - NParams; }
732 
734 
735 
744  bool FillResults(
745  FitParameters_t& params,
746  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
747  ) const override;
748 
758  bool FillResults(
759  FitParameters_t& params, FitParameters_t& paramerrors,
760  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
761  ) const override;
762 
769  bool FillResults
770  (FitParameters_t& params, FitParameters_t& paramerrors)
771  const override;
772 
773 
781  virtual Data_t Evaluate(Data_t x) const override;
782 
783 
785  static FitParameters_t ExtractParameterErrors(FitMatrix_t const& Smat);
786 
787 
788  protected:
789 
791  virtual FitMatrix_t MakeMatrixX() const;
792 
794  virtual FitParameters_t MakeMatrixY() const;
795 
797  virtual FitParameters_t FitParameterErrors
798  (FitMatrix_t const& Smat) const
799  { return ExtractParameterErrors(Smat); }
800 
802  virtual FitParameters_t FitParameters(FitMatrix_t const& Xmat) const;
804 
805  virtual FitParameters_t FitParameters
806  (FitMatrix_t const& Smat, Data_t /* det */) const;
808 
810  virtual Data_t Param
812  (unsigned int n, FitMatrix_t const& Xmat) const;
813  virtual Data_t Param
814  (unsigned int n, FitMatrix_t const& Xmat, Data_t detXmat) const;
816 
817  // import the declaration from the interface
818  using Interface_t::Determinant;
819  using Interface_t::InvertMatrix;
820  using Interface_t::MatrixProduct;
821 
822  }; // class SimplePolyFitterBase<>
823 
824 
825  } // namespace details
826 
827 
848  template <typename T>
851 
852  public:
853  using Base_t::Degree;
854  using Base_t::NParams;
855  using typename Base_t::Data_t;
856 
858  using typename Base_t::Measurement_t;
859 
862 
863  using Base_t::sqr;
864 
866  using FitParameters_t = std::array<Data_t, NParams>;
867  using FitMatrix_t = std::array<Data_t, sqr(NParams)>;
868 
869 
870  // default constructor, destructor and all the rest
871 
877  Data_t Intercept() const { return this->FitParameter(0); }
878 
884  Data_t Slope() const { return this->FitParameter(1); }
885 
891  Data_t InterceptError() const { return this->FitParameterError(0); }
892 
898  Data_t SlopeError() const { return this->FitParameterError(1); }
899 
906  { return this->FitParameterCovariance()[0 * NParams + 1]; }
907 
908 
913  virtual Data_t ChiSquare() const override;
914 
915 
916  protected:
917 
919  Data_t I() const { return Base_t::stats.template XN<0>(); }
921  Data_t X() const { return Base_t::stats.template XN<1>(); }
922  Data_t X2() const { return Base_t::stats.template XN<2>(); }
923  Data_t Y() const { return Base_t::stats.template XNY<0>(); }
924  Data_t XY() const { return Base_t::stats.template XNY<1>(); }
925  Data_t Y2() const { return Base_t::stats.Y2(); }
927 
928  }; // class LinearFit<>
929 
930 
931 
952  template <typename T>
955 
956  public:
957  using Base_t::Degree;
958  using Base_t::NParams;
959  using typename Base_t::Data_t;
960 
962  using typename Base_t::Measurement_t;
963 
966 
967  using Base_t::sqr;
968 
970  using FitParameters_t = std::array<Data_t, NParams>;
971  using FitMatrix_t = std::array<Data_t, sqr(NParams)>;
972 
973 
974  // default constructor, destructor and all the rest
975 
980  virtual Data_t ChiSquare() const override;
981 
982 
983  protected:
984 
986  Data_t I() const { return Base_t::stats.template XN<0>(); }
988  Data_t X() const { return Base_t::stats.template XN<1>(); }
989  Data_t X2() const { return Base_t::stats.template XN<2>(); }
990  Data_t X3() const { return Base_t::stats.template XN<3>(); }
991  Data_t X4() const { return Base_t::stats.template XN<4>(); }
992  Data_t Y() const { return Base_t::stats.template XNY<0>(); }
993  Data_t XY() const { return Base_t::stats.template XNY<1>(); }
994  Data_t X2Y() const { return Base_t::stats.template XNY<2>(); }
995  Data_t Y2() const { return Base_t::stats.Y2(); }
997 
998  }; // class QuadraticFit<>
999 
1000 
1001 
1017  template <typename T>
1021 
1022  public:
1024  static constexpr unsigned int NParams = Base_t::NParams;
1025 
1026  using Data_t = typename Base_t::Data_t;
1027 
1030 
1034 
1037 
1038  using Base_t::sqr;
1039  using Base_t::cube;
1040 
1041 
1042  // default constructor, destructor and all the rest
1043 
1047 
1048  bool add(Data_t x, Data_t y, Data_t sy = Data_t(1.0));
1049 
1050  bool add(Measurement_t value, Data_t sy = Data_t(1.0))
1051  { return add(std::get<0>(value), std::get<1>(value), sy); }
1052 
1054  {
1055  return
1056  add(std::get<0>(value), std::get<1>(value), std::get<2>(value));
1057  }
1058 
1059 
1060  template <typename Iter>
1062  { add_without_uncertainty(begin, end, identity()); }
1063 
1064  template <typename Iter, typename Pred>
1065  void add_without_uncertainty(Iter begin, Iter end, Pred extractor);
1066 
1067  template <typename Cont, typename Pred>
1068  void add_without_uncertainty(Cont cont, Pred extractor)
1069  { add_without_uncertainty(std::begin(cont), std::end(cont), extractor); }
1070 
1071  template <typename Cont>
1072  void add_without_uncertainty(Cont cont)
1073  { add_without_uncertainty(std::begin(cont), std::end(cont)); }
1074 
1075 
1076  template <
1077  typename VIter, typename UIter,
1078  typename VPred, typename UPred = identity
1079  >
1080  unsigned int add_with_uncertainty(
1081  VIter begin_value, VIter end_value,
1082  UIter begin_uncertainty,
1083  VPred value_extractor,
1084  UPred uncertainty_extractor = UPred()
1085  );
1086 
1087 
1088  template <typename Iter>
1089  unsigned int add_with_uncertainty(Iter begin, Iter end);
1090 
1091  template <typename Cont>
1092  unsigned int add_with_uncertainty(Cont cont)
1093  { return add_with_uncertainty(std::begin(cont), std::end(cont)); }
1094 
1095 
1097  void clear() { fitter.clear(); }
1098 
1100  int N() const { return fitter.N(); }
1101 
1102 
1104  template <typename Stream>
1105  void PrintStats(Stream& out) const { fitter.PrintStats(out); }
1106 
1108 
1109 
1112 
1122  virtual bool isValid() const override { return fitter.isValid(); }
1123 
1126 
1132  virtual FitParameters_t FitParameters() const override;
1133 
1139  virtual FitParameters_t FitParameterErrors() const override;
1140 
1150  virtual FitMatrix_t FitParameterCovariance() const override;
1151 
1152 
1161  virtual Data_t ChiSquare() const override { return fitter.ChiSquare(); }
1162 
1170  virtual int NDF() const override { return fitter.NDF(); }
1171 
1173 
1174 
1186  virtual bool FillResults(
1187  FitParameters_t& params,
1188  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1189  ) const override;
1201  virtual bool FillResults(
1202  FitParameters_t& params, FitParameters_t& paramerrors,
1203  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1204  ) const override;
1205 
1214  virtual bool FillResults
1215  (FitParameters_t& params, FitParameters_t& paramerrors) const override;
1216 
1217 
1225  virtual Data_t Evaluate(Data_t x) const override
1226  { return Evaluate(x, FitParameters().data()); }
1227 
1228 
1230  virtual Fitter_t const& Fitter() const { return fitter; }
1231 
1232 
1239  static Data_t Evaluate(Data_t x, Data_t const* params);
1240 
1241  protected:
1243 
1246 
1248  struct Value_t: public std::tuple<Data_t, Data_t> {
1249  using Base_t = std::tuple<Data_t, Data_t>;
1250 
1251  Value_t(Data_t v, Data_t e): Base_t(v, e) {}
1253  Base_t(std::get<1>(meas), std::get<2>(meas)) {}
1254 
1255  constexpr Data_t value() const { return std::get<0>(*this); }
1256  constexpr Data_t error() const { return std::get<1>(*this); }
1257 
1258  Data_t& value() { return std::get<0>(*this); }
1259  Data_t& error() { return std::get<1>(*this); }
1260 
1261  }; // Value_t
1262 
1265  static Data_t EncodeValue(Data_t value) { return std::log(value); }
1266 
1268  static Data_t DecodeValue(Data_t value) { return std::exp(value); }
1269 
1270 
1273  { return { std::log(value), error / std::abs(value) }; }
1274 
1275 
1277  static Value_t EncodeValue(Value_t const& value)
1278  { return EncodeValue(value.value(), value.error()); }
1279 
1280 
1282  static Value_t DecodeValue(Value_t const& value)
1283  {
1284  const Data_t v = std::exp(value.value());
1285  return { v, v * value.error() };
1286  } // DecodeValue()
1287 
1290  {
1291  return
1292  Measurement_t(std::get<0>(meas), EncodeValue(std::get<1>(meas)));
1293  }
1294 
1296  static MeasurementAndUncertainty_t EncodeValue
1298  {
1299  Value_t value = EncodeValue(Value_t(meas));
1300  return { std::get<0>(meas), value.value(), value.error() };
1301  } // EncodeValue(MeasurementAndUncertainty_t)
1302 
1304  static MeasurementAndUncertainty_t EncodeValue
1305  (Measurement_t const& meas, Data_t error)
1306  {
1307  Value_t value = EncodeValue(Value_t(std::get<1>(meas), error));
1308  return { std::get<0>(meas), value.value(), value.error() };
1309  } // EncodeValue(Measurement_t, Data_t)
1310 
1311 
1314  template <typename VPred, typename UPred = void>
1316  EncodeExtractor(VPred& vpred, UPred& upred):
1317  value_extractor(vpred), error_extractor(upred) {}
1318 
1319  // extractor takes whatever dereferencing Iter gives and returns
1320  // Measurement_t or MeasurementAndUncertainty_t,
1321  // the one the extractor returns
1322  template <typename Elem>
1323  auto operator() (Elem elem)
1324  {
1325  // use explicit casts to make sure we know what we are doing
1326  return EncodeValue(
1327  static_cast<Measurement_t&&>(value_extractor(elem)),
1328  static_cast<Data_t&&>(error_extractor(elem))
1329  );
1330  } // operator()
1331 
1334  }; // struct EncodeExtractor
1335 
1338  template <typename Pred>
1339  struct EncodeExtractor<Pred, void> {
1340  EncodeExtractor(Pred& pred): extractor(pred) {}
1341 
1342  // extractor takes whatever dereferencing Iter gives and returns
1343  // Measurement_t or MeasurementAndUncertainty_t,
1344  // the one the extractor returns;
1345  // as usual with enable_if, I am not sure it makes sense
1346  template <
1347  typename Elem,
1349  >
1350  auto operator() (Elem elem) const
1351  { return EncodeValue(extractor(elem)); }
1352 
1353  template <
1354  typename Elem,
1356  >
1357  auto operator() (Elem elem)
1358  { return EncodeValue(extractor(elem)); }
1359 
1360  Pred& extractor;
1361  }; // struct EncodeExtractor<Pred>
1362 
1363  template <typename Pred>
1364  static EncodeExtractor<Pred> Encoder(Pred& pred) { return { pred }; }
1365 
1366  template <typename VPred, typename UPred>
1367  static EncodeExtractor<VPred, UPred> Encoder(VPred& vpred, UPred& upred)
1368  { return { vpred, upred }; }
1369 
1371 
1377  static FitParameters_t ConvertParameters(FitParameters_t const& qpars);
1378 
1386  static void ConvertParametersAndErrors(
1387  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1388  FitParameters_t& params, FitParameters_t& paramerrors
1389  );
1390 
1398  static void ConvertParametersAndVariances(
1399  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1400  FitParameters_t& params, FitParameters_t& paramvariances
1401  );
1402 
1410  static void ConvertParametersAndErrorMatrix(
1411  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1412  FitParameters_t& params, FitMatrix_t& Smat
1413  );
1414 
1421  static bool isValid
1422  (FitParameters_t const& params, FitParameters_t const& qpars);
1423 
1424 
1425  static void ThrowNotImplemented [[noreturn]] (std::string method)
1426  { throw std::logic_error("Method " + method + "() not implemented"); }
1427 
1428  }; // class GaussianFit<>
1429 
1430 
1431  } // namespace util
1432 } // namespace lar
1433 
1434 
1435 //==============================================================================
1436 //=== template implementation
1437 //==============================================================================
1438 
1439 
1440 //******************************************************************************
1441 //*** FitDataCollector<>
1442 //***
1443 
1444 template <typename T, unsigned int D>
1446  (Data_t x_value, Data_t y_value, Data_t sy /* = Data_t(1.0) */)
1447 {
1449  if (!std::isnormal(w)) return false;
1450  // the x section has a 1/s^2 weight; we track that weight separately
1451  s2.add(w);
1452  x.add(x_value, w);
1453  // we treat the y section as if it were a x section with a y/s^2 weight;
1454  // we track that weight separately
1455  Data_t yw = y_value * w;
1456  y.add(yw);
1457  y2.add(sqr(y_value), w); // used only for chi^2
1458  xy.add(x_value, yw);
1459 
1460  return true; // we did add the value
1461 } // FitDataCollector<>::add()
1462 
1463 
1464 template <typename T, unsigned int D>
1465 template <typename Iter, typename Pred>
1467  (Iter begin, Iter end, Pred extractor)
1468 {
1469  std::for_each
1470  (begin, end, [this, extractor](auto item) { this->add(extractor(item)); });
1471 } // FitDataCollector<>::add_without_uncertainty(Iter, Pred)
1472 
1473 
1474 template <typename T, unsigned int D>
1475 template <typename VIter, typename UIter, typename VPred, typename UPred>
1476 unsigned int
1478  VIter begin_value, VIter end_value,
1479  UIter begin_uncertainty,
1480  VPred value_extractor,
1481  UPred uncertainty_extractor /* = UPred() */
1482 ) {
1483  unsigned int n = 0;
1484  while (begin_value != end_value) {
1485  if (add
1486  (value_extractor(*begin_value), uncertainty_extractor(*begin_uncertainty))
1487  )
1488  ++n;
1489  ++begin_value;
1490  ++begin_uncertainty;
1491  } // while
1492  return n;
1493 } // FitDataCollector<>::add_with_uncertainty(VIter, VIter, UIter, VPred, UPred)
1494 
1495 
1496 template <typename T, unsigned int D>
1497 template <typename Iter>
1499  (Iter begin, Iter end)
1500 {
1501  unsigned int old_n = N();
1502  std::for_each(begin, end, [this](auto p) { this->add(p); });
1503  return N() - old_n;
1504 } // FitDataCollector<>::add_with_uncertainty(Iter, Iter)
1505 
1506 
1507 
1508 template <typename T, unsigned int D>
1510  s2.clear();
1511  x.clear();
1512  y.clear();
1513  y2.clear();
1514  xy.clear();
1515 } // FitDataCollector<>::clear()
1516 
1517 
1518 template <typename T, unsigned int D> template <typename Stream>
1520 
1521  out << "Sums 1/s^2=" << s2.Weights()
1522  << "\n x/s^2=" << x.template SumN<1>();
1523  for (unsigned int degree = 2; degree <= x.Power; ++degree)
1524  out << "\n x^" << degree << "/s^2=" << x.Sum(degree);
1525  out
1526  << "\n y/s^2=" << y.Weights()
1527  << "\n y^2/s^2=" << y2.Sum();
1528  if (xy.Power >= 1)
1529  out << "\n xy/s^2=" << xy.template SumN<1>();
1530  for (unsigned int degree = 2; degree <= xy.Power; ++degree)
1531  out << "\n x^" << degree << "y/s^2=" << xy.Sum(degree);
1532  out << std::endl;
1533 } // FitDataCollector<>::Print()
1534 
1535 
1536 //******************************************************************************
1537 //*** SimplePolyFitterBase<>
1538 //***
1539 template <typename T, unsigned int D>
1541  return (Base_t::N() > (int) Degree)
1542  && std::isnormal(Determinant(MakeMatrixX()));
1543 } // SimplePolyFitterBase<>::isValid()
1544 
1545 
1546 template <typename T, unsigned int D>
1548  (unsigned int n) const -> Data_t
1549 {
1550  return Param(n, MakeMatrixX());
1551 } // SimplePolyFitterBase<>::FitParameter(unsigned int)
1552 
1553 
1554 template <typename T, unsigned int D>
1556  (unsigned int n) const -> Data_t
1557 {
1558  if (n > Degree) return Data_t(0); // no parameter, no error
1559  return std::sqrt(FitParameterCovariance()[n * (NParams + 1)]);
1560 } // SimplePolyFitterBase<>::FitParameterError()
1561 
1562 
1563 template <typename T, unsigned int D>
1565  -> FitParameters_t
1566 {
1567  FitMatrix_t Xmat = MakeMatrixX();
1568  FitParameters_t fit_params;
1569  for (unsigned int iParam = 0; iParam < NParams; ++iParam)
1570  fit_params[iParam] = Param(iParam, Xmat);
1571  return fit_params;
1572 } // SimplePolyFitterBase<>::FitParameters()
1573 
1574 
1575 template <typename T, unsigned int D>
1577  -> FitParameters_t
1578 {
1579  return FitParameterErrors(FitParameterCovariance());
1580 } // SimplePolyFitterBase<>::FitParameterErrors()
1581 
1582 
1583 template <typename T, unsigned int D>
1585  () const -> FitMatrix_t
1586 {
1587  FitMatrix_t Xmat = MakeMatrixX();
1588  Data_t det = Determinant(Xmat);
1589  if (!std::isnormal(det)) {
1590  throw std::range_error
1591  ("SimplePolyFitterBase::FitParameterCovariance(): determinant 0 while fitting");
1592  }
1593  return InvertMatrix(Xmat, det);
1594 } // SimplePolyFitterBase<>::FitParameterCovariance()
1595 
1596 
1597 template <typename T, unsigned int D>
1599  FitParameters_t& params,
1600  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1601 ) const {
1602 
1603  Xmat = MakeMatrixX();
1604  det = Determinant(Xmat);
1605  if (!std::isnormal(det)) {
1606  Smat.fill(Data_t(0));
1607  params.fill(Data_t(0));
1608  return false;
1609  }
1610  Smat = InvertMatrix(Xmat, det);
1611  params = FitParameters(Smat, det);
1612  return true;
1613 } // SimplePolyFitterBase<>::FillResults(params, matrices, determinant)
1614 
1615 
1616 template <typename T, unsigned int D>
1618  FitParameters_t& params, FitParameters_t& paramerrors,
1619  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1620 ) const {
1621 
1622  if (!this->FillResults(params, Xmat, det, Smat)) return false;
1623  paramerrors = ExtractParameterErrors(Smat);
1624  return true;
1625 } // SimplePolyFitterBase<>::FillResults(params, errors, matrices, determinant)
1626 
1627 
1628 template <typename T, unsigned int D>
1630  FitParameters_t& params, FitParameters_t& paramerrors
1631 ) const {
1632  // to compute the parameters, we need all the stuff;
1633  // we just keep it local and discard it in the end. Such a waste.
1634  FitMatrix_t Xmat, Smat;
1635  Data_t det;
1636  return FillResults(params, paramerrors, Xmat, det, Smat);
1637 } // SimplePolyFitterBase<>::FillResults(params, errors)
1638 
1639 
1640 template <typename T, unsigned int D>
1642  -> Data_t
1643 {
1644  FitParameters_t params = FitParameters();
1645  unsigned int iParam = NParams - 1; // point to last parameter (highest degree)
1646  Data_t v = params[iParam];
1647  while (iParam > 0) v = v * x + params[--iParam];
1648  return v;
1649 } // SimplePolyFitterBase<>::Evaluate()
1650 
1651 
1652 // --- protected methods follow ---
1653 template <typename T, unsigned int D>
1655  -> FitMatrix_t
1656 {
1657  FitMatrix_t Xmat;
1658  for (unsigned int i = 0; i < NParams; ++i) { // row
1659  for (unsigned int j = i; j < NParams; ++j) { // column
1660  Xmat[j * NParams + i] = Xmat[i * NParams + j] = Base_t::XN(i+j);
1661  } // for j
1662  } // for i
1663  return Xmat;
1664 } // SimplePolyFitterBase<>::MakeMatrixX()
1665 
1666 
1667 template <typename T, unsigned int D>
1669  -> FitParameters_t
1670 {
1671  FitParameters_t Ymat;
1672  for (unsigned int i = 0; i < NParams; ++i) Ymat[i] = Base_t::XNY(i);
1673  return Ymat;
1674 } // SimplePolyFitterBase<>::MakeMatrixY()
1675 
1676 
1677 template <typename T, unsigned int D>
1679  (FitMatrix_t const& Xmat) const
1680  -> FitParameters_t
1681 {
1682  FitParameters_t fit_params;
1683  for (unsigned int iParam = 0; iParam < NParams; ++iParam)
1684  fit_params[iParam] = Param(iParam, Xmat);
1685  return fit_params;
1686 } // SimplePolyFitterBase<>::FitParameters(FitMatrix_t)
1687 
1688 
1689 template <typename T, unsigned int D>
1691  (FitMatrix_t const& Smat, Data_t /* det */) const
1692  -> FitParameters_t
1693 {
1694  return MatrixProduct(Smat, MakeMatrixY());
1695 } // SimplePolyFitterBase<>::FitParameters(FitMatrix_t)
1696 
1697 
1698 template <typename T, unsigned int D>
1700  (unsigned int n, FitMatrix_t const& Xmat) const -> Data_t
1701 {
1702  if (n > Degree) return Data_t(0); // no such a degree, its coefficient is 0
1703 
1704  Data_t detXmat = Determinant(Xmat);
1705  if (!std::isnormal(detXmat)) {
1706  throw std::range_error
1707  ("SimplePolyFitterBase::Param(): Determinant 0 while fitting");
1708  }
1709  return Param(n, Xmat, detXmat);
1710 } // SimplePolyFitterBase<>::Param(unsigned int, FitMatrix_t)
1711 
1712 
1713 template <typename T, unsigned int D>
1715  (FitMatrix_t const& Smat)
1716  -> FitParameters_t
1717 {
1718  FitParameters_t fit_errors;
1719  for (unsigned int iParam = 0; iParam <= Degree; ++iParam)
1720  fit_errors[iParam] = std::sqrt(Smat[iParam * (NParams + 1)]);
1721  return fit_errors;
1722 } // SimplePolyFitterBase<>::FitParameterErrors(FitMatrix_t)
1723 
1724 
1725 template <typename T, unsigned int D>
1727  (unsigned int n, FitMatrix_t const& Xmat, Data_t detXmat) const -> Data_t
1728 {
1729  if (n > Degree) return Data_t(0); // no such a degree, its coefficient is 0
1730  // XYmat is as Xmat...
1731  FitMatrix_t XYmat(Xmat);
1732  // ... except that the N-th column is replaced with { sum x^i y }
1733  for (unsigned int i = 0; i < NParams; ++i)
1734  XYmat[i * NParams + n] = Base_t::XNY(i);
1735 
1736  return Determinant(XYmat) / detXmat;
1737 } // SimplePolyFitterBase<>::Param(unsigned int, FitMatrix_t, Data_t)
1738 
1739 
1740 template <typename T, unsigned int D>
1742 {
1743  // the generic implementation of ChiSquare from sums is complex enough that
1744  // I freaked out
1745  throw std::logic_error
1746  ("SimplePolyFitterBase::ChiSquare() not implemented for generic fit");
1747 } // SimplePolyFitterBase<>::ChiSquare()
1748 
1749 
1750 
1751 //******************************************************************************
1752 //*** LinearFit<>
1753 //***
1754 
1755 template <typename T>
1757 {
1758  FitParameters_t fit_params = this->FitParameters();
1759  const Data_t b = fit_params[0];
1760  const Data_t a = fit_params[1];
1761  return Y2() + sqr(a) * X2() + sqr(b) * I()
1762  + Data_t(2) * (a * b * X2() - a * XY() - b * Y());
1763 } // LinearFit<T>::ChiSquare()
1764 
1765 
1766 //******************************************************************************
1767 //*** QuadraticFit<>
1768 //***
1769 
1770 template <typename T>
1772 {
1773  FitParameters_t a = this->FitParameters();
1774  return Y2() - Data_t(2) * (a[0]*Y() + a[1]*XY() + a[2]*X2Y())
1775  + sqr(a[0])*I() + Data_t(2) * a[0] * ( a[1]*X() + a[2]*X2() )
1776  + sqr(a[1])*X2() + Data_t(2) * a[1] * ( a[2]*X3() )
1777  + sqr(a[2])*X4();
1778 } // QuadraticFit<T>::ChiSquare()
1779 
1780 
1781 //******************************************************************************
1782 //*** GaussianFit<>
1783 //***
1784 
1785 //
1786 // data interface
1787 //
1788 template <typename T>
1790  (Data_t x, Data_t y, Data_t sy /* = Data_t(1.0) */)
1791 {
1792  if (y <= Data_t(0)) return false; // ignore the non-positive values
1793  Value_t value = EncodeValue(Value_t(y, sy));
1794  return fitter.add(x, value.value(), value.error());
1795 } // GaussianFit<T>::add(Data_t, Data_t, Data_t)
1796 
1797 
1798 template <typename T>
1799 template <typename Iter, typename Pred>
1801  (Iter begin, Iter end, Pred extractor)
1802 {
1803  return fitter.add_without_uncertainty(begin, end, Encoder(extractor));
1804 } // GaussianFit<>::add_without_uncertainty(Iter, Iter, Pred)
1805 
1806 
1807 template <typename T>
1808 template <
1809  typename VIter, typename UIter,
1810  typename VPred, typename UPred
1811  >
1813  VIter begin_value, VIter end_value,
1814  UIter begin_uncertainty,
1815  VPred value_extractor,
1816  UPred uncertainty_extractor /* = UPred() */
1817  )
1818 {
1819  return add_with_uncertainty(
1820  begin_value, end_value, begin_uncertainty,
1821  Encoder(value_extractor, uncertainty_extractor)
1822  );
1823 } // GaussianFit<T>::add_with_uncertainty()
1824 
1825 
1826 template <typename T>
1827 template <typename Iter>
1829  (Iter begin, Iter end)
1830 {
1831  unsigned int old_n = N();
1832  std::for_each(begin, end, [this](auto p) { this->add(p); });
1833  return N() - old_n;
1834 } // GaussianFit<T>::add_with_uncertainty()
1835 
1836 
1837 //
1838 // fitting interface
1839 //
1840 template <typename T>
1842  return ConvertParameters(fitter.FitParameters());
1843 } // GaussianFit<>::FitParameters()
1844 
1845 
1846 template <typename T>
1848  FitParameters_t qpars, qparerrors;
1849  if (!FillResults(qpars, qparerrors)) {
1850  throw std::runtime_error
1851  ("GaussianFit::FitParameterErrors() yielded invalid results");
1852  }
1853  return qparerrors;
1854 } // GaussianFit<>::FitParameterErrors()
1855 
1856 
1857 template <typename T>
1859 {
1860  // we need to go through the whole chain to get the error matrix
1861  FitParameters_t params;
1862  FitMatrix_t Xmat;
1863  Data_t det;
1864  FitMatrix_t Smat;
1865  if (!FillResults(params, Xmat, det, Smat)) {
1866  throw std::runtime_error
1867  ("GaussianFit::FitParameterCovariance() yielded invalid results");
1868  }
1869  return Smat;
1870 } // SimplePolyFitterBase<>::FitParameterCovariance()
1871 
1872 
1873 template <typename T>
1875  (FitParameters_t& params, FitParameters_t& paramerrors) const
1876 {
1877  FitParameters_t qpars;
1878  FitMatrix_t qparerrmat;
1879  FitMatrix_t Xmat; // not used
1880  Data_t det; // not used
1881  if (!fitter.FillResults(qpars, Xmat, det, qparerrmat)) return false;
1882  ConvertParametersAndErrors(qpars, qparerrmat, params, paramerrors);
1883  return isValid(params, qpars);
1884 } // GaussianFit<>::FillResults()
1885 
1886 
1887 template <typename T>
1889  FitParameters_t& params, FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1890 ) const {
1891  FitParameters_t qpars;
1892  FitMatrix_t qparerrmat;
1893  if (!fitter.FillResults(qpars, Xmat, det, qparerrmat)) return false;
1894  ConvertParametersAndErrorMatrix(qpars, qparerrmat, params, Smat);
1895  return isValid(params, qpars);
1896 } // GaussianFit::FillResults()
1897 
1898 
1899 template <typename T>
1901  FitParameters_t& params, FitParameters_t& paramerrors,
1902  FitMatrix_t& Xmat, Data_t& det, FitMatrix_t& Smat
1903 ) const {
1904  if (!FillResults(params, Xmat, det, Smat)) return false;
1905  paramerrors = fitter.ExtractParameterErrors(Smat);
1906  return true;
1907 } // GaussianFit::FillResults()
1908 
1909 
1910 template <typename T>
1912  -> Data_t
1913 {
1914  Data_t z = (x - params[1]) / params[2];
1915  return params[0] * std::exp(-0.5*sqr(z));
1916 } // GaussianFit<>::Evaluate()
1917 
1918 
1919 template <typename T>
1921  -> FitParameters_t
1922 {
1923  FitParameters_t params;
1924 
1925 
1926  Data_t sigma2 = -0.5 / qpars[2]; // sigma^2 = -1 / (2 a2)
1927  params[2] = std::sqrt(sigma2); // sigma
1928 
1929  params[1] = sigma2 * qpars[1]; // mean = sigma2 a1
1930 
1931  params[0] = std::exp(qpars[0] - 0.25 * sqr(qpars[1])/qpars[2]);
1932 
1933  return params;
1934 } // GaussianFit<>::ConvertParameters()
1935 
1936 
1937 template <typename T>
1939  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1940  FitParameters_t& params, FitParameters_t& paramvariances
1941  )
1942 {
1943  params = ConvertParameters(qpars);
1944 
1945  FitParameters_t const& a = qpars;
1946  Data_t const& A = params[0];
1947  Data_t const& mu = params[1];
1948  Data_t const& sigma = params[2];
1949 
1950  // error on sigma
1951  paramvariances[2] = qparerrmat[3 * 2 + 2] / sqr(cube(sigma));
1952 
1953  // error on mu
1954  paramvariances[1] = sqr(mu * (
1955  + qparerrmat[3 * 1 + 1] / sqr(a[1])
1956  - 2.*qparerrmat[3 * 2 + 1] / (a[1]*a[2])
1957  + qparerrmat[3 * 2 + 2] / sqr(a[2])
1958  ));
1959 
1960  // error on A
1961  paramvariances[0] = sqr(A * (
1962  + qparerrmat[3 * 0 + 0]
1963  + 2.*qparerrmat[3 * 0 + 1] * mu
1964  +( qparerrmat[3 * 1 + 1]
1965  + 2.*qparerrmat[3 * 0 + 2]) * sqr(mu)
1966  + 2.*qparerrmat[3 * 1 + 2] * cube(mu)
1967  + qparerrmat[3 * 2 + 2] * sqr(sqr(mu))
1968  ));
1969 
1970 } // GaussianFit<>::ConvertParametersAndVariances()
1971 
1972 
1973 template <typename T>
1975  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1976  FitParameters_t& params, FitParameters_t& paramerrors
1977  )
1978 {
1979  ConvertParametersAndVariances(qpars, qparerrmat, params, paramerrors);
1980  // paramerrors actually stores the square of the error; fix it:
1981  for (Data_t& paramerror: paramerrors) paramerror = std::sqrt(paramerror);
1982 } // GaussianFit<>::ConvertParametersAndErrors()
1983 
1984 
1985 template <typename T>
1987  FitParameters_t const& qpars, FitMatrix_t const& qparerrmat,
1988  FitParameters_t& params, FitMatrix_t& Smat
1989  )
1990 {
1991  FitParameters_t paramvariances;
1992  ConvertParametersAndVariances(qpars, qparerrmat, params, paramvariances);
1993 
1994  // let's call things with their names
1995  FitParameters_t const& a = qpars;
1996  Data_t const& A = params[0];
1997  Data_t const& mu = params[1];
1998  Data_t const& sigma = params[2];
1999 
2000  // variance on sigma
2001  Smat[3 * 2 + 2] = paramvariances[2];
2002 
2003  // variance on mu
2004  Smat[3 * 1 + 1] = paramvariances[1];
2005 
2006  // variance on A
2007  Smat[3 * 0 + 0] = paramvariances[0];
2008 
2009  // covariance on sigma and mu
2010  Smat[3 * 1 + 2] = Smat[3 * 2 + 1]
2011  = (qparerrmat[3 * 1 + 2] + 2 * mu * qparerrmat[3 * 2 + 2]) / sigma;
2012 
2013  // this is the sum of the derivatives of A vs. all a parameters, each one
2014  // multiplied by the covariance of that parameter with a2
2015  const Data_t dA_dak_cov_aka2 = A * (
2016  qparerrmat[3 * 0 + 2]
2017  + qparerrmat[3 * 1 + 2] * mu
2018  + qparerrmat[3 * 2 + 2] * sqr(mu)
2019  );
2020  // covariance on A and sigma
2021  Smat[3 * 0 + 2] = Smat[3 * 2 + 0]
2022  = dA_dak_cov_aka2 / cube(sigma);
2023 
2024  // this other is the same as dA_dak_cov_aka2, but for a1
2025  const Data_t dA_dak_cov_aka1 = A * (
2026  qparerrmat[3 * 0 + 1]
2027  + qparerrmat[3 * 1 + 1] * mu
2028  + qparerrmat[3 * 2 + 1] * sqr(mu)
2029  );
2030 
2031  // covariance on A and mu
2032  Smat[3 * 0 + 1] = Smat[3 * 1 + 0] = mu *
2033  (dA_dak_cov_aka1 / a[1] - dA_dak_cov_aka2 / a[2]);
2034 
2035 } // GaussianFit<>::ConvertParametersAndErrors()
2036 
2037 
2038 template <typename T>
2040  (FitParameters_t const& params, FitParameters_t const& qpars)
2041 {
2042  return (qpars[2] < Data_t(0)) && (params[0] >= Data_t(0));
2043 } // GaussianFit<>::isValid(FitParameters_t)
2044 
2045 
2046 //******************************************************************************
2047 
2048 
2049 #endif // SIMPLEFITS_H
static constexpr Data_t cube(Data_t v)
Returns the cube of the specified data value.
Definition: SimpleFits.h:610
Weight_t Weights() const
Returns the sum of the weights.
Definition: StatCollector.h:62
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:135
Float_t s
Definition: plot.C:23
static constexpr unsigned int NParams
Definition: SimpleFits.h:74
virtual Data_t Evaluate(Data_t x) const override
Evaluates the fitted function at the specified point.
Definition: SimpleFits.h:1641
Data_t X4() const
Aliases.
Definition: SimpleFits.h:991
bool add(MeasurementAndUncertainty_t value)
Definition: SimpleFits.h:372
int N() const
Returns the number of entries added.
Definition: StatCollector.h:59
Data_t InterceptError() const
Returns the error on intercept of the fit.
Definition: SimpleFits.h:891
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
unsigned int add_with_uncertainty(Iter begin, Iter end)
Definition: SimpleFits.h:411
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:1477
void add_without_uncertainty(Iter begin, Iter end)
Definition: SimpleFits.h:377
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Clears all the input statistics.
Definition: SimpleFits.h:1790
typename Base_t::Data_t Data_t
type of the data
Definition: SimpleFits.h:1026
unsigned int add_with_uncertainty(VIter begin_value, VIter end_value, UIter begin_uncertainty, VPred value_extractor, UPred uncertainty_extractor=UPred())
Definition: SimpleFits.h:397
Data_t XN(unsigned int n) const
Returns the weighted sum of x^n.
Definition: SimpleFits.h:447
constexpr Data_t error() const
Definition: SimpleFits.h:1256
virtual Data_t FitParameterError(unsigned int n) const
Returns the error on parameter n of the fit result.
Definition: SimpleFits.h:533
Data_t XN(unsigned int n) const
Returns the weighted sum of x^n.
Definition: SimpleFits.h:287
virtual FitParameters_t FitParameterErrors() const override
Computes and returns all the parameter errors of the fit result.
Definition: SimpleFits.h:1847
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:351
Weight_t AverageWeight() const
Returns the arithmetic average of the weights.
Double_t z
Definition: plot.C:279
Float_t Y
Definition: plot.C:39
unsigned int add_with_uncertainty(Cont cont)
Clears all the input statistics.
Definition: SimpleFits.h:1092
std::array< Data_t, sqr(NParams)> FitMatrix_t
Definition: SimpleFits.h:971
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
Definition: SimpleFits.h:731
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:1812
EncodeExtractor(VPred &vpred, UPred &upred)
Definition: SimpleFits.h:1316
static Data_t UncertaintyToWeight(Data_t s)
Transforms an uncertainty into a weight ( )
Definition: SimpleFits.h:317
< type of value and error
Definition: SimpleFits.h:1248
static constexpr Data_t sqr(Data_t v)
Returns the square of the specified data value.
Definition: SimpleFits.h:607
STL namespace.
WeightTracker< Data_t > y
accumulator for y
Definition: SimpleFits.h:329
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:1938
Data_t Y2() const
Aliases.
Definition: SimpleFits.h:995
virtual Data_t Param(unsigned int n, FitMatrix_t const &Xmat) const
Computes a single fit parameter using the given information.
Definition: SimpleFits.h:1700
virtual Data_t Evaluate(Data_t x) const override
Evaluates the fitted function at the specified point.
Definition: SimpleFits.h:1225
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Clears all the input statistics.
Definition: SimpleFits.h:1050
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:1272
Class providing data collection for the simple polynomial fitters.
Definition: SimpleFits.h:37
typename Fitter_t::FitMatrix_t FitMatrix_t
Definition: SimpleFits.h:1036
static constexpr V sqr(V const &v)
Returns the square of the specified value.
Definition: SimpleFits.h:283
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1771
void add(Weight_t weight)
Adds the specified weight to the statistics.
Definition: StatCollector.h:53
std::tuple< Data_t, Data_t > Base_t
Definition: SimpleFits.h:1249
Classes gathering simple statistics.
std::array< Data_t, sqr(NParams)> FitMatrix_t
Definition: SimpleFits.h:867
DataTracker< 1, Data_t > y2
accumulator for y2
Definition: SimpleFits.h:330
virtual FitParameters_t FitParameters() const override
Computes and returns all the parameters of the fit result.
Definition: SimpleFits.h:1841
int N() const
Returns the number of (valid) points added.
Definition: SimpleFits.h:1100
Double_t X2
Definition: plot.C:266
Value_t(Data_t v, Data_t e)
Definition: SimpleFits.h:1251
bool add(MeasurementAndUncertainty_t value)
Adds one entry with specified x, y and uncertainty.
Definition: SimpleFits.h:118
Performs a linear regression of data.
Definition: SimpleFits.h:849
static Measurement_t EncodeValue(Measurement_t const &meas)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1289
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:450
virtual FitMatrix_t MakeMatrixX() const
Fills and returns the matrix of x^n sum coefficients ( { x^(i+j) } )
Definition: SimpleFits.h:1654
virtual FitMatrix_t FitParameterCovariance() const override
Computes and returns all the covariance matrix of the fit result.
Definition: SimpleFits.h:1858
typename Collector_t::MeasurementAndUncertainty_t MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:358
UPred & error_extractor
uncertainty extractor
Definition: SimpleFits.h:1333
Data_t XNY() const
Returns the weighted sum of x^N y.
Definition: SimpleFits.h:302
virtual FitParameters_t FitParameterErrors() const override
Computes and returns all the parameter errors of the fit result.
Definition: SimpleFits.h:1576
void clear()
Resets the count.
Definition: StatCollector.h:56
typename Base_t::Data_t Data_t
type of the data
Definition: SimpleFits.h:653
Classes with hard-coded (hence "fast") matrix math.
T sqr(T v)
Data_t Slope() const
Returns the slope of the fit.
Definition: SimpleFits.h:884
void add_without_uncertainty(Cont cont)
Clears all the input statistics.
Definition: SimpleFits.h:1072
static Value_t DecodeValue(Value_t const &value)
Converts a value from the quadratic fit into a proper value.
Definition: SimpleFits.h:1282
virtual bool FillResults(FitParameters_t &params, FitMatrix_t &Xmat, Data_t &det, FitMatrix_t &Smat) const override
Fills the specified parameters.
Definition: SimpleFits.h:1888
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1756
virtual FitMatrix_t InvertMatrix(FitMatrix_t const &mat) const
Computes the inverse of a matrix.
Definition: SimpleFits.h:624
unsigned int add_with_uncertainty(Cont cont)
Adds measurements with uncertainties from a container.
Definition: SimpleFits.h:254
static FitParameters_t ConvertParameters(FitParameters_t const &qpars)
Converts the specified quadratic fit parameters into Gaussian.
Definition: SimpleFits.h:1920
Provides "fast" matrix operations.
constexpr Data_t value() const
Definition: SimpleFits.h:1255
WeightTracker< Data_t > s2
accumulator for uncertainty
Definition: SimpleFits.h:327
Data_t InterceptSlopeCovariance() const
Returns the covariance between intercept and slope of the fit.
Definition: SimpleFits.h:905
Data_t Intercept() const
Returns the intercept of the fit.
Definition: SimpleFits.h:877
Data_t X2() const
Aliases.
Definition: SimpleFits.h:922
virtual FitMatrix_t FitParameterCovariance() const override
Computes and returns all the covariance matrix of the fit result.
Definition: SimpleFits.h:1585
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
DataTracker< Degree *2, Data_t > x
accumulator for variable x^k
Definition: SimpleFits.h:328
static T Sum(WeightTracker< T > const &, DataTracker< Power, T > const &sums)
Definition: SimpleFits.h:59
A unary functor returning its own argument (any type)
Definition: StatCollector.h:33
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:970
void add_without_uncertainty(Cont cont, Pred extractor)
Definition: SimpleFits.h:385
void add_without_uncertainty(Cont cont, Pred extractor)
Clears all the input statistics.
Definition: SimpleFits.h:1068
bool FillResults(FitParameters_t &params, FitMatrix_t &Xmat, Data_t &det, FitMatrix_t &Smat) const override
Fills the specified parameters.
Definition: SimpleFits.h:1598
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:1974
typename Interface_t::FitParameters_t FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:656
static Data_t WeightToUncertainty(Data_t w)
Transforms a weight back to an uncertainty ( )
Definition: SimpleFits.h:321
int N() const
Returns the number of entries added.
Definition: SimpleFits.h:266
void add_without_uncertainty(Cont cont, Pred extractor)
Adds all measurements from a container, with no uncertainty.
Definition: SimpleFits.h:169
void PrintStats(Stream &out) const
Prints the collected statistics into a stream.
Definition: SimpleFits.h:436
void clear()
Clears all the statistics.
Definition: SimpleFits.h:421
Data_t X() const
Aliases.
Definition: SimpleFits.h:921
Float_t mat
Definition: plot.C:40
void add_without_uncertainty(Iter begin, Iter end)
Clears all the input statistics.
Definition: SimpleFits.h:1061
"Fast" Gaussian fit
Definition: SimpleFits.h:1018
Class tracking sums of variables up to a specified power.
Definition: StatCollector.h:93
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
Definition: SimpleFits.h:1170
VPred & value_extractor
value extractor
Definition: SimpleFits.h:1332
Data_t SlopeError() const
Returns the error in slope of the fit.
Definition: SimpleFits.h:898
virtual Data_t FitParameterError(unsigned int n) const override
Returns the error on parameter n of the fit result.
Definition: SimpleFits.h:1556
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Definition: SimpleFits.h:369
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:866
Value_t(MeasurementAndUncertainty_t meas)
Definition: SimpleFits.h:1252
Data_t AverageUncertainty() const
Returns an average of the uncertainties.
Definition: SimpleFits.h:277
static Value_t EncodeValue(Value_t const &value)
Converts a value and error into a proper input for the quadratic fit.
Definition: SimpleFits.h:1277
Data_t XNY(unsigned int n) const
Returns the weighted sum of x^n y.
Definition: SimpleFits.h:291
Performs a second-degree fit of data.
Definition: SimpleFits.h:953
typename Interface_t::FitMatrix_t FitMatrix_t
type of matrix for covariance (a std::array)
Definition: SimpleFits.h:659
void clear()
Resets the count.
typename MatrixOps::Matrix_t FitMatrix_t
type of matrix for covariance (a std::array)
Definition: SimpleFits.h:472
Data_t Y() const
Aliases.
Definition: SimpleFits.h:992
void Print(Stream &out) const
Prints the statistics into a stream.
Definition: SimpleFits.h:1519
static constexpr unsigned int Power
Definition: StatCollector.h:95
Fitter_t fitter
the actual fitter and data holder
Definition: SimpleFits.h:1242
virtual FitParameters_t FitParameters() const override
Computes and returns all the parameters of the fit result.
Definition: SimpleFits.h:1564
static constexpr V sqr(V const &v)
Returns the square of the specified value.
Definition: SimpleFits.h:441
std::tuple< Data_t, Data_t > Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:79
static FitParameters_t ExtractParameterErrors(FitMatrix_t const &Smat)
Extracts parameter errors from diagonal of the covarriance matrix.
Definition: SimpleFits.h:1715
Data_t X2Y() const
Aliases.
Definition: SimpleFits.h:994
double weight
Definition: plottest35.C:25
virtual Fitter_t const & Fitter() const
Returns the internal fitter (mostly for debugging)
Definition: SimpleFits.h:1230
std::string value(boost::any const &)
DataTracker< Degree, Data_t > xy
accumulator for variable xy
Definition: SimpleFits.h:331
Base class providing virtual fitting interface for polynomial fitters.
Definition: SimpleFits.h:637
bool add(MeasurementAndUncertainty_t value)
Clears all the input statistics.
Definition: SimpleFits.h:1053
LArSoft-specific namespace.
Base class providing data collection for the simple polynomial fitters.
Definition: SimpleFits.h:344
typename Fitter_t::Measurement_t Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:1029
Data_t XY() const
Aliases.
Definition: SimpleFits.h:924
Simple fitter abstract interface.
Definition: SimpleFits.h:458
typename Fitter_t::MeasurementAndUncertainty_t MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:1033
bool add(Measurement_t value, Data_t sy=Data_t(1.0))
Adds one entry with specified x, y and uncertainty.
Definition: SimpleFits.h:108
virtual FitParameters_t MakeMatrixY() const
Fills and returns the matrix (vector) of x^n y sum coefficients.
Definition: SimpleFits.h:1668
void clear()
Clears all the statistics.
Definition: SimpleFits.h:1509
static EncodeExtractor< VPred, UPred > Encoder(VPred &vpred, UPred &upred)
Definition: SimpleFits.h:1367
static constexpr unsigned int Degree
Degree of the fit.
Definition: SimpleFits.h:73
virtual Data_t Determinant(FitMatrix_t const &mat) const
Computes the determinant of a matrix.
Definition: SimpleFits.h:615
void add_without_uncertainty(Cont cont)
Adds all measurements from a container, with no uncertainty.
Definition: SimpleFits.h:183
void clear()
Clears all the input statistics.
Definition: SimpleFits.h:1097
virtual Data_t ChiSquare() const override
Returns the of the fit.
Definition: SimpleFits.h:1741
unsigned int add_with_uncertainty(Cont cont)
Definition: SimpleFits.h:415
Data_t XY() const
Aliases.
Definition: SimpleFits.h:993
virtual bool isValid() const override
Returns if the fit has valid results.
Definition: SimpleFits.h:1540
Char_t n[5]
void add_without_uncertainty(Iter begin, Iter end, Pred extractor)
Definition: SimpleFits.h:381
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
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:1986
Data_t X() const
Aliases.
Definition: SimpleFits.h:988
typename Collector_t::Measurement_t Measurement_t
type of measurement without uncertainty
Definition: SimpleFits.h:354
virtual Data_t ChiSquare() const override
Returns the of the original fit.
Definition: SimpleFits.h:1161
std::array< Data_t, NParams > FitParameters_t
type of set of fit parameters
Definition: SimpleFits.h:469
typename Fitter_t::FitParameters_t FitParameters_t
Definition: SimpleFits.h:1035
Data_t Y() const
Aliases.
Definition: SimpleFits.h:923
static Data_t DecodeValue(Data_t value)
Converts a value from the quadratic fit into a proper value.
Definition: SimpleFits.h:1268
static Data_t EncodeValue(Data_t value)
Definition: SimpleFits.h:1265
Float_t e
Definition: plot.C:34
virtual Data_t FitParameter(unsigned int n) const
Returns the parameter n of the fit result.
Definition: SimpleFits.h:524
Float_t X
Definition: plot.C:39
Data_t X2() const
Aliases.
Definition: SimpleFits.h:989
Float_t w
Definition: plot.C:23
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Definition: SimpleFits.h:366
static EncodeExtractor< Pred > Encoder(Pred &pred)
Definition: SimpleFits.h:1364
Data_t X3() const
Aliases.
Definition: SimpleFits.h:990
Collector_t stats
statistics collected from fit data input
Definition: SimpleFits.h:444
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:1446
virtual Data_t FitParameter(unsigned int n) const override
Returns the parameter n of the fit result.
Definition: SimpleFits.h:1548
void PrintStats(Stream &out) const
Prints the collected statistics into a stream.
Definition: SimpleFits.h:1105
Data_t Y2() const
Aliases.
Definition: SimpleFits.h:925
Data_t Y2() const
Returns the weighted sum of y^2.
Definition: SimpleFits.h:307
std::tuple< Data_t, Data_t, Data_t > MeasurementAndUncertainty_t
type of measurement with uncertainty
Definition: SimpleFits.h:82
virtual bool isValid() const override
Returns if the fit has valid results.
Definition: SimpleFits.h:1122