diff --git a/main.c b/main.c index 39a7b67..e5c6b0c 100644 --- a/main.c +++ b/main.c @@ -5,7 +5,7 @@ #include "src/vec_match.h" #define DATA_LEN 16 -#define REF_LEN 8 +#define REF_LEN 10 static float reference[DATA_LEN] = { //0, 10, 20, 30, 40, 50, 40, 30, 20, 10, 0 @@ -14,7 +14,7 @@ static float reference[DATA_LEN] = { static float data[DATA_LEN] = { //0, 10, 20, 30, 40, 50, 50, 35, 15, 15, 0 - 0, 15.7, 0, 0, 0.1, 0.2, 0.1, 10, 24.242, 0, 0, 2, 0.2, 0.4, 0.5, 0 + 0, 15.7, 0, 0, 0.1, 0.2, 0.1, 10, 24, 0, 2, 2, 0.2, 0.4, 0.5, 0 }; static float ref_p[REF_LEN]; @@ -108,7 +108,7 @@ int main(void) printf("Error rate: ENV %.2f, ABS %.2f\n", env_e, abs_e); float thr; - int ref_pack_len = vec_pack_fit(ref_p, REF_LEN, reference, DATA_LEN, &thr); + int ref_pack_len = vec_pack_auto(ref_p, REF_LEN, reference, DATA_LEN, &thr); printf("Reference packed with zero threshold %.1f to %d items.\n", thr, ref_pack_len); printf("REF packed: "); diff --git a/main.d b/main.d index eadfba7..266d428 100644 --- a/main.d +++ b/main.d @@ -24,4 +24,4 @@ main.out: src/vec_match.c /usr/include/stdc-predef.h \ /usr/include/bits/huge_valf.h /usr/include/bits/huge_vall.h \ /usr/include/bits/inf.h /usr/include/bits/nan.h \ /usr/include/bits/mathdef.h /usr/include/bits/mathcalls.h \ - src/vec_match.h + /usr/include/string.h /usr/include/xlocale.h src/vec_match.h diff --git a/src/vec_match.c b/src/vec_match.c index 7b1dfcf..0b969f8 100644 --- a/src/vec_match.c +++ b/src/vec_match.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "vec_match.h" @@ -202,23 +203,43 @@ uint32_t vec_pack(float *result, uint32_t result_capacity, uint32_t vec_pack_auto(float *result, uint32_t result_capacity, - const float *data, uint32_t data_length, float *threshold_p) + const float *data, uint32_t data_length, float *threshold_p) { - float thr = 0; - uint32_t ref_pack_len; + // lossless case, all fits + if (data_length <= result_capacity) { + *threshold_p = 0; + memcpy(result, data, data_length * sizeof(float)); + return data_length; + } - // TODO use smarter algorithm - while(true) { + float thr = 0.1; + uint32_t ref_pack_len; + + while (true) { ref_pack_len = vec_pack(result, result_capacity, data, data_length, thr); - printf("try %f -> %d\n", thr, ref_pack_len);//FIXME remove + + //printf("try %f -> %d\n", thr, ref_pack_len); if (ref_pack_len <= result_capacity) { if (threshold_p != NULL) *threshold_p = thr; - return result_capacity; + return ref_pack_len; + } else { + float r = (result_capacity / (float)ref_pack_len); + + // experimental values, adjust to best fit your use case + if (r < 0.5) { + thr += 0.8; + } else if (r < 0.6) { + thr += 0.5; + } else if (r < 0.75) { + thr += 0.4; + } else if (r < 0.90) { + thr += 0.25; + } else { + thr += 0.1; + } } - - thr += 0.1f; } } diff --git a/src/vec_match.h b/src/vec_match.h index 965ce14..26d80c6 100644 --- a/src/vec_match.h +++ b/src/vec_match.h @@ -114,5 +114,5 @@ uint32_t vec_unpack(float *result, uint32_t result_capacity, * @param threshold_p field to store the used threshold, can be NULL * @return real result size */ -uint32_t vec_pack_fit(float *result, uint32_t result_capacity, +uint32_t vec_pack_auto(float *result, uint32_t result_capacity, const float *data, uint32_t data_length, float *threshold_p);