use std::cmp::Ordering;
use std::collections::HashMap;
use rand::prelude::*;
use rand_pcg::Pcg64;
use crate::*;
use crate::letter_distribution::*;
fn generate_ground_truth(dist: &LetterDistribution, set_letter_positions: usize) -> Vec<(Vec<usize>, f32)> {
let sorted_letter_probs: Vec<Vec<(usize, f32)>> = dist.letter_probs().iter()
.map(|factor_dist| {
let mut sorted_elements: Vec<(usize, f32)> = factor_dist.as_ref().iter().cloned().enumerate().collect();
sorted_elements.sort_by(|(_idx_a, element_a), (_idx_b, element_b)| element_b.partial_cmp(element_a).unwrap_or(Ordering::Equal));
sorted_elements
})
.collect();
let end_state = vec![set_letter_positions-1; dist.letter_count()];
let mut ground_truth = vec![];
let mut state = vec![0; dist.letter_count()];
loop {
let mut prob: f64 = 1.0;
for l in 0..dist.letter_count() {
let (letter_idx, _prob) = sorted_letter_probs[l][state[l]];
prob *= dist.letter_probs()[l][letter_idx] as f64;
}
let result: Vec<usize> = state.iter()
.enumerate()
.map(|(slot_idx, sorted_letter_idx)| sorted_letter_probs[slot_idx][*sorted_letter_idx].0)
.collect();
if prob > 0.0 {
ground_truth.push((result, prob as f32));
}
if state == end_state {
break;
}
state[0] += 1;
let mut cur_digit = 0;
while state[cur_digit] > set_letter_positions-1 {
state[cur_digit] = 0;
cur_digit += 1;
state[cur_digit] += 1;
}
}
ground_truth.sort_by(|(_, prob_a), (_, prob_b)| prob_b.partial_cmp(prob_a).unwrap_or(Ordering::Equal));
ground_truth
}
fn group_result_by_prob<T>(results: Vec<(Vec<usize>, T)>) -> HashMap<String, Vec<Vec<usize>>>
where T: core::fmt::Display
{
let mut return_map = HashMap::new();
for (result, prob) in results {
let entry_list = return_map.entry(format!("{}", prob)).or_insert(vec![]);
entry_list.push(result);
}
return_map
}
fn result_from_str(input: &str) -> Vec<usize> {
let mut result = Vec::with_capacity(input.len());
for c in input.chars() {
result.push(char_to_idx(c).unwrap())
}
result
}
fn compare_grouped_results(a_group: HashMap<String, Vec<Vec<usize>>>, b_group: HashMap<String, Vec<Vec<usize>>>) -> bool {
let mut sorted_a_group: Vec<(String, Vec<Vec<usize>>)> = a_group.into_iter().collect();
sorted_a_group.sort_by(|(key_a, _group_a), (key_b, _group_b)| key_a.partial_cmp(key_b).unwrap_or(Ordering::Equal));
let mut sorted_b_group: Vec<(String, Vec<Vec<usize>>)> = b_group.into_iter().collect();
sorted_b_group.sort_by(|(key_a, _group_a), (key_b, _group_b)| key_a.partial_cmp(key_b).unwrap_or(Ordering::Equal));
for ((_key_a, group_a), (_key_b, group_b)) in sorted_a_group.into_iter().zip(sorted_b_group.into_iter()) {
if group_a.len() != group_b.len() {
return false;
}
for key_a in group_a {
if !group_b.contains(&key_a) {
return false;
}
}
}
true
}
#[test]
fn ordered_test_0() {
let letter_probs = vec![
vec![('a', 0.8), ('b', 0.2)],
vec![('a', 0.7), ('b', 0.3)],
vec![('a', 0.6), ('b', 0.4)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(usize, (Vec<usize>, f32))> = test_dist.ordered_permutations().enumerate().collect();
for (i, (possible_word, word_prob)) in results.iter() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let result_strings: Vec<Vec<usize>> = results.into_iter().map(|(_idx, (string, _prob))| string).collect();
assert_eq!(result_strings,
vec![
result_from_str("aaa"),
result_from_str("aab"),
result_from_str("aba"),
result_from_str("abb"),
result_from_str("baa"),
result_from_str("bab"),
result_from_str("bba"),
result_from_str("bbb"),
]);
}
#[test]
fn ordered_test_1() {
let letter_probs = vec![
vec![('a', 0.7), ('b', 0.3)],
vec![('a', 0.7), ('b', 0.3)],
vec![('a', 0.7), ('b', 0.3)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(usize, (Vec<usize>, f32))> = test_dist.ordered_permutations().enumerate().collect();
for (i, (possible_word, word_prob)) in results.iter() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
assert_eq!(results.len(), 8);
}
#[test]
fn ordered_test_2() {
let letter_probs = vec![
vec![('b', 0.33), ('c', 0.33), ('h', 0.33)],
vec![('a', 1.0)],
vec![('m', 0.3), ('t', 0.7)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let grouped_results = group_result_by_prob(results);
let grouped_truth = group_result_by_prob(
vec![
(result_from_str("bat"), 0.233),
(result_from_str("cat"), 0.233),
(result_from_str("hat"), 0.233),
(result_from_str("bam"), 0.100),
(result_from_str("cam"), 0.100),
(result_from_str("ham"), 0.100),]
);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn ordered_test_3() {
let letter_probs = vec![
vec![('a', 0.4), ('b', 0.15), ('c', 0.15), ('d', 0.15), ('e', 0.15)],
vec![('a', 0.15), ('b', 0.15), ('c', 0.4), ('d', 0.15), ('e', 0.15)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let grouped_results = group_result_by_prob(results);
let grouped_truth = group_result_by_prob(
vec![
(result_from_str("ac"), 0.16),
(result_from_str("aa"), 0.06),
(result_from_str("ab"), 0.06),
(result_from_str("ad"), 0.06),
(result_from_str("ae"), 0.06),
(result_from_str("bc"), 0.06),
(result_from_str("cc"), 0.06),
(result_from_str("dc"), 0.06),
(result_from_str("ec"), 0.06),
(result_from_str("ba"), 0.0225),
(result_from_str("bb"), 0.0225),
(result_from_str("bd"), 0.0225),
(result_from_str("be"), 0.0225),
(result_from_str("ca"), 0.0225),
(result_from_str("cb"), 0.0225),
(result_from_str("cd"), 0.0225),
(result_from_str("ce"), 0.0225),
(result_from_str("da"), 0.0225),
(result_from_str("db"), 0.0225),
(result_from_str("dd"), 0.0225),
(result_from_str("de"), 0.0225),
(result_from_str("ea"), 0.0225),
(result_from_str("eb"), 0.0225),
(result_from_str("ed"), 0.0225),
(result_from_str("ee"), 0.0225),
]
);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn ordered_test_4() {
let mut rng = Pcg64::seed_from_u64(1); let test_dist = LetterDistribution::random(4, 4, &mut rng, |i, j, _rng| 1.0 + (((i+1) as f32) / 10.0) + (((j+1) as f32) / 100.0));
println!("{}", test_dist);
let ground_truth = generate_ground_truth(&test_dist, 4);
let results: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
assert_eq!(ground_truth, results);
}
#[test]
fn ordered_test_5() {
let mut rng = Pcg64::seed_from_u64(1); let test_dist = LetterDistribution::random(4, 4, &mut rng, |_, _, rng| rng.gen());
println!("{}", test_dist);
let ground_truth = generate_ground_truth(&test_dist, 4);
let results: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
assert_eq!(ground_truth, results);
}
#[test]
fn ordered_test_6() {
let mut rng = Pcg64::seed_from_u64(1); let test_dist = LetterDistribution::random(12, 4, &mut rng, |_, _, rng| rng.gen());
println!("{}", test_dist);
let mut highest_prob = 1.0;
let mut total_prob = 0.0;
for (i, (possible_word, word_prob)) in test_dist.ordered_permutations().take(1000).enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
if word_prob > highest_prob {
println!("ERROR! i={}, {} > {}", i, word_prob, highest_prob);
assert!(false);
}
total_prob += word_prob;
highest_prob = word_prob;
}
println!("Total Distribution Prob Coverage: {}", total_prob);
}
#[test]
fn ordered_test_7() {
let mut rng = Pcg64::seed_from_u64(1);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..4 {
let mut inner_dist = vec![];
for _ in 0..4 {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
println!(" -1- -2- -3- -4-");
for i in 0..4 {
print!("{} -", i);
for inner_dist in test_dist.iter() {
print!("{:>4} ", inner_dist[i]);
}
println!("");
}
let perm_iter = OrderedPermutationIter::new(test_dist.iter(), &|products|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
});
let mut highest_product = u32::MAX;
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
if product > highest_product {
println!("ERROR! i={}, {} > {}", i, product, highest_product);
assert!(false);
}
highest_product = product;
perm_cnt += 1;
}
assert_eq!(perm_cnt, 256);
}
#[test]
fn ordered_test_8() {
let mut rng = Pcg64::seed_from_u64(3);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..3 {
let dist_elements = rng.gen_range(1..8);
let mut inner_dist = Vec::with_capacity(dist_elements);
for _ in 0..dist_elements {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
let factor_element_counts: Vec<usize> = test_dist.iter().map(|inner| inner.len()).collect();
let mut expected_perm_count = 1;
factor_element_counts.iter().for_each(|cnt| expected_perm_count *= cnt);
println!("\nfactor_element_counts {:?}", factor_element_counts);
println!("expected_perm_count {}", expected_perm_count);
let perm_iter = OrderedPermutationIter::new(test_dist.iter(), &|products|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
});
let mut highest_product = u32::MAX;
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
if product > highest_product {
println!("ERROR! i={}, {} > {}", i, product, highest_product);
assert!(false);
}
highest_product = product;
perm_cnt += 1;
}
assert_eq!(perm_cnt, expected_perm_count);
}
#[test]
fn radix_test_0() {
let letter_probs = vec![
vec![('a', 0.8), ('b', 0.2)],
vec![('a', 0.7), ('b', 0.3)],
vec![('a', 0.6), ('b', 0.4)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(usize, (Vec<usize>, f32))> = test_dist.radix_permutations().enumerate().collect();
for (i, (possible_word, word_prob)) in results.iter() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let result_strings: Vec<Vec<usize>> = results.into_iter().map(|(_idx, (string, _prob))| string).collect();
assert_eq!(result_strings,
vec![
result_from_str("aaa"),
result_from_str("aab"),
result_from_str("aba"),
result_from_str("abb"),
result_from_str("baa"),
result_from_str("bba"),
result_from_str("bab"),
result_from_str("bbb"),
]);
}
#[test]
fn radix_test_1() {
let letter_probs = vec![
vec![('a', 0.4), ('b', 0.3), ('c', 0.2), ('d', 0.1)],
vec![('a', 0.4), ('b', 0.3), ('c', 0.2), ('d', 0.1)],
vec![('a', 0.4), ('b', 0.3), ('c', 0.2), ('d', 0.1)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(Vec<usize>, f32)> = test_dist.radix_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let grouped_results = group_result_by_prob(results);
let ground_truth = generate_ground_truth(&test_dist, 4);
let grouped_truth = group_result_by_prob(ground_truth);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn radix_test_2() {
println!();
let mut rng = Pcg64::seed_from_u64(1); let test_dist = LetterDistribution::random(12, 4, &mut rng, |_, _, rng| rng.gen());
println!("{}", test_dist);
let ordered: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().take(30).collect();
let radix: Vec<(Vec<usize>, f32)> = test_dist.radix_permutations().take(100).collect();
let mut no_count = 0;
for (i, (possible_word, word_prob)) in ordered.into_iter().enumerate() {
if radix.contains(&(possible_word.clone(), word_prob)) {
println!("YES --{}: {:?} {}", i, possible_word, word_prob);
} else {
println!("No --{}: {:?} {}", i, possible_word, word_prob);
no_count += 1;
}
}
assert_eq!(no_count, 0);
}
#[test]
fn radix_test_3() {
let mut rng = Pcg64::seed_from_u64(1);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..4 {
let mut inner_dist = vec![];
for _ in 0..4 {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
println!(" -1- -2- -3- -4-");
for i in 0..4 {
print!("{} -", i);
for inner_dist in test_dist.iter() {
print!("{:>4} ", inner_dist[i]);
}
println!("");
}
let perm_iter = RadixPermutationIter::new(test_dist.iter(), &|products|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
});
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
perm_cnt += 1;
}
assert_eq!(perm_cnt, 256);
}
#[test]
fn radix_test_4() {
let mut rng = Pcg64::seed_from_u64(3);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..3 {
let dist_elements = rng.gen_range(1..8);
let mut inner_dist = Vec::with_capacity(dist_elements);
for _ in 0..dist_elements {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
let factor_element_counts: Vec<usize> = test_dist.iter().map(|inner| inner.len()).collect();
let mut expected_perm_count = 1;
factor_element_counts.iter().for_each(|cnt| expected_perm_count *= cnt);
println!("\nfactor_element_counts {:?}", factor_element_counts);
println!("expected_perm_count {}", expected_perm_count);
let product_fn = |products: &[u32]|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
};
let perm_iter = RadixPermutationIter::new(test_dist.iter(), &product_fn);
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
perm_cnt += 1;
}
assert_eq!(perm_cnt, expected_perm_count);
let results: Vec<(Vec<usize>, u32)> = RadixPermutationIter::new(test_dist.iter(), &product_fn).collect();
let grouped_results = group_result_by_prob(results);
let ordered: Vec<(Vec<usize>, u32)> = OrderedPermutationIter::new(test_dist.iter(), &product_fn).collect();
let grouped_truth = group_result_by_prob(ordered);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn manhattan_test_0() {
let letter_probs = vec![
vec![('a', 0.8), ('b', 0.2)],
vec![('a', 0.7), ('b', 0.3)],
vec![('a', 0.6), ('b', 0.4)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(usize, (Vec<usize>, f32))> = test_dist.manhattan_permutations().enumerate().collect();
for (i, (possible_word, word_prob)) in results.iter() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let result_strings: Vec<Vec<usize>> = results.into_iter().map(|(_idx, (string, _prob))| string).collect();
assert_eq!(result_strings,
vec![
result_from_str("aaa"),
result_from_str("aab"),
result_from_str("aba"),
result_from_str("baa"), result_from_str("abb"),
result_from_str("bab"),
result_from_str("bba"),
result_from_str("bbb"),
]);
}
#[test]
fn manhattan_test_1() {
let letter_probs = vec![
vec![('a', 0.7), ('b', 0.2), ('c', 0.1)],
vec![('a', 0.6), ('b', 0.3), ('c', 0.1)],
vec![('a', 0.5), ('b', 0.4), ('c', 0.1)],
];
let test_dist = LetterDistribution::from_probs(&letter_probs);
println!("Testing:");
println!("{}", test_dist);
let results: Vec<(Vec<usize>, f32)> = test_dist.manhattan_permutations().collect();
for (i, (possible_word, word_prob)) in results.iter().enumerate() {
println!("--{}: {:?} {}", i, possible_word, word_prob);
}
let grouped_results = group_result_by_prob(results);
let ground_truth = generate_ground_truth(&test_dist, 4);
let grouped_truth = group_result_by_prob(ground_truth);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn manhattan_test_2() {
println!();
let mut rng = Pcg64::seed_from_u64(1); let test_dist = LetterDistribution::random(12, 4, &mut rng, |_, _, rng| rng.gen());
println!("{}", test_dist);
let ordered: Vec<(Vec<usize>, f32)> = test_dist.ordered_permutations().take(350).collect();
let radix: Vec<(Vec<usize>, f32)> = test_dist.manhattan_permutations().take(14000).collect();
let mut no_count = 0;
for (i, (possible_word, word_prob)) in ordered.into_iter().enumerate() {
if radix.contains(&(possible_word.clone(), word_prob)) {
println!("YES --{}: {:?} {}", i, possible_word, word_prob);
} else {
println!("No --{}: {:?} {}", i, possible_word, word_prob);
no_count += 1;
}
}
assert_eq!(no_count, 0);
}
#[test]
fn manhattan_test_3() {
let mut rng = Pcg64::seed_from_u64(1);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..4 {
let mut inner_dist = vec![];
for _ in 0..4 {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
println!(" -1- -2- -3- -4-");
for i in 0..4 {
print!("{} -", i);
for inner_dist in test_dist.iter() {
print!("{:>4} ", inner_dist[i]);
}
println!("");
}
let perm_iter = ManhattanPermutationIter::new(test_dist.iter(), &|products|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
});
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
perm_cnt += 1;
}
assert_eq!(perm_cnt, 256);
}
#[test]
fn manhattan_test_4() {
let mut rng = Pcg64::seed_from_u64(3);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..3 {
let dist_elements = rng.gen_range(1..8);
let mut inner_dist = Vec::with_capacity(dist_elements);
for _ in 0..dist_elements {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
let factor_element_counts: Vec<usize> = test_dist.iter().map(|inner| inner.len()).collect();
let mut expected_perm_count = 1;
factor_element_counts.iter().for_each(|cnt| expected_perm_count *= cnt);
println!("\nfactor_element_counts {:?}", factor_element_counts);
println!("expected_perm_count {}", expected_perm_count);
let product_fn = |products: &[u32]|{
let mut new_product: u32 = 1;
for product in products.iter() {
new_product *= *product;
}
Some(new_product)
};
let perm_iter = ManhattanPermutationIter::new(test_dist.iter(), &product_fn);
let mut perm_cnt = 0;
for (i, (perm, product)) in perm_iter.enumerate() {
println!("--{}: {:?} {}", i, perm, product);
perm_cnt += 1;
}
assert_eq!(perm_cnt, expected_perm_count);
let results: Vec<(Vec<usize>, u32)> = ManhattanPermutationIter::new(test_dist.iter(), &product_fn).collect();
let grouped_results = group_result_by_prob(results);
let ordered: Vec<(Vec<usize>, u32)> = OrderedPermutationIter::new(test_dist.iter(), &product_fn).collect();
let grouped_truth = group_result_by_prob(ordered);
assert!(compare_grouped_results(grouped_results, grouped_truth));
}
#[test]
fn search_dict_test() {
let dict_tree = LetterTree::new_from_dict_file("/usr/share/dict/words");
let mut rng = Pcg64::seed_from_u64(1);
let mut test_dist = LetterDistribution::random(11, 3, &mut rng, |_, _, rng| rng.gen());
test_dist.set_letter_prob(0, 'a', 0.5);
test_dist.set_letter_prob(1, 'd', 0.5);
test_dist.set_letter_prob(2, 'v', 0.3);
test_dist.set_letter_prob(3, 'e', 0.5);
test_dist.set_letter_prob(4, 'n', 0.3);
test_dist.set_letter_prob(5, 't', 0.01);
test_dist.set_letter_prob(6, 'u', 0.5);
test_dist.set_letter_prob(7, 'r', 0.5);
test_dist.set_letter_prob(8, 'o', 0.01);
test_dist.set_letter_prob(9, 'u', 0.5);
test_dist.set_letter_prob(10, 's', 0.5);
println!("{}", test_dist);
for (i, (permutation, prob)) in test_dist.manhattan_permutations().enumerate().take(100000) {
let perm_string: String = permutation.into_iter().map(|idx| char::from((idx+97) as u8)).collect();
let matched_letters = dict_tree.search(&perm_string);
if matched_letters+3 > perm_string.len() {
println!("idx = {}, raw_prob = {}, {} matches {} letters", i, prob, perm_string, matched_letters);
}
}
}
#[test]
fn non_multiplicative_fn_test() {
let mut rng = Pcg64::seed_from_u64(1);
let mut test_dist: Vec<Vec<u32>> = vec![];
for _ in 0..4 {
let mut inner_dist = vec![];
for _ in 0..4 {
inner_dist.push(rng.gen_range(0..256));
}
test_dist.push(inner_dist);
}
println!(" -1- -2- -3- -4-");
for i in 0..4 {
print!("{} -", i);
for inner_dist in test_dist.iter() {
print!("{:>4} ", inner_dist[i]);
}
println!("");
}
let non_multiplicative_fn = |values: &[u32]| {
let mut new_value: u32 = 0;
for (i, val) in values.iter().enumerate() {
new_value += (i as u32) * 256 * val;
}
Some(new_value)
};
let ordered: Vec<(Vec<usize>, u32)> = OrderedPermutationIter::new(test_dist.iter(), &non_multiplicative_fn).collect();
let mut ground_truth = ordered.clone();
ground_truth.sort_by(|(_element_a, val_a), (_element_b, val_b)| val_b.partial_cmp(val_a).unwrap_or(Ordering::Equal));
assert_eq!(ordered, ground_truth);
let manhattan: Vec<(Vec<usize>, u32)> = ManhattanPermutationIter::new(test_dist.iter(), &non_multiplicative_fn).collect();
let mut total_err: u64 = 0;
for (i, manhattan_result) in manhattan.iter().enumerate() {
let truth_pos = ground_truth.iter().position(|element| element==manhattan_result).unwrap();
total_err += (truth_pos.abs_diff(i) as u64).pow(2);
}
println!("Manhattan Total Squared-Error: {}", total_err);
let radix: Vec<(Vec<usize>, u32)> = RadixPermutationIter::new(test_dist.iter(), &non_multiplicative_fn).collect();
let mut total_err: u64 = 0;
for (i, radix_result) in radix.iter().enumerate() {
let truth_pos = ground_truth.iter().position(|element| element==radix_result).unwrap();
total_err += (truth_pos.abs_diff(i) as u64).pow(2);
}
println!("Radix Total Squared-Error: {}", total_err);
}