diff options
author | David Robillard <d@drobilla.net> | 2018-08-19 14:58:14 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:48:47 +0200 |
commit | b5954ef2de4f205108be0cf5a06f88540194bed9 (patch) | |
tree | 5d19d1398f73a74405231ea59ccda06bcf510b86 | |
parent | bc2836d41e4de1899e5aa649db849befc9dfa109 (diff) | |
download | chilbert-b5954ef2de4f205108be0cf5a06f88540194bed9.tar.gz chilbert-b5954ef2de4f205108be0cf5a06f88540194bed9.tar.bz2 chilbert-b5954ef2de4f205108be0cf5a06f88540194bed9.zip |
Tighten up size constraints
-rw-r--r-- | chilbert/GrayCodeRank.hpp | 19 | ||||
-rw-r--r-- | test/test_gray_code_rank.cpp | 47 | ||||
-rw-r--r-- | test/test_hilbert.cpp | 6 | ||||
-rw-r--r-- | test/test_utils.hpp | 2 |
4 files changed, 40 insertions, 34 deletions
diff --git a/chilbert/GrayCodeRank.hpp b/chilbert/GrayCodeRank.hpp index adb953a..1e3895f 100644 --- a/chilbert/GrayCodeRank.hpp +++ b/chilbert/GrayCodeRank.hpp @@ -21,6 +21,7 @@ #include <cassert> #include <cstddef> +#include <numeric> namespace chilbert { @@ -37,6 +38,9 @@ compactIndex(const size_t* const ms, H& h, HC& hc) { + assert(h.size() >= n * m); + assert(hc.size() >= std::accumulate(ms, ms + n, size_t(0))); + resetBits(hc); auto hm = h.mask(0); @@ -67,6 +71,10 @@ template <class I> inline void grayCodeRank(const I& mask, const I& gi, const size_t n, I& r) { + assert(mask.size() == n); + assert(gi.size() == n); + assert(r.size() == n); + r.reset(); auto mi = mask.begin(); @@ -93,13 +101,15 @@ grayCodeRankInv(const I& mask, I& g, I& gi) { + assert(mask.size() == n); + assert(ptrn.size() == n); + assert(r.size() == n); + assert(g.size() == n); + assert(gi.size() == n); + g.reset(); gi.reset(); - assert(ptrn.size() == mask.size()); - assert(g.size() == mask.size()); - assert(gi.size() == mask.size()); - auto m = mask.mask(n - 1); auto ri = r.begin(b - 1); @@ -145,6 +155,7 @@ extractMask(const size_t* const ms, size_t& b) { assert(0 <= d && d < n); + assert(mask.size() == n); mask.reset(); b = 0; diff --git a/test/test_gray_code_rank.cpp b/test/test_gray_code_rank.cpp index 7980bf3..a421159 100644 --- a/test/test_gray_code_rank.cpp +++ b/test/test_gray_code_rank.cpp @@ -31,11 +31,11 @@ #include <iostream> #include <iterator> -template <class T, size_t N, size_t D> +template <class T, size_t Max, size_t D> T get_mask(const std::array<size_t, D>& ms, const size_t d, const size_t step) { - T mask = make_zero_bitvec<T, N>(); + T mask = make_zero_bitvec<T, D>(); size_t b; chilbert::extractMask(ms.data(), D, d, step, mask, b); @@ -44,15 +44,15 @@ get_mask(const std::array<size_t, D>& ms, const size_t d, const size_t step) return mask; } -template <class T, size_t N, size_t D> +template <class T, size_t Max, size_t D> void test_extract_mask(Context& ctx) { for (size_t d = 0; d < D; ++d) { - const auto ms = make_random_precisions<N, D>(ctx); + const auto ms = make_random_precisions<Max, D>(ctx); const auto max_m = *std::max_element(std::begin(ms), std::end(ms)); const size_t step = rand_between(ctx, 0, max_m); - const auto mask = get_mask<T, N>(ms, d, step); + const auto mask = get_mask<T, D>(ms, d, step); for (size_t i = 0; i < D; ++i) { assert(mask.test(i) == (ms[(d + i) % D] > step)); @@ -60,20 +60,17 @@ test_extract_mask(Context& ctx) } } -template <class T, size_t N, size_t D> +template <class T, size_t Max, size_t D> void test_gray_code_rank(Context& ctx) { for (size_t d = 0; d < D; ++d) { // Generate random mask - const auto ms = make_random_precisions<N, D>(ctx); - const auto max_m = *std::max_element(std::begin(ms), std::end(ms)); - const size_t step = rand_between(ctx, 0, max_m); - const auto mask = get_mask<T, N>(ms, d, step); + const auto mask = make_random_bitvec<T, D>(ctx); // Generate two random values and their gray codes - const auto a = make_random_bitvec<T, N>(ctx); - const auto b = make_random_bitvec<T, N>(ctx); + const auto a = make_random_bitvec<T, D>(ctx); + const auto b = make_random_bitvec<T, D>(ctx); auto ga = a; grayCode(ga); @@ -82,19 +79,17 @@ test_gray_code_rank(Context& ctx) grayCode(gb); // Calculate gray code ranks - auto ra = make_zero_bitvec<T, N>(); + auto ra = make_zero_bitvec<T, D>(); chilbert::grayCodeRank(mask, ga, D, ra); - auto rb = make_zero_bitvec<T, N>(); + auto rb = make_zero_bitvec<T, D>(); chilbert::grayCodeRank(mask, gb, D, rb); // Ensure ranks have at most mask.count() bits - if (mask.count() < N) { - auto max = make_zero_bitvec<T, N>(); - setBit(max, mask.count(), 1); - assert(ra < max); - assert(rb < max); - } + auto max = make_zero_bitvec<T, D>(); + setBit(max, mask.count(), 1); + assert(ra < max); + assert(rb < max); // Test fundamental property of gray code ranks const auto mga = ga & mask; @@ -103,8 +98,8 @@ test_gray_code_rank(Context& ctx) // Test inversion const auto pat = ~mask; - auto ga_out = make_zero_bitvec<T, N>(); - auto gag_out = make_zero_bitvec<T, N>(); + auto ga_out = make_zero_bitvec<T, D>(); + auto gag_out = make_zero_bitvec<T, D>(); grayCodeRankInv(mask, pat, ra, D, mask.count(), gag_out, ga_out); assert((ga_out & mask) == (ga & mask)); @@ -114,12 +109,12 @@ test_gray_code_rank(Context& ctx) } } -template <class T, size_t N, size_t D> +template <class T, size_t Max, size_t D> void test(Context& ctx) { - test_extract_mask<T, N, D>(ctx); - test_gray_code_rank<T, N, D>(ctx); + test_extract_mask<T, Max, D>(ctx); + test_gray_code_rank<T, Max, D>(ctx); } int @@ -140,7 +135,7 @@ main() test<chilbert::CBigBitVec, 64, 33>(ctx); test<chilbert::CBigBitVec, 64, 60>(ctx); test<chilbert::CBigBitVec, 64, 64>(ctx); - test<chilbert::CBigBitVec, 128, 65>(ctx); + test<chilbert::CBigBitVec, 96, 65>(ctx); test<chilbert::CBigBitVec, 1024, 997>(ctx); return 0; diff --git a/test/test_hilbert.cpp b/test/test_hilbert.cpp index 20646a2..6a3d1b8 100644 --- a/test/test_hilbert.cpp +++ b/test/test_hilbert.cpp @@ -94,7 +94,7 @@ from_big_int(const mpz_class& num) return vec; } -template <class T, size_t M, size_t D> +template <class H, size_t M, size_t D> void test_standard(Context& ctx) { @@ -103,7 +103,7 @@ test_standard(Context& ctx) // Generate random point and its hilbert index const auto pa = make_random_point<M, D>(ctx); - T ha = make_zero_bitvec<T, D * M>(); + H ha = make_zero_bitvec<H, D * M>(); assert(ha.size() >= D * M); chilbert::coordsToIndex(pa.data(), M, D, ha); @@ -119,7 +119,7 @@ test_standard(Context& ctx) // Generate the next hilbert index const auto ib = ia + 1; - const auto hb = from_big_int<T, D * M>(ib); + const auto hb = from_big_int<H, D * M>(ib); // Unmap next hilbert index to a point auto pb = make_random_point<M, D>(ctx); diff --git a/test/test_utils.hpp b/test/test_utils.hpp index a695134..37db804 100644 --- a/test/test_utils.hpp +++ b/test/test_utils.hpp @@ -66,7 +66,7 @@ rand_between(Context& ctx, const size_t min, const size_t max) return r; } -/// Return an array of D precisions with sum at most N and each at most Max +/// Return an array of D precisions each at most Max and with sum at most N template <size_t N, size_t D, size_t Max = 64> std::array<size_t, D> make_random_precisions(Context& ctx) |