Last active
July 31, 2020 12:46
-
-
Save dominicparga/069c014eb3a0c2cf655d4d89ae4e7391 to your computer and use it in GitHub Desktop.
Computing a power-set from a boolean vector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() { | |
// in the end, print all combinations from this vector ([0, 1, 0, 1, 1, 0]), | |
// only considering entries != 0 | |
// resulting in | |
// [0, 1, 0, 0, 0, 0], | |
// [0, 0, 0, 1, 0, 0], [0, 1, 0, 1, 0, 0], | |
// [0, 0, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0], [0, 0, 0, 1, 1, 0], [0, 1, 0, 1, 1, 0] | |
let v = vec![false, true, false, true, true, false]; | |
// v | |
println!("{:?}", v); | |
// create v_mask from v | |
// rev() is important, because vectors grow from left and integers from right | |
let v_mask = v | |
.iter() | |
.rev() | |
.fold(0, |acc, &digit| 2 * acc + if digit { 1 } else { 0 }); | |
println!("v_mask == 0x{:b}", v_mask); | |
// if mask is a power of 2 (e.g. 2==0x10, e.g. not 6==0x110) | |
// -> metric-idx should be set | |
let is_pow_of_2 = |mask: u32| mask & (mask - 1) == 0; | |
let mut metric_idx = 0; | |
for mask in 1..2u32.pow(v.len() as u32) { | |
// println!("LOOP {} == 0x{:b}", mask, mask); | |
// this if-clause causes to discard masks, that have a 1 where v_mask is 0 | |
if ((v_mask | mask) ^ v_mask) == 0 { | |
// parse mask into vector of 0 and 1 | |
// casting to u32 is explicit, because it could be replaced, e.g. by f64 | |
let alphas: Vec<_> = (0..v.len()) | |
.map(|idx| ((mask >> idx) & 1) as u32) | |
.collect(); | |
if is_pow_of_2(mask) { | |
println!("{:?} of metric {}", alphas, metric_idx); | |
metric_idx += 1; | |
} else { | |
println!("{:?}", alphas); | |
} | |
} else if is_pow_of_2(mask) { | |
metric_idx += 1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment