(values: &[f64])
| 268 | } |
| 269 | |
| 270 | fn tstat(values: &[f64]) -> f64 { |
| 271 | if values.is_empty() { |
| 272 | return 0.0; |
| 273 | } |
| 274 | let mean = values.iter().sum::<f64>() / values.len() as f64; |
| 275 | let var = values |
| 276 | .iter() |
| 277 | .map(|v| { |
| 278 | let d = *v - mean; |
| 279 | d * d |
| 280 | }) |
| 281 | .sum::<f64>() |
| 282 | / values.len() as f64; |
| 283 | let std = var.sqrt(); |
| 284 | if std <= 1e-12 { |
| 285 | if mean > 0.0 { |
| 286 | f64::INFINITY |
| 287 | } else { |
| 288 | 0.0 |
| 289 | } |
| 290 | } else { |
| 291 | mean / std |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | fn labels_from_clusters(n: usize, clusters: &BTreeMap<usize, Vec<usize>>) -> Vec<usize> { |
| 296 | let mut labels = vec![0usize; n]; |
no test coverage detected