GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TLMFitter.h
Go to the documentation of this file.
1// Author: Ryan Dunlop 11/15
2
3#ifndef TLMFITTER_H
4#define TLMFITTER_H
5
6/** \addtogroup Fitting Fitting & Analysis
7 * @{
8 */
9
10#include <complex>
11#include <iostream>
12#include <fstream>
13
14#include "Rtypes.h"
15#include "TObject.h"
16#include "TH1.h"
17#include "TF1.h"
18
19/////////////////////////////////////////////////////////////////
20///
21/// \class TLMFitter
22///
23/// This Class can be used to fit weighted-poisson distributed
24/// data. It is originally from Numerical recipes, and adapted
25/// by G.F Grinyer. It is based on the non-linear
26/// Levenberg-Marquardt minimization algorithm.
27///
28/////////////////////////////////////////////////////////////////
29
30// Vector Types
31
32// Overloaded complex operations to handle mixed float and double
33// This takes care of e.g. 1.0/z, z complex<float>
34
35template <class T>
36class NRVec {
37private:
38 int nn; // size of array. upper index is nn-1
39 T* v;
40
41public:
42 NRVec();
43 explicit NRVec(int n); // Zero-based array
44 NRVec(const T& a, int n); // initialize to constant value
45 NRVec(const T* a, int n); // Initialize to array
46 NRVec(const NRVec& rhs); // Copy constructor
47 NRVec(NRVec&& rhs) noexcept = default; // Move constructor
48 NRVec& operator=(const NRVec& rhs); // copy assignment
49 NRVec& operator=(NRVec&& rhs) noexcept = default; // move assignment
50 NRVec& operator=(const T& a); // assign a to every element
51 inline T& operator[](int i); // i'th element
52 inline const T& operator[](int i) const;
53 inline int size() const;
54 ~NRVec();
55};
56
57template <class T>
58NRVec<T>::NRVec() : nn(0), v(0)
59{
60}
61
62template <class T>
63NRVec<T>::NRVec(int n) : nn(n), v(new T[n]())
64{
65 for(int i = 0; i < n; ++i) {
66 v[i] = 0.0;
67 }
68}
69
70template <class T>
71NRVec<T>::NRVec(const T& a, int n) : nn(n), v(new T[n]())
72{
73 for(int i = 0; i < n; i++) {
74 v[i] = a;
75 }
76}
77
78template <class T>
79NRVec<T>::NRVec(const T* a, int n) : nn(n), v(new T[n]())
80{
81 for(int i = 0; i < n; i++) {
82 v[i] = *a++;
83 }
84}
85
86template <class T>
87NRVec<T>::NRVec(const NRVec<T>& rhs) : nn(rhs.nn), v(new T[nn]())
88{
89 for(int i = 0; i < nn; i++) {
90 v[i] = rhs[i];
91 }
92}
93
94template <class T>
96// postcondition: normal assignment via copying has been performed;
97// if vector and rhs were different sizes, vector
98// has been resized to match the size of rhs
99{
100 if(this != &rhs) {
101 if(nn != rhs.nn) {
102 delete[] v;
103 nn = rhs.nn;
104 v = new T[nn];
105 }
106 for(int i = 0; i < nn; i++) {
107 v[i] = rhs[i];
108 }
109 }
110 return *this;
111}
112
113template <class T>
114NRVec<T>& NRVec<T>::operator=(const T& a) // assign a to every element
115{
116 for(int i = 0; i < nn; i++) {
117 v[i] = a;
118 }
119 return *this;
120}
121
122template <class T>
123inline T& NRVec<T>::operator[](const int i) // subscripting
124{
125 return v[i];
126}
127
128template <class T>
129inline const T& NRVec<T>::operator[](const int i) const // subscripting
130{
131 return v[i];
132}
133
134template <class T>
135inline int NRVec<T>::size() const
136{
137 return nn;
138}
139
140template <class T>
142{
143 if(v != nullptr) {
144 delete[] (v);
145 }
146}
147
148template <class T>
149class NRMat {
150private:
151 int nn;
152 int mm;
153 T** v;
154
155public:
156 NRMat();
157 NRMat(int n, int m); // Zero-based array
158 NRMat(const T& a, int n, int m); // Initialize to constant
159 NRMat(const T* a, int n, int m); // Initialize to array
160 NRMat(const NRMat& rhs); // Copy constructor
161 NRMat(NRMat&& rhs) noexcept = default; // Move constructor
162 NRMat& operator=(const NRMat& rhs); // copy assignment
163 NRMat& operator=(NRMat&& rhs) noexcept = default; // move assignment
164 NRMat& operator=(const T& a); // assign a to every element
165 inline T* operator[](int i); // subscripting: pointer to row i
166 inline const T* operator[](int i) const;
167 inline int nrows() const;
168 inline int ncols() const;
169 ~NRMat();
170};
171
172template <class T>
173NRMat<T>::NRMat() : nn(0), mm(0), v(0)
174{
175}
176
177template <class T>
178NRMat<T>::NRMat(int n, int m) : nn(n), mm(m), v(new T*[n]())
179{
180 v[0] = new T[m * n]();
181 for(int i = 1; i < n; i++) {
182 v[i] = v[i - 1] + m;
183 }
184
185 for(int i = 0; i < n; ++i) {
186 for(int j = 0; j < m; ++j) {
187 v[i][j] = 0.0;
188 }
189 }
190}
191
192template <class T>
193NRMat<T>::NRMat(const T& a, int n, int m) : nn(n), mm(m), v(new T*[n]())
194{
195 v[0] = new T[m * n]();
196 for(int i = 1; i < n; i++) {
197 v[i] = v[i - 1] + m;
198 }
199 for(int i = 0; i < n; i++) {
200 for(int j = 0; j < m; j++) {
201 v[i][j] = a;
202 }
203 }
204}
205
206template <class T>
207NRMat<T>::NRMat(const T* a, int n, int m) : nn(n), mm(m), v(new T*[n]())
208{
209 v[0] = new T[m * n]();
210 for(int i = 1; i < n; i++) {
211 v[i] = v[i - 1] + m;
212 }
213 for(int i = 0; i < n; i++) {
214 for(int j = 0; j < m; j++) {
215 v[i][j] = *a++;
216 }
217 }
218}
219
220template <class T>
221NRMat<T>::NRMat(const NRMat& rhs) : nn(rhs.nn), mm(rhs.mm), v(new T*[nn]())
222{
223 v[0] = new T[mm * nn]();
224 for(int i = 1; i < nn; i++) {
225 v[i] = v[i - 1] + mm;
226 }
227 for(int i = 0; i < nn; i++) {
228 for(int j = 0; j < mm; j++) {
229 v[i][j] = rhs[i][j];
230 }
231 }
232}
233
234template <class T>
236// postcondition: normal assignment via copying has been performed;
237// if matrix and rhs were different sizes, matrix
238// has been resized to match the size of rhs
239{
240 if(this != &rhs) {
241 if(nn != rhs.nn || mm != rhs.mm) {
242 delete[] v[0];
243 delete[] v;
244 nn = rhs.nn;
245 mm = rhs.mm;
246 v = new T*[nn];
247 v[0] = new T[mm * nn];
248 }
249 for(int i = 1; i < nn; i++) {
250 v[i] = v[i - 1] + mm;
251 }
252 for(int i = 0; i < nn; i++) {
253 for(int j = 0; j < mm; j++) {
254 v[i][j] = rhs[i][j];
255 }
256 }
257 }
258 return *this;
259}
260
261template <class T>
262NRMat<T>& NRMat<T>::operator=(const T& a) // assign a to every element
263{
264 for(int i = 0; i < nn; i++) {
265 for(int j = 0; j < mm; j++) {
266 v[i][j] = a;
267 }
268 }
269 return *this;
270}
271
272template <class T>
273inline T* NRMat<T>::operator[](const int i) // subscripting: pointer to row i
274{
275 return v[i];
276}
277
278template <class T>
279inline const T* NRMat<T>::operator[](const int i) const
280{
281 return v[i];
282}
283
284template <class T>
285inline int NRMat<T>::nrows() const
286{
287 return nn;
288}
289
290template <class T>
291inline int NRMat<T>::ncols() const
292{
293 return mm;
294}
295
296template <class T>
298{
299 if(v != nullptr) {
300 delete[] (v[0]);
301 delete[] (v);
302 }
303}
304
305template <class T>
306class NRMat3d {
307private:
308 int nn;
309 int mm;
310 int kk;
311 T*** v;
312
313public:
314 NRMat3d();
315 NRMat3d(int n, int m, int k);
316 inline T** operator[](int i); // subscripting: pointer to row i
317 inline const T* const* operator[](int i) const;
318 inline int dim1() const;
319 inline int dim2() const;
320 inline int dim3() const;
321 NRMat3d(const NRMat3d&) = default;
322 NRMat3d(NRMat3d&&) noexcept = default;
323 NRMat3d& operator=(const NRMat3d&) = default;
324 NRMat3d& operator=(NRMat3d&&) noexcept = default;
325 ~NRMat3d();
326};
327
328template <class T>
329NRMat3d<T>::NRMat3d() : nn(0), mm(0), kk(0), v(0)
330{
331}
332
333template <class T>
334NRMat3d<T>::NRMat3d(int n, int m, int k) : nn(n), mm(m), kk(k), v(new T**[n])
335{
336 v[0] = new T*[n * m];
337 v[0][0] = new T[n * m * k];
338 for(int j = 1; j < m; j++) {
339 v[0][j] = v[0][j - 1] + k;
340 }
341 for(int i = 1; i < n; i++) {
342 v[i] = v[i - 1] + m;
343 v[i][0] = v[i - 1][0] + m * k;
344 for(int j = 1; j < m; j++) {
345 v[i][j] = v[i][j - 1] + k;
346 }
347 }
348}
349
350template <class T>
351inline T** NRMat3d<T>::operator[](const int i) // subscripting: pointer to row i
352{
353 return v[i];
354}
355
356template <class T>
357inline const T* const* NRMat3d<T>::operator[](const int i) const
358{
359 return v[i];
360}
361
362template <class T>
363inline int NRMat3d<T>::dim1() const
364{
365 return nn;
366}
367
368template <class T>
369inline int NRMat3d<T>::dim2() const
370{
371 return mm;
372}
373
374template <class T>
375inline int NRMat3d<T>::dim3() const
376{
377 return kk;
378}
379
380template <class T>
382{
383 if(v != 0) {
384 delete[] (v[0][0]);
385 delete[] (v[0]);
386 delete[] (v);
387 }
388}
389
394
396using Vec_I_CHR = const NRVec<char>;
399
404
406using Vec_I_INT = const NRVec<int>;
409
414
419
424
426using Vec_I_SP = const NRVec<float>;
429
434
439
444
445// Matrix Types
446
451
453using Mat_I_CHR = const NRMat<char>;
456
461
463using Mat_I_INT = const NRMat<int>;
466
471
476
481
483using Mat_I_SP = const NRMat<float>;
486
491
496
501
502// 3D Matrix Types
503
508
509// Miscellaneous Types
510
514
515template <class T>
516inline T SQR(const T a)
517{
518 return a * a;
519}
520
521template <class T>
522inline T MAX(const T& a, const T& b)
523{
524 return b > a ? (b) : (a);
525}
526
527inline float MAX(const double& a, const float& b)
528{
529 return b > a ? (b) : static_cast<float>(a);
530}
531
532inline float MAX(const float& a, const double& b)
533{
534 return b > a ? static_cast<float>(b) : (a);
535}
536
537template <class T>
538inline T SIGN(const T& a, const T& b)
539{
540 if(b >= 0) {
541 return (a >= 0 ? a : -a);
542 }
543 return (a >= 0 ? -a : a);
544}
545
546inline float SIGN(const float& a, const double& b)
547{
548 if(b >= 0) {
549 return (a >= 0 ? a : -a);
550 }
551 return (a >= 0 ? -a : a);
552}
553
554inline float SIGN(const double& a, const float& b)
555{
556 if(b >= 0) {
557 return static_cast<float>(a >= 0 ? a : -a);
558 }
559 return static_cast<float>(a >= 0 ? -a : a);
560}
561
562template <class T>
563inline void SWAP(T& a, T& b)
564{
565 T dum = a;
566 a = b;
567 b = dum;
568}
569
570inline std::complex<float> operator+(const double& a, const std::complex<float>& b)
571{
572 return static_cast<float>(a) + b;
573}
574
575inline std::complex<float> operator+(const std::complex<float>& a, const double& b)
576{
577 return a + static_cast<float>(b);
578}
579
580inline std::complex<float> operator-(const double& a, const std::complex<float>& b)
581{
582 return static_cast<float>(a) - b;
583}
584
585inline std::complex<float> operator-(const std::complex<float>& a, const double& b)
586{
587 return a - static_cast<float>(b);
588}
589
590inline std::complex<float> operator*(const double& a, const std::complex<float>& b)
591{
592 return static_cast<float>(a) * b;
593}
594
595inline std::complex<float> operator*(const std::complex<float>& a, const double& b)
596{
597 return a * static_cast<float>(b);
598}
599
600inline std::complex<float> operator/(const double& a, const std::complex<float>& b)
601{
602 return static_cast<float>(a) / b;
603}
604
605inline std::complex<float> operator/(const std::complex<float>& a, const double& b)
606{
607 return a / static_cast<float>(b);
608}
609
610class TLMFitter : public TObject {
611public:
612 TLMFitter() = default;
613 TLMFitter(const TLMFitter&) = default;
614 TLMFitter(TLMFitter&&) noexcept = default;
615 TLMFitter& operator=(const TLMFitter&) = default;
616 TLMFitter& operator=(TLMFitter&&) noexcept = default;
617 ~TLMFitter() = default;
618
619private:
621 TH1* fHist{nullptr};
622 TF1* fFunction{nullptr};
624 int fRangeMin{0};
625 int fRangeMax{0};
626
627public:
628 template <class T>
629 class NRVec;
630 template <class T>
631 class NRMat;
632 template <class T>
633 class NRMat3d;
634
635 void Fit(TH1* hist, TF1* func);
636
637protected:
638 void SetFitterRange(int min, int max)
639 {
640 fRangeMin = min;
641 fRangeMax = max;
642 }
643
644 void nrerror(const std::string& error_text)
645 // Numerical Recipes standard error handler
646 {
647 std::cerr << "Numerical Recipes run-time error..." << std::endl;
648 std::cerr << error_text << std::endl;
649 std::cerr << "...now exiting to system..." << std::endl;
650 exit(1);
651 }
652
653 void funcs(const double& x, Vec_IO_double& a, double& y, Vec_O_double& dyda);
655 Mat_O_double& alpha, double& chisq, Vec_I_double& W, double& alamda);
656
658 Vec_O_double& beta, double& chisq, Vec_I_double& W, double& chisqexp);
660 void covsrt(Mat_IO_double& covar, Vec_I_BOOL& ia, int mfit);
662 Vec_double& dyda, int chisqnumber, const double& bin_width, Vec_double& yfit, const int& bin);
663
664public:
665 /// \cond CLASSIMP
666 ClassDefOverride(TLMFitter, 1) // NOLINT(readability-else-after-return)
667 /// \endcond
668};
669/*! @} */
670#endif // TLMFitter_H
TH1D * hist
Definition UserFillObj.h:3
T *** v
Definition TLMFitter.h:311
NRMat3d(NRMat3d &&) noexcept=default
NRMat3d(const NRMat3d &)=default
int nn
Definition TLMFitter.h:151
T ** v
Definition TLMFitter.h:153
NRMat(NRMat &&rhs) noexcept=default
NRMat & operator=(NRMat &&rhs) noexcept=default
int mm
Definition TLMFitter.h:152
int nn
Definition TLMFitter.h:38
NRVec & operator=(NRVec &&rhs) noexcept=default
T * v
Definition TLMFitter.h:39
NRVec(NRVec &&rhs) noexcept=default
TH1 * fHist
Definition TLMFitter.h:621
void nrerror(const std::string &error_text)
Definition TLMFitter.h:644
void covsrt(Mat_IO_double &covar, Vec_I_BOOL &ia, int mfit)
TLMFitter(const TLMFitter &)=default
TLMFitter(TLMFitter &&) noexcept=default
int integrator(Vec_I_double &x, Vec_I_double &y, Vec_double &sig, Vec_I_double &W, Vec_IO_double &a, Vec_double &dyda, int chisqnumber, const double &bin_width, Vec_double &yfit, const int &bin)
void SetFitterRange(int min, int max)
Definition TLMFitter.h:638
int fIntegrationSteps
Definition TLMFitter.h:620
int fInitChi2Number
Definition TLMFitter.h:623
int fRangeMin
Definition TLMFitter.h:624
TLMFitter()=default
int fRangeMax
Definition TLMFitter.h:625
void mrqcof(Vec_I_double &x, Vec_I_double &y, Vec_double &sig, Vec_IO_double &a, Vec_I_BOOL &ia, Mat_O_double &alpha, Vec_O_double &beta, double &chisq, Vec_I_double &W, double &chisqexp)
TF1 * fFunction
Definition TLMFitter.h:622
void mrqmin(Vec_I_double &x, Vec_I_double &y, Vec_double &sig, Vec_IO_double &a, Vec_I_BOOL &ia, Mat_O_double &covar, Mat_O_double &alpha, double &chisq, Vec_I_double &W, double &alamda)
*******************************************************************‍/
void gaussj(Mat_IO_double &a, Mat_IO_double &b)
void funcs(const double &x, Vec_IO_double &a, double &y, Vec_O_double &dyda)
Definition TLMFitter.cxx:23
void Fit(TH1 *hist, TF1 *func)
Definition TLMFitter.cxx:35
T SQR(const T a)
Definition TLMFitter.h:516
T & operator[](int i)
Definition TLMFitter.h:123
int nrows() const
Definition TLMFitter.h:285
~NRMat()
Definition TLMFitter.h:297
int ncols() const
Definition TLMFitter.h:291
T ** operator[](int i)
Definition TLMFitter.h:351
std::complex< float > operator+(const double &a, const std::complex< float > &b)
Definition TLMFitter.h:570
int size() const
Definition TLMFitter.h:135
T * operator[](int i)
Definition TLMFitter.h:273
int dim1() const
Definition TLMFitter.h:363
NRVec()
Definition TLMFitter.h:58
void SWAP(T &a, T &b)
Definition TLMFitter.h:563
std::complex< float > operator-(const double &a, const std::complex< float > &b)
Definition TLMFitter.h:580
NRMat & operator=(const NRMat &rhs)
Definition TLMFitter.h:235
T MAX(const T &a, const T &b)
Definition TLMFitter.h:522
int dim3() const
Definition TLMFitter.h:375
std::complex< float > operator/(const double &a, const std::complex< float > &b)
Definition TLMFitter.h:600
NRVec & operator=(const NRVec &rhs)
Definition TLMFitter.h:95
T SIGN(const T &a, const T &b)
Definition TLMFitter.h:538
int dim2() const
Definition TLMFitter.h:369
~NRVec()
Definition TLMFitter.h:141
std::complex< float > operator*(const double &a, const std::complex< float > &b)
Definition TLMFitter.h:590
NRMat()
Definition TLMFitter.h:173