arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/spqlios/lib/test/spqlios_zn_conversions_test.cpp
spqlios/lib/test/spqlios_zn_conversions_test.cppRaw
  1#include <gtest/gtest.h>
  2#include <spqlios/arithmetic/zn_arithmetic_private.h>
  3
  4#include "testlib/test_commons.h"
  5
  6template <typename SRC_T, typename DST_T>
  7static void test_conv(void (*conv_f)(const MOD_Z*, DST_T* res, uint64_t res_size, const SRC_T* a, uint64_t a_size),
  8                      DST_T (*ideal_conv_f)(SRC_T x), SRC_T (*random_f)()) {
  9  MOD_Z* module = new_z_module_info(DEFAULT);
 10  for (uint64_t a_size : {0, 1, 2, 42}) {
 11    for (uint64_t res_size : {0, 1, 2, 42}) {
 12      for (uint64_t trials = 0; trials < 100; ++trials) {
 13        std::vector<SRC_T> a(a_size);
 14        std::vector<DST_T> res(res_size);
 15        uint64_t msize = std::min(a_size, res_size);
 16        for (SRC_T& x : a) x = random_f();
 17        conv_f(module, res.data(), res_size, a.data(), a_size);
 18        for (uint64_t i = 0; i < msize; ++i) {
 19          DST_T expect = ideal_conv_f(a[i]);
 20          DST_T actual = res[i];
 21          ASSERT_EQ(expect, actual);
 22        }
 23        for (uint64_t i = msize; i < res_size; ++i) {
 24          DST_T expect = 0;
 25          SRC_T actual = res[i];
 26          ASSERT_EQ(expect, actual);
 27        }
 28      }
 29    }
 30  }
 31  delete_z_module_info(module);
 32}
 33
 34static int32_t ideal_dbl_to_tn32(double a) {
 35  double _2p32 = INT64_C(1) << 32;
 36  double a_mod_1 = a - rint(a);
 37  int64_t t = rint(a_mod_1 * _2p32);
 38  return int32_t(t);
 39}
 40
 41static double random_f64_10() { return uniform_f64_bounds(-10, 10); }
 42
 43static void test_dbl_to_tn32(DBL_TO_TN32_F dbl_to_tn32_f) {
 44  test_conv(dbl_to_tn32_f, ideal_dbl_to_tn32, random_f64_10);
 45}
 46
 47TEST(zn_arithmetic, dbl_to_tn32) { test_dbl_to_tn32(dbl_to_tn32); }
 48TEST(zn_arithmetic, dbl_to_tn32_ref) { test_dbl_to_tn32(dbl_to_tn32_ref); }
 49
 50static double ideal_tn32_to_dbl(int32_t a) {
 51  const double _2p32 = INT64_C(1) << 32;
 52  return double(a) / _2p32;
 53}
 54
 55static int32_t random_t32() { return uniform_i64_bits(32); }
 56
 57static void test_tn32_to_dbl(TN32_TO_DBL_F tn32_to_dbl_f) { test_conv(tn32_to_dbl_f, ideal_tn32_to_dbl, random_t32); }
 58
 59TEST(zn_arithmetic, tn32_to_dbl) { test_tn32_to_dbl(tn32_to_dbl); }
 60TEST(zn_arithmetic, tn32_to_dbl_ref) { test_tn32_to_dbl(tn32_to_dbl_ref); }
 61
 62static int32_t ideal_dbl_round_to_i32(double a) { return int32_t(rint(a)); }
 63
 64static double random_dbl_explaw_18() { return uniform_f64_bounds(-1., 1.) * pow(2., uniform_u64_bits(6) % 19); }
 65
 66static void test_dbl_round_to_i32(DBL_ROUND_TO_I32_F dbl_round_to_i32_f) {
 67  test_conv(dbl_round_to_i32_f, ideal_dbl_round_to_i32, random_dbl_explaw_18);
 68}
 69
 70TEST(zn_arithmetic, dbl_round_to_i32) { test_dbl_round_to_i32(dbl_round_to_i32); }
 71TEST(zn_arithmetic, dbl_round_to_i32_ref) { test_dbl_round_to_i32(dbl_round_to_i32_ref); }
 72
 73static double ideal_i32_to_dbl(int32_t a) { return double(a); }
 74
 75static int32_t random_i32_explaw_18() { return uniform_i64_bits(uniform_u64_bits(6) % 19); }
 76
 77static void test_i32_to_dbl(I32_TO_DBL_F i32_to_dbl_f) {
 78  test_conv(i32_to_dbl_f, ideal_i32_to_dbl, random_i32_explaw_18);
 79}
 80
 81TEST(zn_arithmetic, i32_to_dbl) { test_i32_to_dbl(i32_to_dbl); }
 82TEST(zn_arithmetic, i32_to_dbl_ref) { test_i32_to_dbl(i32_to_dbl_ref); }
 83
 84static int64_t ideal_dbl_round_to_i64(double a) { return rint(a); }
 85
 86static double random_dbl_explaw_50() { return uniform_f64_bounds(-1., 1.) * pow(2., uniform_u64_bits(7) % 51); }
 87
 88static void test_dbl_round_to_i64(DBL_ROUND_TO_I64_F dbl_round_to_i64_f) {
 89  test_conv(dbl_round_to_i64_f, ideal_dbl_round_to_i64, random_dbl_explaw_50);
 90}
 91
 92TEST(zn_arithmetic, dbl_round_to_i64) { test_dbl_round_to_i64(dbl_round_to_i64); }
 93TEST(zn_arithmetic, dbl_round_to_i64_ref) { test_dbl_round_to_i64(dbl_round_to_i64_ref); }
 94
 95static double ideal_i64_to_dbl(int64_t a) { return double(a); }
 96
 97static int64_t random_i64_explaw_50() { return uniform_i64_bits(uniform_u64_bits(7) % 51); }
 98
 99static void test_i64_to_dbl(I64_TO_DBL_F i64_to_dbl_f) {
100  test_conv(i64_to_dbl_f, ideal_i64_to_dbl, random_i64_explaw_50);
101}
102
103TEST(zn_arithmetic, i64_to_dbl) { test_i64_to_dbl(i64_to_dbl); }
104TEST(zn_arithmetic, i64_to_dbl_ref) { test_i64_to_dbl(i64_to_dbl_ref); }