crate_activity/
correlation.rs

1crate::ix!();
2
3pub fn compute_pairwise_correlations(
4    summaries: &[CrateUsageSummary],
5) -> Vec<(String, String, f64)> {
6    let mut correlations = Vec::new();
7
8    for i in 0..summaries.len() {
9        for j in (i + 1)..summaries.len() {
10            let crate_a = summaries[i].crate_name();
11            let crate_b = summaries[j].crate_name();
12
13            let downloads_a = summaries[i].version_downloads();
14            let downloads_b = summaries[j].version_downloads();
15
16            // Extract and intersect date ranges
17            let dates_a: Vec<_> = downloads_a.iter().map(|d| *d.date()).collect();
18            let dates_b: Vec<_> = downloads_b.iter().map(|d| *d.date()).collect();
19            let common_dates = intersect_date_ranges(&dates_a, &dates_b);
20
21            // Align data to the common date range
22            let aligned_a = align_and_normalize_data(downloads_a, &common_dates);
23            let aligned_b = align_and_normalize_data(downloads_b, &common_dates);
24
25            // Skip if either dataset lacks variance
26            if !has_significant_variance(&aligned_a) || !has_significant_variance(&aligned_b) {
27                continue;
28            }
29
30            // Compute correlation
31            let correlation = pearson_correlation(&aligned_a, &aligned_b);
32            correlations.push((crate_a.clone(), crate_b.clone(), correlation));
33        }
34    }
35
36    correlations
37}
38
39pub fn debug_correlation(crate_a: &str, crate_b: &str, correlation: f64) {
40    println!("Correlation for {} and {}: {:.4}", crate_a, crate_b, correlation);
41}