GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
TGo4FitAmplEstimation.cxx
Go to the documentation of this file.
1// $Id$
2//-----------------------------------------------------------------------
3// The GSI Online Offline Object Oriented (Go4) Project
4// Experiment Data Processing at EE department, GSI
5//-----------------------------------------------------------------------
6// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7// Planckstr. 1, 64291 Darmstadt, Germany
8// Contact: http://go4.gsi.de
9//-----------------------------------------------------------------------
10// This software can be used under the license agreements as stated
11// in Go4License.txt file which is part of the distribution.
12//-----------------------------------------------------------------------
13
15
16#include <iostream>
17
18#include "TMath.h"
19#include "TMatrixD.h"
20#include "TVectorD.h"
21#include "TArrayC.h"
22#include "TArrayD.h"
23
24#include "TGo4Fitter.h"
25#include "TGo4FitModel.h"
26#include "TGo4FitData.h"
27#include "TGo4FitParameter.h"
28
30
31TGo4FitAmplEstimation::TGo4FitAmplEstimation(const char *Name, Int_t NumIters)
32 : TGo4FitterAction(Name, "Estimate amplitude action"), fiNumIters(NumIters)
33{
34}
35
37
39{
40 auto f = dynamic_cast<TGo4Fitter *>(Fitter);
41 if (!f)
42 return;
45}
46
47Double_t
48TGo4FitAmplEstimation::PointWeight(Int_t niter, Int_t FFtype, Double_t value, Double_t modelvalue, Double_t standdev)
49{
50 switch (FFtype) {
51 case TGo4Fitter::ff_least_squares: return 1.;
52 case TGo4Fitter::ff_chi_square: return (standdev <= 0.) ? 0. : 1. / standdev;
55 if (niter == 0)
56 return (value < 0.) ? 0. : 1. / (value + 1.);
57 else
58 return (modelvalue <= 0.) ? 0. : 1. / modelvalue;
59 case TGo4Fitter::ff_chi_Neyman: return (value < 1.) ? 1. : 1. / value;
60 case TGo4Fitter::ff_chi_gamma: return (value < 0.) ? 0. : 1. / (value + 1.);
61 case TGo4Fitter::ff_user: return 1.;
62 }
63 return 1.;
64}
65
67{
68 if (!fitter->IsInitialized())
69 return kFALSE;
70
71 for (Int_t n = 0; n < fitter->GetNumData(); n++)
72 if (!fitter->DataBuffersAllocated(fitter->GetData(n)))
73 return kFALSE;
74
75 for (Int_t n = 0; n < fitter->GetNumModel(); n++)
76 if (!fitter->ModelBuffersAllocated(fitter->GetModel(n)))
77 return kFALSE;
78
79 TObjArray comps, fixedcomps;
80
81 for (Int_t n = 0; n < fitter->GetNumModel(); n++) {
82 TGo4FitModel *fModel = fitter->GetModel(n);
83
84 Bool_t assigned = kFALSE;
85 for (Int_t na = 0; na < fModel->NumAssigments(); na++)
86 if (fitter->FindData(fModel->AssignmentName(na))) {
87 assigned = kTRUE;
88 break;
89 }
90 if (!assigned)
91 continue;
92
93 if (fModel->GetAmplPar() && !fModel->GetAmplPar()->GetFixed())
94 comps.Add(fModel);
95 else
96 fixedcomps.Add(fModel);
97 }
98
99 Int_t ncomp = comps.GetLast() + 1;
100 if (ncomp <= 0)
101 return kFALSE;
102
103 TMatrixD matr(ncomp, ncomp);
104 TVectorD vector(ncomp);
105
106 Double_t **DopData = new Double_t *[fitter->GetNumData()];
107 for (Int_t n = 0; n < fitter->GetNumData(); n++)
108 DopData[n] = new Double_t[fitter->GetDataBinsSize(fitter->GetData(n))];
109
110 Double_t **Weights = new Double_t *[fitter->GetNumData()];
111 for (Int_t n = 0; n < fitter->GetNumData(); n++)
112 Weights[n] = new Double_t[fitter->GetDataBinsSize(fitter->GetData(n))];
113
114 Int_t niter = 0;
115 Int_t FFtype = fitter->GetFitFunctionType();
116 Bool_t changed = kFALSE;
117
118 do {
119
120 fitter->RebuildAll();
121
122 for (Int_t ndata = 0; ndata < fitter->GetNumData(); ndata++) {
123 TGo4FitData *data = fitter->GetData(ndata);
124
125 Int_t size = fitter->GetDataBinsSize(data);
126 Double_t ampl = data->GetAmplValue();
127
128 Double_t *values = fitter->GetDataBinsValues(data);
129 Double_t *result = fitter->GetDataBinsResult(data);
130 Double_t *devs = fitter->GetDataBinsDevs(data);
131 Double_t *weight = Weights[ndata];
132
133 for (Int_t nbin = 0; nbin < size; nbin++)
134 weight[nbin] = PointWeight(niter, FFtype, ampl * values[nbin], result[nbin], ampl * ampl * devs[nbin]);
135 }
136
137 for (Int_t n1 = 0; n1 < ncomp; n1++)
138 for (Int_t n2 = n1; n2 < ncomp; n2++) {
139 Double_t fSum = 0.;
140 for (Int_t ndata = 0; ndata < fitter->GetNumData(); ndata++) {
141 Double_t *bins1 = fitter->GetModelBinsValues((TGo4FitModel *)comps[n1], fitter->GetDataName(ndata));
142 Double_t *bins2 = fitter->GetModelBinsValues((TGo4FitModel *)comps[n2], fitter->GetDataName(ndata));
143 if (bins1 && bins2) {
144 Int_t size = fitter->GetDataBinsSize(fitter->GetData(ndata));
145 Double_t *weight = Weights[ndata];
146 for (Int_t nbin = 0; nbin < size; nbin++)
147 fSum += bins1[nbin] * bins2[nbin] * weight[nbin];
148 }
149 }
150 matr(n1, n2) = fSum;
151 matr(n2, n1) = fSum;
152 }
153
154 // calculating difference between data and fixed components
155 for (Int_t ndata = 0; ndata < fitter->GetNumData(); ndata++) {
156 TGo4FitData *data = fitter->GetData(ndata);
157 Int_t size = fitter->GetDataBinsSize(data);
158 Double_t dampl = data->GetAmplValue();
159 Double_t *values = fitter->GetDataBinsValues(data);
160 Double_t *bins = DopData[ndata];
161
162 for (Int_t nbin = 0; nbin < size; nbin++)
163 bins[nbin] = dampl * values[nbin];
164
165 for (Int_t n = 0; n <= fixedcomps.GetLast(); n++) {
166 TGo4FitModel *model = (TGo4FitModel *)fixedcomps[n];
167 Double_t *mbins = fitter->GetModelBinsValues(model, data->GetName());
168 if (mbins) {
169 Double_t mampl = model->GetAmplValue();
170 for (Int_t nbin = 0; nbin < size; nbin++)
171 bins[nbin] -= mampl * mbins[nbin];
172 }
173 }
174 }
175
176 // filling vector
177
178 for (Int_t n = 0; n < ncomp; n++) {
179 Double_t fSum = 0.;
180 for (Int_t ndata = 0; ndata < fitter->GetNumData(); ndata++) {
181 Double_t *bins1 = fitter->GetModelBinsValues((TGo4FitModel *)comps[n], fitter->GetDataName(ndata));
182 if (!bins1)
183 continue;
184 Int_t size = fitter->GetDataBinsSize(fitter->GetData(ndata));
185 Double_t *bins = DopData[ndata];
186 Double_t *weight = Weights[ndata];
187 for (Int_t nbin = 0; nbin < size; nbin++)
188 fSum += bins[nbin] * bins1[nbin] * weight[nbin];
189 }
190 vector(n) = fSum;
191 }
192
193 if (matr.Determinant() == 0.) {
194 std::cerr << " Amplitude estimation algorithm failed. " << std::endl;
195 std::cerr
196 << " Determinant of matrix == 0.; This may be due to equivalent model components or zero model at all"
197 << std::endl;
198 break;
199 }
200
201 matr.Invert();
202 vector *= matr;
203
204 for (Int_t n = 0; n < ncomp; n++) {
205 TGo4FitModel *model = (TGo4FitModel *)comps[n];
206 model->SetAmplValue(vector(n));
207 if (matr(n, n) > 0.)
208 model->SetAmplError(TMath::Sqrt(matr(n, n)));
209 }
210
211 changed = kFALSE;
212 niter++;
213 if (niter < fiNumIters)
214 if ((FFtype == TGo4Fitter::ff_chi_Pearson) || (FFtype == TGo4Fitter::ff_ML_Poisson))
215 changed = kTRUE;
216
217 } while (changed);
218
219 for (Int_t n = 0; n < fitter->GetNumData(); n++)
220 delete[] Weights[n];
221 delete[] Weights;
222
223 for (Int_t n = 0; n < fitter->GetNumData(); n++)
224 delete[] DopData[n];
225 delete[] DopData;
226
227 return kTRUE;
228}
229
231{
232 if (!fitter)
233 return kFALSE;
234
235 Int_t nmodel = fitter->GetNumModel();
236 TArrayI refindex(fitter->GetNumModel());
237 refindex.Reset(-1);
238 TArrayI fixedindex(fitter->GetNumModel());
239 fixedindex.Reset(-1);
240
241 Int_t ncomp = 0;
242 Int_t nfixed = 0;
243
244 for (Int_t n = 0; n < nmodel; n++) {
245 TGo4FitModel *model = fitter->GetModel(n);
246 Bool_t assigned = kFALSE;
247 for (Int_t na = 0; na < model->NumAssigments(); na++)
248 if (fitter->FindData(model->AssignmentName(na))) {
249 assigned = kTRUE;
250 break;
251 }
252 if (!assigned)
253 continue;
254
255 if (model->GetAmplPar() && !model->GetAmplPar()->GetFixed())
256 refindex[ncomp++] = n;
257 else
258 fixedindex[nfixed++] = n;
259 }
260
261 if (ncomp <= 0)
262 return kFALSE;
263
264 TMatrixD matr(ncomp, ncomp);
265 TVectorD vector(ncomp);
266
267 TArrayC Usage(nmodel);
268 TArrayD ModelValues(nmodel);
269 TArrayD ModelAmpls(nmodel);
270
271 Int_t niter = 0;
272 Int_t FFtype = fitter->GetFitFunctionType();
273 Bool_t changed = kFALSE;
274
275 do {
276 matr = 0.;
277 vector = 0.;
278
279 for (Int_t ndata = 0; ndata < fitter->GetNumData(); ndata++) {
280 TGo4FitData *data = fitter->GetData(ndata);
281 auto iter = data->MakeIter();
282 if (!iter)
283 return kFALSE;
284
285 Double_t dampl = data->GetAmplValue();
286
287 if (iter->Reset()) {
288 Usage.Reset(0);
289 ModelAmpls.Reset(0.);
290 ModelValues.Reset(0.);
291 for (Int_t n = 0; n < nmodel; n++) {
292 TGo4FitModel *model = fitter->GetModel(n);
293 if (model->IsAssignTo(data->GetName())) {
294 Usage[n] = 1;
295 ModelAmpls[n] = model->GetAmplValue() * model->GetRatioValueFor(data->GetName());
296 model->BeforeEval(iter->IndexesSize());
297 }
298 }
299
300 do {
301 Double_t result = 0.;
302 for (Int_t n = 0; n < nmodel; n++)
303 if (Usage[n]) {
304 ModelValues[n] = fitter->GetModel(n)->EvaluateAtPoint(iter);
305 result += ModelAmpls[n] * ModelValues[n];
306 }
307 Double_t weight =
308 PointWeight(niter, FFtype, dampl * iter->Value(), result, dampl * dampl * iter->StandardDeviation());
309 if (weight <= 0.)
310 continue;
311
312 for (Int_t i1 = 0; i1 < ncomp; i1++)
313 for (Int_t i2 = i1; i2 < ncomp; i2++) {
314 Double_t zn = matr(i1, i2);
315 zn += ModelValues[refindex[i1]] * ModelValues[refindex[i2]] * weight;
316 matr(i1, i2) = zn;
317 if (i1 != i2)
318 matr(i2, i1) = zn;
319 }
320
321 Double_t dvalue = dampl * iter->Value();
322 for (Int_t nf = 0; nf < nfixed; nf++)
323 dvalue -= ModelAmpls[fixedindex[nf]] * ModelValues[fixedindex[nf]];
324
325 for (Int_t i1 = 0; i1 < ncomp; i1++) {
326 Double_t zn = vector(i1);
327 zn += ModelValues[refindex[i1]] * dvalue * weight;
328 vector(i1) = zn;
329 }
330
331 } while (iter->Next());
332
333 for (Int_t n = 0; n < nmodel; n++)
334 if (Usage[n])
335 fitter->GetModel(n)->AfterEval();
336 }
337 }
338
339 if (matr.Determinant() == 0.) {
340 std::cerr << " Amplitude estimation algorithm failed. " << std::endl;
341 std::cerr
342 << " Determinant of matrix == 0.; This may be due to equivalent model components or zero model at all"
343 << std::endl;
344 return kFALSE;
345 }
346
347 matr.Invert();
348 vector *= matr;
349
350 for (Int_t n = 0; n < ncomp; n++) {
351 TGo4FitModel *model = fitter->GetModel(refindex[n]);
352 model->SetAmplValue(vector(n));
353 if (matr(n, n) > 0.)
354 model->SetAmplError(TMath::Sqrt(matr(n, n)));
355 }
356
357 changed = kFALSE;
358 niter++;
359 if (niter < fiNumIters)
360 if ((FFtype == TGo4Fitter::ff_chi_Pearson) || (FFtype == TGo4Fitter::ff_ML_Poisson))
361 changed = kTRUE;
362
363 } while (changed);
364
365 return kTRUE;
366}
367
368void TGo4FitAmplEstimation::Print(Option_t *option) const
369{
371 std::cout << " number of iterations " << fiNumIters << std::endl;
372}
Bool_t CalculateWithBuffers(TGo4Fitter *fitter)
virtual ~TGo4FitAmplEstimation()
Destroys TGo4FitAmplEstimation object.
Bool_t CalculateWithIterators(TGo4Fitter *fitter)
Double_t PointWeight(Int_t niter, Int_t FFtype, Double_t value, Double_t modelvalue, Double_t standdev)
TGo4FitAmplEstimation()
Default constructor.
void DoAction(TGo4FitterAbstract *Fitter) override
Perform amplitude estimations.
void Print(Option_t *option="") const override
Print information on standard output.
Int_t fiNumIters
Number of iterations, used for amplitude estimation.
TGo4FitParameter * GetAmplPar()
Return amplitude parameter object.
void SetAmplError(Double_t iError)
Set error of amplitude parameter.
Double_t GetAmplValue()
Return value of amplitude parameter.
void SetAmplValue(Double_t iAmpl)
Set value of amplitude parameter.
Basic abstract class for representing data, which should be fitted.
Definition TGo4FitData.h:39
virtual std::unique_ptr< TGo4FitDataIter > MakeIter()
Creates iterator for data object.
Basic abstract class for representing model components of fitted data.
const char * AssignmentName(Int_t n)
Returns name of data, to which model object is assigned.
virtual Bool_t BeforeEval(Int_t ndim)
Prepares (if necessary) some intermediate variables to be able calculate values of model via EvalN() ...
Bool_t IsAssignTo(const char *DataName) const
Checks, if model assigned to given data.
virtual Double_t EvaluateAtPoint(TGo4FitData *data, Int_t nbin, Bool_t UseRanges=kTRUE)
Evaluate model value for specified data point.
virtual void AfterEval()
Clear buffers, which were created by BeforeEval() method.
Double_t GetRatioValueFor(const char *DataName)
Returns ratio value for specified data object.
Int_t NumAssigments() const
Returns number of assignment for this model.
void Print(Option_t *option="") const override
Bool_t GetFixed() const
Return status, if parameter fixed or not.
Abstract fitter class.
Bool_t IsInitialized() const
Return kTRUE, if Initialize() was done.
TGo4FitterAction()
Default constructor.
Central class of Go4Fit package.
Definition TGo4Fitter.h:38
@ ff_least_squares
Definition TGo4Fitter.h:40
Bool_t ModelBuffersAllocated(TGo4FitModel *model)
Bool_t DataBuffersAllocated(TGo4FitData *data)
Double_t * GetDataBinsResult(TGo4FitData *data) const
TGo4FitModel * GetModel(Int_t n)
Return model component with given index.
const char * GetDataName(Int_t n)
Return name of data object with given index.
Double_t * GetModelBinsValues(TGo4FitModel *model, const char *DataName) const
Int_t GetNumModel() const
Return number of model component in fitter.
Definition TGo4Fitter.h:179
Int_t GetDataBinsSize(TGo4FitData *data) const
void RebuildAll(Bool_t ForceBuild=kFALSE)
Update all data objects and model components according to current parameters values.
TGo4FitData * GetData(Int_t n)
Return data object with given index.
TGo4FitData * FindData(const char *DataName)
Return data object with given name.
Int_t GetNumData() const
Return number of data objects in fitter.
Definition TGo4Fitter.h:124
Double_t * GetDataBinsDevs(TGo4FitData *data) const
Double_t * GetDataBinsValues(TGo4FitData *data) const
Int_t GetFitFunctionType() const
Return type of fitted function.
Definition TGo4Fitter.h:86