On Wed, 19 Jun 2024 10:55:53 -0400 Dmitry Goncharov <dgoncha...@users.sf.net> wrote:
> On Tue, Jun 18, 2024 at 5:38 PM Sergei Trofimovich <sly...@gmail.com> wrote: > > After the change probabilities are not as biased: > > > > 0 1 2 3 > > _____ _____ _____ _____ > > 0 | 24.99 24.99 25.01 25.01 > > 1 | 24.99 25.04 24.99 24.99 > > 2 | 25.01 25.00 25.00 24.99 > > 3 | 25.01 24.98 25.00 25.01 > > > > Looks like you wrote a program to figure out these probabilities. > Should such a program be included as a part of make test suite? I wrote a one-off `a.c` printer (attached). It might be tricky to write safe ranges for probabilities: 4% is "obviously" biased, but 0.02% is trickier (PRNG / modulo bias, truncation, or expected deviation). Glancing at tests/ all the tests exercise user-facing `make` API. What would be the best way to validate probabilities? -- Sergei
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define LEN 4 static int a[LEN]; static void random_shuffle_array (void) { size_t i; for (i = 0; i < LEN; i++) { int t; /* Pick random element and swap. */ unsigned int j = rand () % LEN; if (i == j) continue; /* Swap. */ t = a[i]; a[i] = a[j]; a[j] = t; } } static void random_shuffle_array_fixed (void) { size_t i; for (i = LEN - 1; i >= 1; i--) { int t; /* Pick random element and swap. */ unsigned int j = rand () % (i + 1); if (i == j) continue; /* Swap. */ t = a[i]; a[i] = a[j]; a[j] = t; } } int main() { size_t hist[LEN][LEN]; memset(hist, 0, sizeof(hist)); srand(time(NULL)); size_t niters = 10000000; for (size_t iter = 0; iter < niters; ++iter) { for (size_t i = 0; i < LEN; ++i) a[i] = i; // random_shuffle_array (); random_shuffle_array_fixed (); for (size_t i = 0; i < LEN; ++i) hist[i][a[i]] += 1; } printf(" "); for (size_t j = 0; j < LEN; ++j) { printf(" %5zu", j); } printf("\n"); printf(" "); for (size_t j = 0; j < LEN; ++j) { printf(" _____"); } printf("\n"); for (size_t i = 0; i < LEN; ++i) { printf("%5zu |", i); for (size_t j = 0; j < LEN; ++j) { printf(" %5.2f", (double)(hist[i][j]) / (double)(niters) * 100.0); } printf("\n"); } }