The SALSO algorithm is an efficient greedy search procedure to obtain a clustering estimate based on a partition loss function. The algorithm is implemented for many loss functions, including the Binder loss and a generalization of the variation of information loss, both of which allow for unequal weights on the two types of clustering mistakes. Efficient implementations are also provided for Monte Carlo estimation of the posterior expected loss of a given clustering estimate. SALSO was first presented at the workshop 'Bayesian Nonparametric Inference: Dependence Structures and their Applications' in Oaxaca, Mexico on December 6, 2017.

```
extern crate num_cpus;
extern crate rand;
use crate::*;
#[derive(Debug, Clone)]
pub struct Log2Cache {
log2n: Vec<f64>,
nlog2n: Vec<f64>,
nlog2n_difference: Vec<f64>,
}
impl Log2Cache {
pub fn new(n: usize) -> Self {
let mut log2n = Vec::with_capacity(n + 1);
let mut nlog2n = Vec::with_capacity(n + 1);
let mut nlog2n_difference = Vec::with_capacity(n);
log2n.push(0.0);
nlog2n.push(0.0);
for i in 1..=n {
let i = i as f64;
let log2i = i.log2();
log2n.push(log2i);
let ilog2i = i * log2i;
let ilog2i_last = *nlog2n.last().unwrap();
nlog2n.push(ilog2i);
nlog2n_difference.push(ilog2i - ilog2i_last);
}
Self {
log2n,
nlog2n,
nlog2n_difference,
}
}
pub fn plog2p(&self, x: CountType, n: CountType) -> f64 {
let p = (x as f64) / (n as f64);
let log2p = unsafe {
*self.log2n.get_unchecked(x as usize) - *self.log2n.get_unchecked(n as usize)
};
p * log2p
}
pub fn nlog2n(&self, n: CountType) -> f64 {
unsafe { *self.nlog2n.get_unchecked(n as usize) }
}
pub fn nlog2n_difference(&self, n: CountType) -> f64 {
unsafe { *self.nlog2n_difference.get_unchecked(n as usize) }
}
}
```