From c53d2f0603ae86447e98b697c3d86d710be8ac2d Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sun, 17 Jan 2021 18:09:31 +0100 Subject: Fixed value offset bug. Added gauss example with csmap. --- examples/csmap_ex.c | 2 +- examples/ex_gauss1.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ examples/ex_gauss2.c | 42 +++++++++++++++++++++++++++++++++++++ examples/ex_gaussian.c | 57 -------------------------------------------------- stc/csmap.h | 28 ++++++++++++------------- 5 files changed, 113 insertions(+), 73 deletions(-) create mode 100644 examples/ex_gauss1.c create mode 100644 examples/ex_gauss2.c delete mode 100644 examples/ex_gaussian.c diff --git a/examples/csmap_ex.c b/examples/csmap_ex.c index cd623b06..14d21b67 100644 --- a/examples/csmap_ex.c +++ b/examples/csmap_ex.c @@ -3,7 +3,7 @@ #include #include -using_csmap(i, int, int); +using_csmap(i, int, size_t); using_csset_str(); #include diff --git a/examples/ex_gauss1.c b/examples/ex_gauss1.c new file mode 100644 index 00000000..b9228aa5 --- /dev/null +++ b/examples/ex_gauss1.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "stc/crand.h" +#include "stc/cstr.h" +#include "stc/cmap.h" +#include "stc/cvec.h" + +// Declare int -> int hashmap. Uses typetag 'i' for ints. +using_cmap(i, int, size_t); + +// Declare int vector with map entries that can be sorted by map keys. +static int compare(cmap_i_value_t *a, cmap_i_value_t *b) { + return c_default_compare(&a->first, &b->first); +} +// Vector: typetag 'e' for (map) entry +using_cvec(e, cmap_i_value_t, compare); + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_init(seed); + stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); + + // Create histogram map + cmap_i mhist = cmap_i_init(); + for (size_t i = 0; i < N; ++i) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + cmap_i_emplace(&mhist, index, 0).first->second += 1; + } + + // Transfer map to vec and sort it by map keys. + cvec_e vhist = cvec_e_init(); + c_foreach (i, cmap_i, mhist) + cvec_e_push_back(&vhist, *i.ref); + cvec_e_sort(&vhist); + + // Print the gaussian bar chart + cstr_t bar = cstr_init(); + c_foreach (i, cvec_e, vhist) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, bar.str); + } + } + // Cleanup + cstr_del(&bar); + cmap_i_del(&mhist); + cvec_e_del(&vhist); +} diff --git a/examples/ex_gauss2.c b/examples/ex_gauss2.c new file mode 100644 index 00000000..7352d6a8 --- /dev/null +++ b/examples/ex_gauss2.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "stc/crand.h" +#include "stc/cstr.h" +#include "stc/csmap.h" + +// Declare int -> int sorted map. Uses typetag 'i' for ints. +using_csmap(i, int, size_t); + +int main() +{ + enum {N = 10000000}; + const double Mean = -12.0, StdDev = 6.0, Scale = 74; + + printf("Demo of gaussian / normal distribution of %d random samples\n", N); + + // Setup random engine with normal distribution. + uint64_t seed = time(NULL); + stc64_t rng = stc64_init(seed); + stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); + + // Create histogram map + csmap_i mhist = csmap_i_init(); + for (size_t i = 0; i < N; ++i) { + int index = (int) round( stc64_normalf(&rng, &dist) ); + ++ csmap_i_emplace(&mhist, index, 0).first->second; + } + + // Print the gaussian bar chart + cstr_t bar = cstr_init(); + c_foreach (i, csmap_i, mhist) { + size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N); + if (n > 0) { + cstr_resize(&bar, n, '*'); + printf("%4d %s\n", i.ref->first, bar.str); + } + } + // Cleanup + cstr_del(&bar); + csmap_i_del(&mhist); +} diff --git a/examples/ex_gaussian.c b/examples/ex_gaussian.c deleted file mode 100644 index b9228aa5..00000000 --- a/examples/ex_gaussian.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include "stc/crand.h" -#include "stc/cstr.h" -#include "stc/cmap.h" -#include "stc/cvec.h" - -// Declare int -> int hashmap. Uses typetag 'i' for ints. -using_cmap(i, int, size_t); - -// Declare int vector with map entries that can be sorted by map keys. -static int compare(cmap_i_value_t *a, cmap_i_value_t *b) { - return c_default_compare(&a->first, &b->first); -} -// Vector: typetag 'e' for (map) entry -using_cvec(e, cmap_i_value_t, compare); - -int main() -{ - enum {N = 10000000}; - const double Mean = -12.0, StdDev = 6.0, Scale = 74; - - printf("Demo of gaussian / normal distribution of %d random samples\n", N); - - // Setup random engine with normal distribution. - uint64_t seed = time(NULL); - stc64_t rng = stc64_init(seed); - stc64_normalf_t dist = stc64_normalf_init(Mean, StdDev); - - // Create histogram map - cmap_i mhist = cmap_i_init(); - for (size_t i = 0; i < N; ++i) { - int index = (int) round( stc64_normalf(&rng, &dist) ); - cmap_i_emplace(&mhist, index, 0).first->second += 1; - } - - // Transfer map to vec and sort it by map keys. - cvec_e vhist = cvec_e_init(); - c_foreach (i, cmap_i, mhist) - cvec_e_push_back(&vhist, *i.ref); - cvec_e_sort(&vhist); - - // Print the gaussian bar chart - cstr_t bar = cstr_init(); - c_foreach (i, cvec_e, vhist) { - size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N); - if (n > 0) { - cstr_resize(&bar, n, '*'); - printf("%4d %s\n", i.ref->first, bar.str); - } - } - // Cleanup - cstr_del(&bar); - cmap_i_del(&mhist); - cvec_e_del(&vhist); -} diff --git a/stc/csmap.h b/stc/csmap.h index ae4c862a..e64d1204 100644 --- a/stc/csmap.h +++ b/stc/csmap.h @@ -189,11 +189,10 @@ int main(void) { keyDel(KEY_REF_##C(val)); \ MAP_ONLY_##C( mappedDel(&val->second); ) \ } \ - STC_INLINE C##_##X##_value_t \ - C##_##X##_value_clone(C##_##X##_value_t val) { \ - *KEY_REF_##C(&val) = keyFromRaw(keyToRaw(KEY_REF_##C(&val))); \ - MAP_ONLY_##C( val.second = mappedFromRaw(mappedToRaw(&val.second)); ) \ - return val; \ + STC_INLINE void \ + C##_##X##_value_copy(const C##_##X##_value_t* src, C##_##X##_value_t* dst) { \ + *KEY_REF_##C(dst) = keyFromRaw(keyToRaw(KEY_REF_##C(src))); \ + MAP_ONLY_##C( dst->second = mappedFromRaw(mappedToRaw(&src->second)); ) \ } \ \ STC_API C##_##X##_node_t* C##_##X##_clone_r_(C##_##X##_node_t *tn); \ @@ -268,12 +267,12 @@ int main(void) { \ STC_INLINE void \ C##_##X##_next(C##_##X##_iter_t* it) { \ - cbst_next((csmap___iter_t*) it); \ + cbst_next((csmap___iter_t*) it, offsetof(C##_##X##_node_t, value)); \ } \ STC_INLINE C##_##X##_iter_t \ C##_##X##_begin(C##_##X* self) { \ C##_##X##_iter_t it = {NULL, 0, self->root}; \ - cbst_next((csmap___iter_t*) &it); \ + cbst_next((csmap___iter_t*) &it, offsetof(C##_##X##_node_t, value)); \ return it; \ } \ STC_INLINE C##_##X##_iter_t \ @@ -307,7 +306,7 @@ static csmap___node_t cbst_nil = {&cbst_nil, &cbst_nil, 0}; STC_API csmap___node_t* cbst_skew(csmap___node_t *tn); STC_API csmap___node_t* cbst_split(csmap___node_t *tn); -STC_API void cbst_next(csmap___iter_t *it); +STC_API void cbst_next(csmap___iter_t *it, size_t offset); /* -------------------------- IMPLEMENTATION ------------------------- */ @@ -410,7 +409,7 @@ STC_API void cbst_next(csmap___iter_t *it); cn->link[0] = C##_##X##_clone_r_(tn->link[0]); \ cn->link[1] = C##_##X##_clone_r_(tn->link[1]); \ cn->level = tn->level; \ - cn->value = C##_##X##_value_clone(tn->value); \ + C##_##X##_value_copy(&tn->value, &cn->value); \ return cn; \ } @@ -438,19 +437,18 @@ cbst_split(csmap___node_t *tn) { } STC_DEF void -cbst_next(csmap___iter_t *it) { +cbst_next(csmap___iter_t *it, size_t offset) { csmap___node_t *tn = it->_tn; - if (tn->level == 0 && it->_top == 0) - it->ref = NULL; - else { + if (tn->level || it->_top) { while (tn->level) { it->_st[it->_top++] = tn; tn = tn->link[0]; } tn = it->_st[--it->_top]; - it->ref = &tn->value; it->_tn = tn->link[1]; - } + it->ref = (csmap___value_t *) ((uint8_t *)tn + offset); + } else + it->ref = NULL; } #else -- cgit v1.2.3