pub fn medoid_silhouette<M, N, L>(
    mat: &M,
    meds: &[usize],
    samples: bool
) -> (L, Vec<L>)where
    N: Zero + PartialOrd + Copy,
    L: AddAssign + Div<Output = L> + Sub<Output = L> + Signed + Zero + PartialOrd + Copy + From<N> + From<u32>,
    M: ArrayAdapter<N>,
Expand description

Compute the Medoid Silhouette of a clustering.

The Medoid Silhouette is an approximation to the original Silhouette where the distance to the cluster medoid is used instead of the average distance, hence reducing the run time from O(N²) to O(Nk). Here we assume that every object is assigned the nearest cluster, and hence only a distance matrix and a list of medoids is given.

Because of the additional requirement of a division operator, this implementation currently always returns a float result, and accepts only input distances that can be converted into floats.

TODO: allow using N x k distance matrixes, too.

  • type M - matrix data type such as ndarray::Array2 or kmedoids::arrayadapter::LowerTriangle
  • type N - number data type such as u32 or f64
  • type L - number data type such as f64 for the cost (use a float type)
  • mat - a pairwise distance matrix
  • meds - the medoid list
  • samples - whether to keep the individual samples, or not

returns a tuple containing:

  • the average medoid silhouette
  • the individual medoid silhouette values (empty if samples = false)


  • panics when the dissimilarity matrix is not square


Given a dissimilarity matrix of size 4 x 4, use:

let data = ndarray::arr2(&[[0,1,2,3],[1,0,4,5],[2,4,0,6],[3,5,6,0]]);
let mut meds = kmedoids::random_initialization(4, 2, &mut rand::thread_rng());
let (loss, assi, n_iter): (f64, _, _) = kmedoids::alternating(&data, &mut meds, 100);
let (sil, _): (f64, _) = kmedoids::medoid_silhouette(&data, &meds, false);
println!("Silhouette is: {}", sil);