void assign_keys(double insert_prob, int n_parties, int num_keys, std::unordered_map<key_type, std::vector<int> >& key_assignments) { std::unordered_set<key_type> all_keys; generate_distinct_keys(num_keys, all_keys); assign_keys( insert_prob, n_parties, all_keys, key_assignments); }
//---- Assign Huffman Keys to Nodes in Tree ---- double assign_keys(const void *nodes, int arity) { struct node *root = ((struct node *) nodes); double expected_code_length = 0; for (int i = arity - 1; i >= 0; i--) { if (root->children[i] != 0) { root->children[i]->key = (double) concatenate_numbers((unsigned) root->key,(unsigned) i); expected_code_length += assign_keys(root->children[i], arity); } else if (root->probability != 0) { //printf("Item with probability %f has key %d\n", root->probability, (int) root->key); expected_code_length += (root->probability * (int) length_of_number((unsigned) root->key)); return expected_code_length; } } return expected_code_length; }
int main(int argc, char** argv) { srand(time(NULL)); double distribution_of_characters[6] = {0}; double theoretical_distribution[] = {1.0/21, 2.0/21, 3.0/21, 4.0/21, 5.0/21, 6.0/21}; char *generated_characters = malloc(atoi(argv[argc-1])*sizeof(char)); for (int i = 2; i < 5; i++) { int arity = i; printf("\nArity :=\t%d\n\n", arity); for (int i = 0; i < atoi(argv[argc-1]); i++) { generated_characters[i] = static_gen_pmf(); distribution_of_characters[(int)(generated_characters[i] - 'a')]++; //static_gen_pmf must return values >= 'a' } for (int i = 0; i < sizeof(distribution_of_characters)/sizeof(*distribution_of_characters); i++) { distribution_of_characters[i] /= (double)(atof(argv[argc-1])); } //---- Initialize base nodes ---- int base_nodes = arity + ceil(((sizeof(distribution_of_characters)/sizeof(*distribution_of_characters)) - (double) arity)/(arity - 1))*(arity - 1); struct node *nodes = calloc(2 * base_nodes, sizeof(struct node)); if (!nodes) { printf("Failed to allocate memory\n"); return 1;} for (int i = 0; i < base_nodes; i++){ if (i < (sizeof(distribution_of_characters)/sizeof(*distribution_of_characters))) { nodes[i].probability = distribution_of_characters[i]; nodes[i].value = (i + 'a'); } else { nodes[i].probability = 0; } } //---- Create Node Tree ---- while (base_nodes != 1) { qsort(nodes, base_nodes, sizeof(*nodes), compare_struct_node); nodes[base_nodes].probability = 0; for (int i = 0; i < arity; i++) { nodes[base_nodes].probability += nodes[i].probability; nodes[base_nodes].children[i] = &nodes[i]; nodes[base_nodes].value = (char) 0; nodes[i].parent = &nodes[base_nodes]; } for(int i = 0; i < arity; i++){ nodes++; } base_nodes -= (arity - 1); } //---- Calculate Entropy of PMF ---- double entropy = 0; for (int i = 0; i < sizeof(theoretical_distribution)/sizeof(*theoretical_distribution); i++) { entropy -= (theoretical_distribution[i] * (log10(theoretical_distribution[i])/log10(arity))); } printf("Entropy of Distribution:\t%f\n", entropy); printf("Expected Average Length:\t%f\n", assign_keys(nodes, arity)); //---- Encode and decode string ---- double encoding[atoi(argv[argc-1])]; char decoded_string[atoi(argv[argc-1])]; double average_size = encode(nodes, generated_characters, sizeof(generated_characters)/sizeof(*generated_characters), encoding); decode(nodes, encoding, sizeof(encoding)/sizeof(*encoding), decoded_string); printf("Actual Average Length:\t\t%f\n", average_size); for (int i = 0; i < atoi(argv[argc-1]); i++) { if (decoded_string[i] != generated_characters[i]) break; if (i == atoi(argv[argc-1]) - 1) printf("Successfully decoded encoded string\n"); } } return 0; }