print either counts or percentages
authorGeoffrey Allott <geoffrey@allott.email>
Wed, 4 Jan 2023 20:57:51 +0000 (20:57 +0000)
committerGeoffrey Allott <geoffrey@allott.email>
Wed, 4 Jan 2023 20:57:51 +0000 (20:57 +0000)
tools/entropy.c

index fc2cbe9dbc1a942004ea6d6a02424f998d824c2d..3d95c1d9fcee58e556bd95f31c69384b820a02d9 100644 (file)
@@ -6,6 +6,9 @@
 #include <stdlib.h>
 #include <string.h>
 
+#define PRINT_COUNTS      1
+#define PRINT_PERCENTAGES 2
+
 static double bit_entropy(FILE *input, int bits, int chain_len, int low_est_threshold, int print_counts)
 {
     size_t *counts;
@@ -37,16 +40,6 @@ static double bit_entropy(FILE *input, int bits, int chain_len, int low_est_thre
         }
     }
 
-    if (print_counts) {
-        for (i = 0; i < ((size_t) 1 << (bits * (chain_len - 1))); ++i) {
-            for (j = 0, subtotal = 0; j < ((size_t) 1 << bits); ++j) {
-                for (k = 0; k + 1 < (size_t) chain_len; ++k)
-                    printf("%02x ", (i >> ((size_t) bits * ((size_t) chain_len - k - 2))) & (((size_t) 1 << bits) - 1));
-                printf("%02x: %lu\n", j, counts[(i << bits) + j]);
-            }
-        }
-    }
-
     entropy = 0;
     total = 0;
     for (i = 0; i < ((size_t) 1 << (bits * (chain_len - 1))); ++i) {
@@ -67,6 +60,20 @@ static double bit_entropy(FILE *input, int bits, int chain_len, int low_est_thre
 
     entropy /= (double) (total * (size_t) bits);
 
+    if (print_counts) {
+        for (i = 0; i < ((size_t) 1 << (bits * (chain_len - 1))); ++i) {
+            for (j = 0, subtotal = 0; j < ((size_t) 1 << bits); ++j) {
+                for (k = 0; k + 1 < (size_t) chain_len; ++k)
+                    printf("%02lx ", (i >> ((size_t) bits * ((size_t) chain_len - k - 2))) & (((size_t) 1 << bits) - 1));
+                printf("%02lx: ", j);
+                if (print_counts == PRINT_PERCENTAGES)
+                    printf("%.02f%%\n", 100.0 * (double) counts[(i << bits) + j] / (double) total);
+                else
+                    printf("%lu\n", counts[(i << bits) + j]);
+            }
+        }
+    }
+
     free(counts);
     free(chain);
     return entropy;
@@ -89,6 +96,7 @@ static void usage(void)
         "    -c - Keep a markov chain `len' symbols long (default 1)\n"
         "    -t - Estimate maximal entropy if subtotal < `threshold' (default 0)\n"
         "    -p - Print all symbol counts for the file\n"
+        "    -P - Print all symbol counts for the file as a percentage\n"
     );
 }
 
@@ -97,7 +105,7 @@ int main(int argc, char *argv[])
     int opt, bits = 8, chain_len = 1, low_est_threshold = 0, print_counts = 0;
     FILE *input;
 
-    while ((opt = getopt(argc, argv, "hb:c:t:p")) != -1) {
+    while ((opt = getopt(argc, argv, "hb:c:t:pP")) != -1) {
         switch (opt) {
         case 'h':
             usage();
@@ -112,7 +120,10 @@ int main(int argc, char *argv[])
             low_est_threshold = atoi(optarg);
             break;
         case 'p':
-            print_counts = 1;
+            print_counts = PRINT_COUNTS;
+            break;
+        case 'P':
+            print_counts = PRINT_PERCENTAGES;
             break;
         default:
             usage();