fn similarity_matrix<V, F>(inputs: &[V], compare: &F) -> Vec<f64>
where
    F: Fn(&V, &V) -> f64 + Send + Sync,
    V: Sync,
{
    if inputs.is_empty() {
        return vec![];
    }

    let mut intermediate = vec![];
    for row in 0..inputs.len() - 1 {
        for col in row + 1..inputs.len() {
            intermediate.push((row, col))
        }
    }

    let pb = indicatif::ProgressBar::new(intermediate.len().try_into().unwrap());
    pb.set_style(
        indicatif::ProgressStyle::default_bar()
            .template("[{wide_bar:.cyan/blue}] {pos}/{len} ({percent}%, {eta_precise})")
            .progress_chars("#>-"),
    );

    intermediate
        .par_iter()
        .progress_with(pb)
        .map(|(row, col)| (compare)(&inputs[*row], &inputs[*col]))
        .collect()
}
/// This function is very heavily inspired by the example provided within the kodama documentation
/// (at https://docs.rs/kodama)
///
/// The biggest differences? This allows for the comparison operation to be provided, and it
/// compares values leveraging Rayon to speed up the operations. Due to the use of Rayon, we
/// construct an intermediate vector to hold positions for calculations.


The biggest differences. This allows for the comparison operation to be provided, and it
compares values leveraging Rayon to speed up the operations. Due to the use of Rayon, we
construct an intermediate vector to hold positions for calculations.
The biggest differences . This allows for the comparison operation to be provided and it compares values leveraging Rayon to speed up the operations . Due to the use of Rayon we construct an intermediate vector to hold positions for calculations .
fn similarity_matrix<V, F>(inputs: &[V], compare: &F) -> Vec<f64>
where
    F: Fn(&V, &V) -> f64 + Send + Sync,
    V: Sync,
{
    if inputs.is_empty() {
        return vec![];
    }
    let mut intermediate = vec![];
    for row in 0..inputs.len() - 1 {
        for col in row + 1..inputs.len() {
            intermediate.push((row, col))
        }
    }
    let pb = indicatif::ProgressBar::new(intermediate.len().try_into().unwrap());
    pb.set_style(
        indicatif::ProgressStyle::default_bar()
            .template("[{wide_bar:.cyan/blue}] {pos}/{len} ({percent}%, {eta_precise})")
            .progress_chars("#>-"),
    );
    intermediate
        .par_iter()
        .progress_with(pb)
        .map(|(row, col)| (compare)(&inputs[*row], &inputs[*col]))
        .collect()
}
fn similarity_matrix < V , F > ( inputs : & [ V ] , compare : & F ) -> Vec < f64 > where F : Fn ( & V , & V ) -> f64 + Send + Sync , V : Sync , { if inputs . is_empty ( ) { return vec ! [ ] ; } let mut intermediate = vec ! [ ] ; for row in 0 .. inputs . len ( ) - 1 { for col in row + 1 .. inputs . len ( ) { intermediate . push ( ( row , col ) ) } } let pb = indicatif :: ProgressBar :: new ( intermediate . len ( ) . try_into ( ) . unwrap ( ) ) ; pb . set_style ( indicatif :: ProgressStyle :: default_bar ( ) . template ( " " ) . progress_chars ( " " ) , ) ; intermediate . par_iter ( ) . progress_with ( pb ) . map ( | ( row , col ) | ( compare ) ( & inputs [ * row ] , & inputs [ * col ] ) ) . collect ( ) }
This function is very heavily inspired by the example provided within the kodama documentation
(at https://docs.rs/kodama)
This function is very heavily inspired by the example provided within the kodama documentation ( at https : // docs . rs / kodama )
inputs
&[V]
compare
&F
inputs
&[V]
compare
&F