lsst.jointcal  15.0-18-ga2cb10d+1
Histo4d.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <math.h> /* for floor */
3 #include <string.h> /* for memset*/
4 #include <algorithm> /* for sort */
5 #include <limits.h>
6 
7 #include "lsst/log/Log.h"
9 
10 namespace {
11 LOG_LOGGER _log = LOG_GET("jointcal.Histo4d");
12 }
13 
14 namespace lsst {
15 namespace jointcal {
16 
17 SparseHisto4d::SparseHisto4d(const int n1, double min1, double max1, const int n2, double min2, double max2,
18  const int n3, double min3, double max3, const int n4, double min4, double max4,
19  const int nEntries) {
20  double indexMax = n1 * n2 * n3 * n4;
21  _data.reset();
22  if (indexMax > double(INT_MAX))
23  LOGLS_WARN(_log, "Cannot hold a 4D histo with more than " << INT_MAX << " values.");
24  _n[0] = n1;
25  _n[1] = n2;
26  _n[2] = n3;
27  _n[3] = n4;
28  _minVal[0] = min1;
29  _minVal[1] = min2;
30  _minVal[2] = min3;
31  _minVal[3] = min4;
32  _maxVal[0] = max1;
33  _maxVal[1] = max2;
34  _maxVal[2] = max3;
35  _maxVal[3] = max4;
36 
37  for (int i = 0; i < 4; ++i) _scale[i] = _n[i] / (_maxVal[i] - _minVal[i]);
38  _data.reset(new int[nEntries]);
39  _dataSize = nEntries;
40  _ndata = 0;
41  _sorted = false;
42 }
43 
44 int SparseHisto4d::code_value(const double x[4]) const {
45  int index = 0;
46  for (int idim = 0; idim < 4; ++idim) {
47  int i = (int)floor((x[idim] - _minVal[idim]) * _scale[idim]);
48  if (i < 0 || i >= _n[idim]) return -1;
49  index = index * _n[idim] + i;
50  }
51  return index;
52 }
53 
54 void SparseHisto4d::inverse_code(int code, double x[4]) const {
55  for (int i = 3; i >= 0; --i) {
56  int bin = code % _n[i];
57  code /= _n[i];
58  x[i] = _minVal[i] + ((double)bin + 0.5) / _scale[i];
59  }
60 }
61 
63  if (!_sorted) {
64  std::sort(_data.get(), _data.get() + _ndata);
65  _sorted = true;
66  }
67 }
68 
69 void SparseHisto4d::fill(const double x[4])
70 
71 {
72  int code = code_value(x);
73  if (code < 0) return;
74  if (_ndata == _dataSize) {
75  std::unique_ptr<int[]> newData(new int[_dataSize * 2]);
76  memcpy(newData.get(), _data.get(), _dataSize * sizeof(_data[0]));
77  _data.swap(newData);
78  _dataSize *= 2;
79  }
80  _data[_ndata++] = code;
81  _sorted = false;
82 }
83 
84 void SparseHisto4d::fill(const double x1, const double x2, const double x3, const double x4) {
85  static double x[4];
86  x[0] = x1;
87  x[1] = x2;
88  x[2] = x3;
89  x[3] = x4;
90  fill(x);
91 }
92 
93 int SparseHisto4d::maxBin(double x[4]) {
94  sort();
95  if (_ndata == 0) return 0;
96  int maxval = _data[0];
97  int maxCount = 1;
98  int oldval = _data[0];
99  int currentCount = 1;
100  for (int i = 1; i < _ndata; ++i) {
101  if (_data[i] == oldval)
102  currentCount++;
103  else
104  currentCount = 1;
105  if (currentCount > maxCount) {
106  maxCount = currentCount;
107  maxval = _data[i];
108  }
109  oldval = _data[i];
110  }
111  inverse_code(maxval, x);
112  return maxCount;
113 }
114 
115 void SparseHisto4d::zeroBin(double x[4]) {
116  sort();
117  int code = code_value(x);
118  // inefficient locator...
119  int start = 0;
120  while ((_data[start] < code) && start < _ndata) start++;
121  // find how many identical entries we have
122  int end = std::min(start + 1, _ndata);
123  while (end < _ndata && _data[start] == _data[end]) end++;
124  int shift = end - start;
125  int lastShift = _ndata - (end - start);
126  for (int i = start; i < lastShift; ++i) _data[i] = _data[i + shift];
127  _ndata -= shift;
128 }
129 
130 void SparseHisto4d::binLimits(const double x[4], const int iDim, double &xMin, double &xMax) const {
131  int code = code_value(x);
132  double xCenter[4];
133  inverse_code(code, xCenter);
134  xMin = xCenter[iDim] - 0.5 / _scale[iDim];
135  xMax = xCenter[iDim] + 0.5 / _scale[iDim];
136 }
137 
138 void SparseHisto4d::dump() const {
139  for (int i = 0; i < _ndata; ++i) // DEBUG
140  std::cout << _data[i] << ' ';
141  std::cout << std::endl;
142 }
143 } // namespace jointcal
144 } // namespace lsst
void fill(const double x[4])
Definition: Histo4d.cc:69
int code_value(const double x[4]) const
Definition: Histo4d.cc:44
T swap(T... args)
T endl(T... args)
void binLimits(const double x[4], const int idim, double &xMin, double &xMax) const
return the bin limits of dimension idim (0<=idim<4), around point X.
Definition: Histo4d.cc:130
T floor(T... args)
void inverse_code(const int code, double x[4]) const
Definition: Histo4d.cc:54
T min(T... args)
int maxBin(double x[4])
Definition: Histo4d.cc:93
Class for a simple mapping implementing a generic Gtransfo.
T memcpy(T... args)
int end
void zeroBin(double x[4])
Definition: Histo4d.cc:115
T reset(T... args)
T get(T... args)
double x
T sort(T... args)
#define LOG_GET(logger)
#define LOGLS_WARN(logger, message)