Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
compressor_generator.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file compressor_generator.h
1 
7 //-----------------------------------------------------------------------------
8 #include <map>
9 #include <random>
10 #include <set>
11 #include <utility>
12 #include <vector>
13 
14 #include "RtypesCore.h"
15 //-----------------------------------------------------------------------------
16 
17 UShort_t residesIn(Float_t raw, std::vector<Float_t>* dict)
18 {
19  for (size_t i = 0; i < dict->size(); ++i)
20  {
21  if (raw <= dict->at(i))
22  {
23  if (i == 0)
24  return 0;
25  else if ((dict->at(i) - raw) < (raw - dict->at(i - 1)))
26  return i;
27  else
28  return i - 1;
29  }
30  }
31  return dict->size() - 1;
32 }
33 //-----------------------------------------------------------------------------
37 Float_t approx(
38  std::vector<UShort_t>* order,
39  std::vector<Float_t>* dict,
40  std::vector<size_t>* cnt,
41  Int_t n_entries,
42  std::default_random_engine& generator,
43  std::normal_distribution<double>& distribution,
44  size_t maxNumClusters);
45 //-----------------------------------------------------------------------------
46 Int_t newLoc(std::vector<Int_t>* loc_vec, std::vector<std::vector<Int_t>>* loc_vec_vec);
47 void removeDiff(Float_t distance, Float_t min, std::map<Float_t, std::set<Float_t>>* distance_min_set_map);
48 void addDiff(Float_t distance, Float_t min, std::map<Float_t, std::set<Float_t>>* distance_min_set_map);
49 //-----------------------------------------------------------------------------
50 Float_t approx(std::vector<UShort_t>* order, std::vector<Float_t>* dict, std::vector<size_t>* cnt, Int_t n_entries, std::default_random_engine& generator, std::normal_distribution<double>& distribution, size_t maxNumClusters)
51 {
52  Float_t maxAbsErrorDoubled = (Float_t) 0;
53 
54  std::map<Float_t, std::pair<Float_t, Int_t>> min_max_loc_map;
55  std::vector<std::vector<Int_t>> loc_vec_vec;
56  std::vector<Int_t> loc_vec;
57  std::map<Float_t, std::set<Float_t>> distance_min_set_map;
58 
59  for (Int_t j = 0; j < n_entries; j++)
60  {
61  Float_t number = distribution(generator);
62  Float_t* gen_ = &number;
63 
64  std::map<Float_t, std::pair<Float_t, Int_t>>::iterator mmlm = min_max_loc_map.find(*gen_);
65 
66  if (mmlm != min_max_loc_map.end())
67  loc_vec_vec[mmlm->second.second].push_back(j);
68  else
69  {
70  Int_t loc = newLoc(&loc_vec, &loc_vec_vec);
71 
72  loc_vec_vec[loc].push_back(j);
73 
74  min_max_loc_map[*gen_] = std::pair<Float_t, Int_t>(*gen_, loc);
75 
76  mmlm = min_max_loc_map.find(*gen_);
77  if (mmlm != min_max_loc_map.begin() && *gen_ <= prev(mmlm)->second.first)
78  {
79  loc_vec_vec[prev(mmlm)->second.second].push_back(j);
80  loc_vec_vec[mmlm->second.second].clear();
81  loc_vec.push_back(mmlm->second.second);
82 
83  min_max_loc_map.erase(mmlm);
84  }
85  else if (min_max_loc_map.size() >= 2)
86  {
87  if (mmlm != min_max_loc_map.begin() && mmlm != prev(min_max_loc_map.end()))
88  {
89  removeDiff(next(mmlm)->second.first - prev(mmlm)->first, prev(mmlm)->first, &distance_min_set_map);
90  }
91 
92  if (mmlm != min_max_loc_map.begin())
93  addDiff(mmlm->second.first - prev(mmlm)->first, prev(mmlm)->first, &distance_min_set_map);
94 
95  if (mmlm != prev(min_max_loc_map.end()))
96  addDiff(next(mmlm)->second.first - mmlm->first, mmlm->first, &distance_min_set_map);
97  }
98  }
99 
100  if (min_max_loc_map.size() <= maxNumClusters)
101  continue;
102 
103  std::map<Float_t, std::set<Float_t>>::iterator dmsm = distance_min_set_map.begin();
104  Float_t min = *(dmsm->second.begin());
105 
106  dmsm->second.erase(min);
107  if (dmsm->second.empty())
108  distance_min_set_map.erase(dmsm);
109 
110  mmlm = min_max_loc_map.find(min);
111  if (mmlm != min_max_loc_map.begin())
112  removeDiff(mmlm->second.first - prev(mmlm)->first, prev(mmlm)->first, &distance_min_set_map);
113 
114  if (next(mmlm) != prev(min_max_loc_map.end()))
115  removeDiff(next(next(mmlm))->second.first - next(mmlm)->first, next(mmlm)->first, &distance_min_set_map);
116 
117  std::vector<Int_t>* s = &(loc_vec_vec[next(mmlm)->second.second]);
118  loc_vec_vec[mmlm->second.second].insert(loc_vec_vec[mmlm->second.second].end(), s->begin(), s->end());
119  mmlm->second.first = next(mmlm)->second.first;
120  min_max_loc_map.erase(next(mmlm));
121  mmlm = min_max_loc_map.find(min);
122  maxAbsErrorDoubled = std::max(maxAbsErrorDoubled, mmlm->second.first - mmlm->first);
123  if (mmlm != min_max_loc_map.begin())
124  addDiff(mmlm->second.first - prev(mmlm)->first, prev(mmlm)->first, &distance_min_set_map);
125 
126  if (mmlm != prev(min_max_loc_map.end()))
127  addDiff(next(mmlm)->second.first - mmlm->first, mmlm->first, &distance_min_set_map);
128  }
129 
130  order->resize(n_entries);
131  for (const auto& mmlm : min_max_loc_map)
132  {
133  Double_t estimate = (Double_t) (mmlm.first + mmlm.second.first) / (Double_t) 2;
134  // cppcheck-suppress containerOutOfBounds
135  for (const auto& index : loc_vec_vec[mmlm.second.second])
136  {
137  (*order)[index] = dict->size();
138  }
139 
140  dict->push_back(estimate);
141  // cppcheck-suppress containerOutOfBounds
142  cnt->push_back(loc_vec_vec[mmlm.second.second].size());
143  }
144 
145  return maxAbsErrorDoubled / (double) 2; // sqrt((squaredSum / (Double_t) n_entries) - avg * avg);
146 }
147 
148 Int_t newLoc(std::vector<Int_t>* loc_vec, std::vector<std::vector<Int_t>>* loc_vec_vec)
149 {
150  if (!loc_vec->empty())
151  {
152  Int_t loc = loc_vec->back();
153  loc_vec->pop_back();
154  return loc;
155  }
156 
157  Int_t loc = loc_vec_vec->size();
158  loc_vec_vec->push_back({});
159  return loc;
160 }
161 
162 void removeDiff(Float_t distance, Float_t min, std::map<Float_t, std::set<Float_t>>* distance_min_set_map)
163 {
164  std::map<Float_t, std::set<Float_t>>::iterator dmsm = distance_min_set_map->find(distance);
165  dmsm->second.erase(min);
166 
167  if (dmsm->second.empty())
168  distance_min_set_map->erase(dmsm);
169 }
170 
171 void addDiff(Float_t distance, Float_t min, std::map<Float_t, std::set<Float_t>>* distance_min_set_map)
172 {
173  std::map<Float_t, std::set<Float_t>>::iterator dmsm = distance_min_set_map->find(distance);
174  if (dmsm == distance_min_set_map->end())
175  {
176  (*distance_min_set_map)[distance] = {min};
177  }
178  else
179  {
180  dmsm->second.insert(min);
181  }
182 }