growth.rs
2.4 kB · rust · 94 lines
1use crate::series::Rep;2use crate::word::{render, CODES};34pub fn family(prefix: u8, last: u8, length: usize) -> Vec<u8> {5 let mut word = vec![prefix; length - 1];6 word.push(last);7 word8}910pub fn components(word: &[u8]) -> u64 {11 render(word).components()12}1314pub fn merging(word: &[u8]) -> u64 {15 render(word).merging()16}1718pub fn max_components(length: usize) -> (u64, Vec<u8>) {19 let mut best = 0u64;20 let mut witness: Vec<u8> = Vec::new();21 let mut word = vec![0u8; length];22 walk(&mut word, 0, &mut |candidate: &[u8]| {23 let count = render(candidate).components();24 if count > best {25 best = count;26 witness = candidate.to_vec();27 }28 });29 (best, witness)30}3132pub fn max_merging(length: usize) -> (u64, Vec<u8>) {33 let mut best = 0u64;34 let mut witness: Vec<u8> = Vec::new();35 let mut word = vec![0u8; length];36 walk(&mut word, 0, &mut |candidate: &[u8]| {37 let count = render(candidate).merging();38 if count > best {39 best = count;40 witness = candidate.to_vec();41 }42 });43 (best, witness)44}4546fn walk(word: &mut Vec<u8>, at: usize, visit: &mut dyn FnMut(&[u8])) {47 if at == word.len() {48 visit(word);49 return;50 }51 for &code in CODES.iter() {52 word[at] = code;53 walk(word, at + 1, visit);54 }55}5657pub fn max_predicted(rep: &Rep, length: usize) -> i64 {58 let state: Vec<i128> = rep.lambda.iter().map(|value| *value as i128).collect();59 let mut best = i64::MIN;60 descend(rep, &state, length, &mut best);61 best62}6364fn descend(rep: &Rep, state: &[i128], left: usize, best: &mut i64) {65 if left == 0 {66 let value: i128 = state67 .iter()68 .zip(rep.gamma.iter())69 .map(|(a, b)| a * *b as i128)70 .sum();71 if value as i64 > *best {72 *best = value as i64;73 }74 return;75 }76 for &code in CODES.iter() {77 let matrix = &rep.matrices[&code];78 let mut next = vec![0i128; state.len()];79 for (i, weight) in state.iter().enumerate() {80 if *weight == 0 {81 continue;82 }83 for (j, slot) in next.iter_mut().enumerate() {84 *slot += weight * matrix[i][j] as i128;85 }86 }87 descend(rep, &next, left - 1, best);88 }89}9091pub fn independent_bound(length: usize) -> u64 {92 let side = 1u64 << length;93 side * side / 294}