(
covariance: &DMatrix<f64>,
ordered_indices: &[usize],
)
| 340 | } |
| 341 | |
| 342 | fn recursive_bisection_min_var( |
| 343 | covariance: &DMatrix<f64>, |
| 344 | ordered_indices: &[usize], |
| 345 | ) -> Result<Vec<f64>, HrpError> { |
| 346 | let n = covariance.nrows(); |
| 347 | let mut weights = vec![1.0; n]; |
| 348 | let mut clustered = vec![ordered_indices.to_vec()]; |
| 349 | while !clustered.is_empty() { |
| 350 | let mut split = Vec::new(); |
| 351 | for cluster in clustered { |
| 352 | if cluster.len() > 1 { |
| 353 | let mid = cluster.len() / 2; |
| 354 | split.push(cluster[0..mid].to_vec()); |
| 355 | split.push(cluster[mid..].to_vec()); |
| 356 | } |
| 357 | } |
| 358 | if split.is_empty() { |
| 359 | break; |
| 360 | } |
| 361 | for i in (0..split.len()).step_by(2) { |
| 362 | let left = &split[i]; |
| 363 | let right = &split[i + 1]; |
| 364 | let lv = cluster_variance(covariance, left)?; |
| 365 | let rv = cluster_variance(covariance, right)?; |
| 366 | let a = 1.0 - lv / (lv + rv + f64::EPSILON); |
| 367 | for &idx in left { |
| 368 | weights[idx] *= a; |
| 369 | } |
| 370 | for &idx in right { |
| 371 | weights[idx] *= 1.0 - a; |
| 372 | } |
| 373 | } |
| 374 | clustered = split; |
| 375 | } |
| 376 | let sum: f64 = weights.iter().sum(); |
| 377 | if sum > 0.0 { |
| 378 | for w in &mut weights { |
| 379 | *w /= sum; |
| 380 | } |
| 381 | } |
| 382 | Ok(weights) |
| 383 | } |
no test coverage detected