uLib-0.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Accumulator.h
Go to the documentation of this file.
1 /*//////////////////////////////////////////////////////////////////////////////
2 // CMT Cosmic Muon Tomography project //////////////////////////////////////////
4 
5  Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
6  All rights reserved
7 
8  Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
9 
10  ------------------------------------------------------------------
11  This library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU Lesser General Public
13  License as published by the Free Software Foundation; either
14  version 3.0 of the License, or (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public
22  License along with this library.
23 
25 
26 
27 
28 #ifndef U_DATABINNING_H
29 #define U_DATABINNING_H
30 
31 #include <vector>
32 
33 #include "Dense.h"
34 
35 
36 namespace uLib {
37 
38 
39 
40 // TODO: USE BOOST ACCUMULATORS //
41 
42 
43 template <typename T>
44 class Accumulator_Mean {
45  typedef std::pair<T,unsigned long> Tmean;
46 public:
47  Accumulator_Mean() {
48  m_Means.push_back( Tmean(0,0) );
49  }
50 
51  void operator()(const T data) {
52  T tmp = 0;
53  // for(typename std::vector<Tmean>::iterator it = m_Means.begin(); it < m_Means.back(); ++it)
54  // tmp += it->first/it->second;
55  for(int i=0; i<m_Means.size()-1;++i)
56  tmp += m_Means[i].first / m_Means[i].second;
57  m_Means.back().first += data - tmp;
58  m_Means.back().second += 1;
59  }
60 
61  T operator()() const {
62  T mean = 0;
63  // for(typename std::vector<Tmean>::iterator it = m_Means.begin(); it < m_Means.end(); ++it) {
64  // mean += it->first/it->second; }
65  for(int i=0; i<m_Means.size();++i)
66  mean += m_Means[i].first / m_Means[i].second;
67  return mean;
68  }
69 
70  void AddPass() { m_Means.push_back( Tmean(0,0) ); }
71 
72 private:
73  std::vector< Tmean > m_Means;
74 };
75 
76 
77 
78 
82 // accumulator Trim //
83 
84 template < typename T, int subsample_size=200 >
85 class Accumulator_ABTrim {
86 
87 public:
88  Accumulator_ABTrim() :
89  m_Avg(0),
90  m_InternalCount(0),
91  m_SizeA(0),
92  m_SizeB(0),
93  m_IdA(0),
94  m_IdB(0)
95  {}
96 
97  Accumulator_ABTrim(const Accumulator_ABTrim &c) {
98 # pragma omp critical
99  {
100  m_Avg = c.m_Avg;
101  m_InternalCount = c.m_InternalCount;
102  m_SizeA = c.m_SizeA;
103  m_SizeB = c.m_SizeB;
104  m_IdA = c.m_IdA;
105  m_IdB = c.m_IdB;
106  memcpy (m_Av, c.m_Av, sizeof (m_Av));
107  }
108  }
109 
110  void operator += (T value) {
111  if(m_InternalCount > subsample_size) {
112  // array complete and counter over subsample //
113  if( m_SizeA > 0 && value < m_ValA ) {
114  ;// m_Avg += m_ValA;
115  }
116  else if (m_SizeB > 0 && value > m_ValB)
117  {
118  ;// m_Avg += m_ValB;
119  }
120  else
121  {
122  m_Avg += value;
123  m_InternalCount++;
124  }
125  }
126  else if(m_InternalCount >=0) {
127  // array complete
128  if(m_SizeA > 0 && value < m_ValA)
129  {
130  m_Avg += m_ValA;
131  m_Av[m_IdA] = value;
132  for (unsigned int i=0; i < m_SizeA; i++)
133  if(m_Av[i] > m_Av[m_IdA])
134  { m_IdA = i; m_ValA = m_Av[i]; }
135  }
136  else if(m_SizeB > 0 && value > m_ValB)
137  {
138  m_Avg += m_ValB;
139  m_Av[m_IdB] = value;
140  for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++)
141  if(m_Av[i] < m_Av[m_IdB])
142  { m_IdB = i; m_ValB = m_Av[i]; }
143  }
144  else {
145  m_Avg += value;
146  }
147  m_InternalCount++;
148  }
149  else { // m_InternalCount < 0
150  // array is not fullfilled
151  m_Av[m_SizeA+m_SizeB+m_InternalCount] = value;
152  m_InternalCount++;
153  if(m_InternalCount == 0) {
154  std::sort(m_Av,m_Av+m_SizeA+m_SizeB);
155  if(m_SizeA > 0) {
156  m_IdA = m_SizeA-1;
157  m_ValA = m_Av[m_IdA];
158  }
159  if(m_SizeB > 0) {
160  m_IdB = m_SizeA;
161  m_ValB = m_Av[m_SizeA];
162  }
163  }
164  }
165  }
166 
167  T operator()() {
168  if(m_InternalCount <= 0) {
169  std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount);
170  return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value //
171  }
172  else {
173 // return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) /
174 // (m_InternalCount + m_SizeA + m_SizeB);
175  return (m_Avg) / m_InternalCount;
176  }
177  }
178 
179  void SetABTrim(int a, int b) {
180  if(a+b > subsample_size/2) {
181  m_SizeA = a/(a+b) * subsample_size/2;
182  m_SizeB = b/(a+b) * subsample_size/2;
183  }
184  else {
185  m_SizeA = a;
186  m_SizeB = b;
187  }
188  m_Avg = 0;
189  m_InternalCount = -m_SizeA-m_SizeB;
190  }
191 
192 
193 private:
194  T m_Av[subsample_size/2];
195  T m_Avg, m_ValA, m_ValB;
196  int m_IdA, m_IdB, m_InternalCount;
197  int m_SizeA, m_SizeB;
198 };
199 
200 
201 
202 
203 
204 
205 
206 
207 
211 // Clip Accumulator //
212 
213 template < typename T, int subsample_size=200 >
214 class Accumulator_ABClip {
215 
216 public:
217  Accumulator_ABClip() :
218  m_Avg(0),
219  m_InternalCount(0),
220  m_SizeA(0),
221  m_SizeB(0),
222  m_IdA(0),
223  m_IdB(0)
224  {}
225 
226  Accumulator_ABClip(const Accumulator_ABClip &c) {
227 # pragma omp critical
228  {
229  m_Avg = c.m_Avg;
230  m_InternalCount = c.m_InternalCount;
231  m_SizeA = c.m_SizeA;
232  m_SizeB = c.m_SizeB;
233  m_IdA = c.m_IdA;
234  m_IdB = c.m_IdB;
235  memcpy (m_Av, c.m_Av, sizeof (m_Av));
236  }
237  }
238 
239  void operator += (T value) {
240  if(m_InternalCount > subsample_size) {
241  // array complete and counter over subsample //
242  if( m_SizeA > 0 && value < m_ValA ) {
243  m_Avg += m_ValA;
244  }
245  else if (m_SizeB > 0 && value > m_ValB) {
246  m_Avg += m_ValB;
247  }
248  else {
249  m_Avg += value;
250  }
251  m_InternalCount++;
252  }
253  else if(m_InternalCount >=0) {
254  // array complete
255  if(m_SizeA > 0 && value < m_ValA)
256  {
257  m_Avg += m_ValA;
258  m_Av[m_IdA] = value;
259  for (unsigned int i=0; i < m_SizeA; i++)
260  if(m_Av[i] > m_Av[m_IdA])
261  { m_IdA = i; m_ValA = m_Av[i]; }
262  }
263  else if(m_SizeB > 0 && value > m_ValB)
264  {
265  m_Avg += m_ValB;
266  m_Av[m_IdB] = value;
267  for (unsigned int i=m_SizeA; i < m_SizeA+m_SizeB; i++)
268  if(m_Av[i] < m_Av[m_IdB])
269  { m_IdB = i; m_ValB = m_Av[i]; }
270  }
271  else {
272  m_Avg += value;
273  }
274  m_InternalCount++;
275  }
276  else { // m_InternalCount < 0
277  // array is not fullfilled
278  m_Av[m_SizeA+m_SizeB+m_InternalCount] = value;
279  m_InternalCount++;
280  if(m_InternalCount == 0) {
281  std::sort(m_Av,m_Av+m_SizeA+m_SizeB);
282  if(m_SizeA > 0) {
283  m_IdA = m_SizeA-1;
284  m_ValA = m_Av[m_IdA];
285  }
286  if(m_SizeB > 0) {
287  m_IdB = m_SizeA;
288  m_ValB = m_Av[m_SizeA];
289  }
290  }
291  }
292  }
293 
294  T operator()() {
295  if(m_InternalCount <= 0) {
296  std::sort(m_Av, m_Av+m_SizeA+m_SizeB+m_InternalCount);
297  return m_Av[ (m_SizeA+m_SizeB+m_InternalCount) / 2]; // median value //
298  }
299  else {
300  return (m_Avg + m_ValA * m_SizeA + m_ValB * m_SizeB) /
301  (m_InternalCount + m_SizeA + m_SizeB);
302  }
303  }
304 
305  void SetABTrim(int a, int b) {
306  if(a+b > subsample_size/2) {
307  m_SizeA = a/(a+b) * subsample_size/2;
308  m_SizeB = b/(a+b) * subsample_size/2;
309  }
310  else {
311  m_SizeA = a;
312  m_SizeB = b;
313  }
314  m_Avg = 0;
315  m_InternalCount = -m_SizeA-m_SizeB;
316  }
317 
318 
319 private:
320  T m_Av[subsample_size/2];
321  T m_Avg, m_ValA, m_ValB;
322  int m_IdA, m_IdB, m_InternalCount;
323  int m_SizeA, m_SizeB;
324 };
325 
326 
327 
328 
329 
330 } // uLib
331 
332 
333 
334 
335 #endif // U_DATABINNING_H