File indexing completed on 2023-03-17 10:50:36
0001 #ifndef liblogintpack_h
0002 #define liblogintpack_h
0003
0004 #include <cmath>
0005 #include <cstdint>
0006
0007 namespace logintpack {
0008 constexpr int8_t smallestPositive = 0;
0009
0010
0011 constexpr int8_t smallestNegative = -1;
0012 inline int16_t pack16logCeil(double x, double lmin, double lmax, uint16_t base = 32768) {
0013 if (base > 32768)
0014 base = 32768;
0015 const double l = std::log(std::abs(x));
0016 const double centered = (l - lmin) / (lmax - lmin) * base;
0017 int16_t r = std::ceil(centered);
0018 if (centered >= base - 1)
0019 r = base - 1;
0020 if (centered < 0)
0021 r = 0;
0022 if (x < 0)
0023 r = r == 0 ? -1 : -r;
0024 return r;
0025 }
0026
0027 inline int16_t pack16log(double x, double lmin, double lmax, uint16_t base = 32768) {
0028 if (base > 32768)
0029 base = 32768;
0030 const float delta = (log(1. + exp((lmax - lmin) / base)) - log(2.)) * base / (lmax - lmin);
0031 const double l = std::log(std::abs(x));
0032 const double centered = (l - lmin) / (lmax - lmin) * base;
0033 int16_t r = std::floor(centered);
0034 if (centered - r > delta)
0035 r += 1;
0036 if (centered >= base - 1)
0037 r = base - 1;
0038 if (centered < 0)
0039 r = 0;
0040 if (x < 0)
0041 r = r == 0 ? -1 : -r;
0042 return r;
0043 }
0044
0045
0046
0047 inline int16_t pack16logClosed(double x, double lmin, double lmax, uint16_t base = 32768) {
0048 if (base > 32768)
0049 base = 32768;
0050 const double l = std::log(std::abs(x));
0051 const double centered = (l - lmin) / (lmax - lmin) * (base - 1);
0052 int16_t r = round(centered);
0053 if (centered >= base - 1)
0054 r = base - 1;
0055 if (centered < 0)
0056 r = 0;
0057 if (x < 0)
0058 r = r == 0 ? -1 : -r;
0059 return r;
0060 }
0061
0062 inline double unpack16log(int16_t i, double lmin, double lmax, uint16_t base = 32768) {
0063 if (base > 32768)
0064 base = 32768;
0065 const double basef = base;
0066 const double l = lmin + std::abs(i) / basef * (lmax - lmin);
0067 const double val = std::exp(l);
0068 if (i < 0)
0069 return -val;
0070 else
0071 return val;
0072 }
0073
0074
0075 inline double unpack16logClosed(int16_t i, double lmin, double lmax, uint16_t base = 32768) {
0076 if (base > 32768)
0077 base = 32768;
0078 const double basef = base - 1;
0079 double l = lmin + std::abs(i) / basef * (lmax - lmin);
0080 if (std::abs(i) == base - 1)
0081 l = lmax;
0082 const double val = std::exp(l);
0083 if (i < 0)
0084 return -val;
0085 else
0086 return val;
0087 }
0088
0089 inline int8_t pack8logCeil(double x, double lmin, double lmax, uint8_t base = 128) {
0090 if (base > 128)
0091 base = 128;
0092 const double l = std::log(std::abs(x));
0093 const double centered = (l - lmin) / (lmax - lmin) * base;
0094 int8_t r = std::ceil(centered);
0095 if (centered >= base - 1)
0096 r = base - 1;
0097 if (centered < 0)
0098 r = 0;
0099 if (x < 0)
0100 r = r == 0 ? -1 : -r;
0101 return r;
0102 }
0103
0104 inline int8_t pack8log(double x, double lmin, double lmax, uint8_t base = 128) {
0105 if (base > 128)
0106 base = 128;
0107 const double l = std::log(std::abs(x));
0108 const double centered = (l - lmin) / (lmax - lmin) * base;
0109 int8_t r = centered;
0110 if (centered >= base - 1)
0111 r = base - 1;
0112 if (centered < 0)
0113 r = 0;
0114 if (x < 0)
0115 r = r == 0 ? -1 : -r;
0116 return r;
0117 }
0118
0119
0120
0121 inline int8_t pack8logClosed(double x, double lmin, double lmax, uint8_t base = 128) {
0122 if (base > 128)
0123 base = 128;
0124 const double l = std::log(std::abs(x));
0125 const double centered = (l - lmin) / (lmax - lmin) * (base - 1);
0126 int8_t r = round(centered);
0127 if (centered >= base - 1)
0128 r = base - 1;
0129 if (centered < 0)
0130 r = 0;
0131 if (x < 0)
0132 r = r == 0 ? -1 : -r;
0133 return r;
0134 }
0135
0136 inline double unpack8log(int8_t i, double lmin, double lmax, uint8_t base = 128) {
0137 if (base > 128)
0138 base = 128;
0139 const double basef = base;
0140 const double l = lmin + std::abs(i) / basef * (lmax - lmin);
0141 const double val = std::exp(l);
0142 if (i < 0)
0143 return -val;
0144 else
0145 return val;
0146 }
0147
0148
0149 inline double unpack8logClosed(int8_t i, double lmin, double lmax, uint8_t base = 128) {
0150 if (base > 128)
0151 base = 128;
0152 const double basef = base - 1;
0153 double l = lmin + std::abs(i) / basef * (lmax - lmin);
0154 if (std::abs(i) == base - 1)
0155 l = lmax;
0156 const double val = std::exp(l);
0157 if (i < 0)
0158 return -val;
0159 else
0160 return val;
0161 }
0162
0163 }
0164 #endif