CMS 3D CMS Logo

liblogintpack.h
Go to the documentation of this file.
1 #ifndef liblogintpack_h
2 #define liblogintpack_h
3 
4 #include <cmath>
5 #include <cstdint>
6 
7 namespace logintpack {
9  // note that abs(unpack(smallestNegative)) == unpack(1), i.e. there
10  // is no "x" such that "unpack(x) == -unpack(0)"
12  inline int16_t pack16logCeil(double x, double lmin, double lmax, uint16_t base = 32768) {
13  if (base > 32768)
14  base = 32768;
15  const double l = std::log(std::abs(x));
16  const double centered = (l - lmin) / (lmax - lmin) * base;
17  int16_t r = std::ceil(centered);
18  if (centered >= base - 1)
19  r = base - 1;
20  if (centered < 0)
21  r = 0;
22  if (x < 0)
23  r = r == 0 ? -1 : -r;
24  return r;
25  }
26 
27  inline int16_t pack16log(double x, double lmin, double lmax, uint16_t base = 32768) {
28  if (base > 32768)
29  base = 32768;
30  const float delta = (log(1. + exp((lmax - lmin) / base)) - log(2.)) * base / (lmax - lmin);
31  const double l = std::log(std::abs(x));
32  const double centered = (l - lmin) / (lmax - lmin) * base;
33  int16_t r = std::floor(centered);
34  if (centered - r > delta)
35  r += 1;
36  if (centered >= base - 1)
37  r = base - 1;
38  if (centered < 0)
39  r = 0;
40  if (x < 0)
41  r = r == 0 ? -1 : -r;
42  return r;
43  }
44 
47  inline int16_t pack16logClosed(double x, double lmin, double lmax, uint16_t base = 32768) {
48  if (base > 32768)
49  base = 32768;
50  const double l = std::log(std::abs(x));
51  const double centered = (l - lmin) / (lmax - lmin) * (base - 1);
52  int16_t r = round(centered);
53  if (centered >= base - 1)
54  r = base - 1;
55  if (centered < 0)
56  r = 0;
57  if (x < 0)
58  r = r == 0 ? -1 : -r;
59  return r;
60  }
61 
62  inline double unpack16log(int16_t i, double lmin, double lmax, uint16_t base = 32768) {
63  if (base > 32768)
64  base = 32768;
65  const double basef = base;
66  const double l = lmin + std::abs(i) / basef * (lmax - lmin);
67  const double val = std::exp(l);
68  if (i < 0)
69  return -val;
70  else
71  return val;
72  }
73 
75  inline double unpack16logClosed(int16_t i, double lmin, double lmax, uint16_t base = 32768) {
76  if (base > 32768)
77  base = 32768;
78  const double basef = base - 1;
79  double l = lmin + std::abs(i) / basef * (lmax - lmin);
80  if (std::abs(i) == base - 1)
81  l = lmax;
82  const double val = std::exp(l);
83  if (i < 0)
84  return -val;
85  else
86  return val;
87  }
88 
89  inline int8_t pack8logCeil(double x, double lmin, double lmax, uint8_t base = 128) {
90  if (base > 128)
91  base = 128;
92  const double l = std::log(std::abs(x));
93  const double centered = (l - lmin) / (lmax - lmin) * base;
94  int8_t r = std::ceil(centered);
95  if (centered >= base - 1)
96  r = base - 1;
97  if (centered < 0)
98  r = 0;
99  if (x < 0)
100  r = r == 0 ? -1 : -r;
101  return r;
102  }
103 
104  inline int8_t pack8log(double x, double lmin, double lmax, uint8_t base = 128) {
105  if (base > 128)
106  base = 128;
107  const double l = std::log(std::abs(x));
108  const double centered = (l - lmin) / (lmax - lmin) * base;
109  int8_t r = centered;
110  if (centered >= base - 1)
111  r = base - 1;
112  if (centered < 0)
113  r = 0;
114  if (x < 0)
115  r = r == 0 ? -1 : -r;
116  return r;
117  }
118 
121  inline int8_t pack8logClosed(double x, double lmin, double lmax, uint8_t base = 128) {
122  if (base > 128)
123  base = 128;
124  const double l = std::log(std::abs(x));
125  const double centered = (l - lmin) / (lmax - lmin) * (base - 1);
126  int8_t r = round(centered);
127  if (centered >= base - 1)
128  r = base - 1;
129  if (centered < 0)
130  r = 0;
131  if (x < 0)
132  r = r == 0 ? -1 : -r;
133  return r;
134  }
135 
136  inline double unpack8log(int8_t i, double lmin, double lmax, uint8_t base = 128) {
137  if (base > 128)
138  base = 128;
139  const double basef = base;
140  const double l = lmin + std::abs(i) / basef * (lmax - lmin);
141  const double val = std::exp(l);
142  if (i < 0)
143  return -val;
144  else
145  return val;
146  }
147 
149  inline double unpack8logClosed(int8_t i, double lmin, double lmax, uint8_t base = 128) {
150  if (base > 128)
151  base = 128;
152  const double basef = base - 1;
153  double l = lmin + std::abs(i) / basef * (lmax - lmin);
154  if (std::abs(i) == base - 1)
155  l = lmax;
156  const double val = std::exp(l);
157  if (i < 0)
158  return -val;
159  else
160  return val;
161  }
162 
163 } // namespace logintpack
164 #endif
constexpr int32_t ceil(float num)
double unpack8log(int8_t i, double lmin, double lmax, uint8_t base=128)
int8_t pack8log(double x, double lmin, double lmax, uint8_t base=128)
double unpack16log(int16_t i, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:62
constexpr int8_t smallestNegative
Definition: liblogintpack.h:11
int8_t pack8logCeil(double x, double lmin, double lmax, uint8_t base=128)
Definition: liblogintpack.h:89
double unpack16logClosed(int16_t i, double lmin, double lmax, uint16_t base=32768)
reverse of pack8logClosed
Definition: liblogintpack.h:75
int8_t pack8logClosed(double x, double lmin, double lmax, uint8_t base=128)
int16_t pack16logClosed(double x, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr int8_t smallestPositive
Definition: liblogintpack.h:8
double unpack8logClosed(int8_t i, double lmin, double lmax, uint8_t base=128)
reverse of pack8logClosed
float x
int16_t pack16log(double x, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:27
int16_t pack16logCeil(double x, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:12