File indexing completed on 2024-04-06 12:04:44
0001 #include <cppunit/extensions/HelperMacros.h>
0002 #include <iostream>
0003 #include <iomanip>
0004 #include <limits>
0005
0006 #include "DataFormats/Math/interface/liblogintpack.h"
0007
0008 class testlogintpack : public CppUnit::TestFixture {
0009 CPPUNIT_TEST_SUITE(testlogintpack);
0010
0011 CPPUNIT_TEST(test16base11);
0012 CPPUNIT_TEST(test8);
0013
0014 CPPUNIT_TEST_SUITE_END();
0015
0016 public:
0017 void setUp() {}
0018 void tearDown() {}
0019
0020 void test16base11();
0021 void test8();
0022
0023 private:
0024 };
0025
0026 namespace {
0027 int16_t pack16base11(double x) { return logintpack::pack16log(x, -15, 0, 1 << 11); }
0028 int16_t pack16base11ceil(double x) { return logintpack::pack16logCeil(x, -15, 0, 1 << 11); }
0029 int16_t pack16base11closed(double x) { return logintpack::pack16logClosed(x, -15, 0, 1 << 11); }
0030 double unpack16base11(int16_t x) { return logintpack::unpack16log(x, -15, 0, 1 << 11); }
0031 double unpack16base11closed(int16_t x) { return logintpack::unpack16logClosed(x, -15, 0, 1 << 11); }
0032
0033 int8_t pack(double x) { return logintpack::pack8log(x, -15, 0); }
0034 int8_t packceil(double x) { return logintpack::pack8logCeil(x, -15, 0); }
0035 int8_t packclosed(double x) { return logintpack::pack8log(x, -15, 0); }
0036 double unpack(int8_t x) { return logintpack::unpack8log(x, -15, 0); }
0037 double unpackclosed(int8_t x) { return logintpack::unpack8logClosed(x, -15, 0); }
0038 }
0039
0040 void testlogintpack::test16base11() {
0041 constexpr uint16_t base = 1 << 11;
0042
0043 constexpr int16_t smallestPositive = 0;
0044 constexpr int16_t smallestNegative = -1;
0045 constexpr int16_t largestPositive = base - 1;
0046 constexpr int16_t largestNegative = -largestPositive;
0047
0048 union {
0049 float flt;
0050 uint32_t i32;
0051 } conv32;
0052 union {
0053 double flt;
0054 uint64_t i64;
0055 } conv64;
0056
0057 const double smallestValuePos = std::exp(-15.);
0058 const double smallestValueNeg = -std::exp(-15. + 1. / base * 15.);
0059 const double smallestValueNegForClosed = -std::exp(-15. + 1. / (base - 1) * 15.);
0060 CPPUNIT_ASSERT(pack16base11(smallestValuePos) == smallestPositive);
0061 CPPUNIT_ASSERT(pack16base11ceil(smallestValuePos) == smallestPositive);
0062 CPPUNIT_ASSERT(pack16base11closed(smallestValuePos) == smallestPositive);
0063 CPPUNIT_ASSERT(unpack16base11(smallestPositive) == smallestValuePos);
0064 CPPUNIT_ASSERT(unpack16base11closed(smallestPositive) == smallestValuePos);
0065
0066 CPPUNIT_ASSERT(pack16base11(smallestValueNeg) == smallestNegative);
0067 CPPUNIT_ASSERT(pack16base11ceil(smallestValueNeg) == smallestNegative);
0068 CPPUNIT_ASSERT(unpack16base11(smallestNegative) == smallestValueNeg);
0069 CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNeg)) == smallestValueNeg);
0070 CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNeg)) == smallestValueNeg);
0071 CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegForClosed)) == smallestValueNegForClosed);
0072
0073 CPPUNIT_ASSERT(pack16base11(smallestValuePos - std::exp(-16.)) == smallestPositive);
0074 CPPUNIT_ASSERT(pack16base11ceil(smallestValuePos - std::exp(-16.)) == smallestPositive);
0075 CPPUNIT_ASSERT(pack16base11closed(smallestValuePos - std::exp(-16.)) == smallestPositive);
0076 conv64.flt = smallestValuePos;
0077 conv64.i64 -= 1;
0078 const double smallestValuePosMinus1Ulp64 = conv64.flt;
0079 CPPUNIT_ASSERT(pack16base11(smallestValuePosMinus1Ulp64) == smallestPositive);
0080 CPPUNIT_ASSERT(pack16base11ceil(smallestValuePosMinus1Ulp64) == smallestPositive);
0081 CPPUNIT_ASSERT(pack16base11closed(smallestValuePosMinus1Ulp64) == smallestPositive);
0082
0083 CPPUNIT_ASSERT(pack16base11(smallestValueNeg + std::exp(-16.)) == smallestNegative);
0084 CPPUNIT_ASSERT(pack16base11ceil(smallestValueNeg + std::exp(-16.)) == smallestNegative);
0085 CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNeg + std::exp(-16.))) == smallestValueNeg);
0086 CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNeg + std::exp(-16.))) == smallestValueNeg);
0087 CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegForClosed + std::exp(-16.))) ==
0088 smallestValueNegForClosed);
0089 conv64.flt = smallestValueNeg;
0090 conv64.i64 += 1;
0091 const double smallestValueNegPlusUlp64 = conv64.flt;
0092 CPPUNIT_ASSERT(pack16base11(smallestValueNegPlusUlp64) == smallestNegative);
0093 CPPUNIT_ASSERT(pack16base11ceil(smallestValueNegPlusUlp64) == smallestNegative);
0094 CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNegPlusUlp64)) == smallestValueNeg);
0095 CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNegPlusUlp64)) == smallestValueNeg);
0096 CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegPlusUlp64)) == smallestValueNegForClosed);
0097
0098 const double largestValuePos = std::exp(-15. + double(base - 1) / base * 15.);
0099 const double largestValueNeg = -largestValuePos;
0100 CPPUNIT_ASSERT(pack16base11(largestValuePos) == largestPositive);
0101 CPPUNIT_ASSERT(pack16base11ceil(largestValuePos) == largestPositive);
0102 CPPUNIT_ASSERT(unpack16base11(largestPositive) == largestValuePos);
0103
0104 CPPUNIT_ASSERT(pack16base11(largestValueNeg) == largestNegative);
0105 CPPUNIT_ASSERT(pack16base11ceil(largestValueNeg) == largestNegative);
0106 CPPUNIT_ASSERT(unpack16base11(largestNegative) == largestValueNeg);
0107
0108 CPPUNIT_ASSERT(pack16base11(largestValuePos + 0.1) == largestPositive);
0109 CPPUNIT_ASSERT(pack16base11ceil(largestValuePos + 0.1) == largestPositive);
0110
0111 CPPUNIT_ASSERT(pack16base11(largestValueNeg - 0.1) == largestNegative);
0112 CPPUNIT_ASSERT(pack16base11ceil(largestValueNeg - 0.1) == largestNegative);
0113
0114 const double largestValueClosedPos = std::exp(0.);
0115 const double largestValueClosedNeg = -largestValueClosedPos;
0116 CPPUNIT_ASSERT(pack16base11closed(largestValueClosedPos) == largestPositive);
0117 CPPUNIT_ASSERT(unpack16base11closed(largestPositive) == largestValueClosedPos);
0118 CPPUNIT_ASSERT(pack16base11closed(largestValueClosedNeg) == largestNegative);
0119 CPPUNIT_ASSERT(unpack16base11closed(largestNegative) == largestValueClosedNeg);
0120
0121 CPPUNIT_ASSERT(pack16base11closed(largestValueClosedPos + 0.1) == largestPositive);
0122 CPPUNIT_ASSERT(pack16base11closed(largestValueClosedNeg - 0.1) == largestNegative);
0123
0124 const double someValue = std::exp(-15. + 1. / base * 15.);
0125 const float someValueFloat = std::exp(-15.f + 1.f / float(base) * 15.f);
0126 CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(someValue)) == someValue);
0127 CPPUNIT_ASSERT(static_cast<float>(unpack16base11(pack16base11ceil(someValue))) == someValueFloat);
0128
0129 conv32.flt = someValueFloat;
0130 conv32.i32 += 1;
0131 const float someValuePlus1Ulp32 = conv32.flt;
0132 CPPUNIT_ASSERT(static_cast<float>(unpack16base11(pack16base11ceil(someValuePlus1Ulp32))) >= someValuePlus1Ulp32);
0133
0134 conv64.flt = someValue;
0135 conv64.i64 += 1;
0136 const float someValuePlus1Ulp64 = conv64.flt;
0137 CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(someValuePlus1Ulp64)) >= someValuePlus1Ulp64);
0138 }
0139
0140 void testlogintpack::test8() {
0141 using logintpack::smallestNegative;
0142 using logintpack::smallestPositive;
0143 constexpr int8_t largestPositive = 127;
0144 constexpr int8_t largestNegative = -127;
0145
0146 const double smallestValuePos = std::exp(-15.);
0147 const double smallestValueNeg = -std::exp(-15. + 1. / 128. * 15.);
0148 const double smallestValueNegForClosed = -std::exp(-15. + 1. / 127. * 15.);
0149 CPPUNIT_ASSERT(pack(smallestValuePos) == smallestPositive);
0150 CPPUNIT_ASSERT(packceil(smallestValuePos) == smallestPositive);
0151 CPPUNIT_ASSERT(packclosed(smallestValuePos) == smallestPositive);
0152 CPPUNIT_ASSERT(unpack(smallestPositive) == smallestValuePos);
0153 CPPUNIT_ASSERT(unpackclosed(smallestPositive) == smallestValuePos);
0154
0155 CPPUNIT_ASSERT(pack(smallestValueNeg) == smallestNegative);
0156 CPPUNIT_ASSERT(packceil(smallestValueNeg) == smallestNegative);
0157 CPPUNIT_ASSERT(unpack(smallestNegative) == smallestValueNeg);
0158 CPPUNIT_ASSERT(unpack(pack(smallestValueNeg)) == smallestValueNeg);
0159 CPPUNIT_ASSERT(unpack(packceil(smallestValueNeg)) == smallestValueNeg);
0160 CPPUNIT_ASSERT(unpackclosed(packclosed(smallestValueNegForClosed)) == smallestValueNegForClosed);
0161
0162 const double largestValuePos = std::exp(-15. + 127. / 128. * 15.);
0163 const double largestValueNeg = -largestValuePos;
0164 CPPUNIT_ASSERT(pack(largestValuePos) == largestPositive);
0165 CPPUNIT_ASSERT(packceil(largestValuePos) == largestPositive);
0166 CPPUNIT_ASSERT(unpack(largestPositive) == largestValuePos);
0167
0168 CPPUNIT_ASSERT(pack(largestValueNeg) == largestNegative);
0169 CPPUNIT_ASSERT(packceil(largestValueNeg) == largestNegative);
0170 CPPUNIT_ASSERT(unpack(largestNegative) == largestValueNeg);
0171
0172 const double largestValueClosedPos = std::exp(0.);
0173 const double largestValueClosedNeg = -largestValueClosedPos;
0174 CPPUNIT_ASSERT(packclosed(largestValueClosedPos) == largestPositive);
0175 CPPUNIT_ASSERT(unpackclosed(largestPositive) == largestValueClosedPos);
0176 CPPUNIT_ASSERT(packclosed(largestValueClosedNeg) == largestNegative);
0177 CPPUNIT_ASSERT(unpackclosed(largestNegative) == largestValueClosedNeg);
0178
0179 const double someValue = std::exp(-15. + 1 / 128. * 15.);
0180 const float someValueFloat = std::exp(-15.f + 1 / 128.f * 15.f);
0181 CPPUNIT_ASSERT(unpack(packceil(someValue)) == someValue);
0182 CPPUNIT_ASSERT(static_cast<float>(unpack(packceil(someValue))) == someValueFloat);
0183 {
0184 union {
0185 float flt;
0186 uint32_t i32;
0187 } conv;
0188 conv.flt = someValueFloat;
0189 conv.i32 += 1;
0190 const float someValuePlus1Ulp32 = conv.flt;
0191 CPPUNIT_ASSERT(static_cast<float>(unpack(packceil(someValuePlus1Ulp32))) >= someValuePlus1Ulp32);
0192 }
0193 {
0194 union {
0195 double flt;
0196 uint64_t i64;
0197 } conv;
0198 conv.flt = someValue;
0199 conv.i64 += 1;
0200 const float someValuePlus1Ulp64 = conv.flt;
0201 CPPUNIT_ASSERT(unpack(packceil(someValuePlus1Ulp64)) >= someValuePlus1Ulp64);
0202 }
0203 }
0204
0205 CPPUNIT_TEST_SUITE_REGISTRATION(testlogintpack);