(
&self,
direction: &Direction,
ns: &[usize],
)
| 280 | |
| 281 | impl ComputeTopSegmentProportions for IMArrayElement { |
| 282 | fn top_segment_proportions( |
| 283 | &self, |
| 284 | direction: &Direction, |
| 285 | ns: &[usize], |
| 286 | ) -> anyhow::Result<ndarray::Array2<f64>> { |
| 287 | let shape = self.get_shape()?; |
| 288 | let (n_items, n_features) = match direction { |
| 289 | Direction::ROW => (shape[0], shape[1]), |
| 290 | Direction::COLUMN => (shape[1], shape[0]), |
| 291 | }; |
| 292 | |
| 293 | for &n in ns { |
| 294 | if n > n_features { |
| 295 | return Err(anyhow::anyhow!( |
| 296 | "Requested top {} features but only {} available", |
| 297 | n, |
| 298 | n_features |
| 299 | )); |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | let totals: Vec<f64> = self.sum_whole(direction)?; |
| 304 | |
| 305 | let mut proportions = ndarray::Array2::<f64>::zeros((n_items, ns.len())); |
| 306 | |
| 307 | let mut unique_ns: Vec<usize> = ns.to_vec(); |
| 308 | unique_ns.sort_unstable(); |
| 309 | unique_ns.dedup(); |
| 310 | |
| 311 | let mut n_to_indices: std::collections::HashMap<usize, Vec<usize>> = |
| 312 | std::collections::HashMap::new(); |
| 313 | for (idx, &n) in ns.iter().enumerate() { |
| 314 | n_to_indices.entry(n).or_default().push(idx); |
| 315 | } |
| 316 | |
| 317 | for &n in &unique_ns { |
| 318 | let top_values: Vec<f64> = self.n_top_whole(direction, n)?; |
| 319 | |
| 320 | for item_idx in 0..n_items { |
| 321 | let total = totals[item_idx]; |
| 322 | if total > 0.0 { |
| 323 | let start_idx = item_idx * n; |
| 324 | let end_idx = start_idx + n; |
| 325 | let sum_top_n: f64 = top_values[start_idx..end_idx].iter().sum(); |
| 326 | let proportion = sum_top_n / total; |
| 327 | |
| 328 | for &ns_idx in &n_to_indices[&n] { |
| 329 | proportions[[item_idx, ns_idx]] = proportion; |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | Ok(proportions) |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | /* |
no test coverage detected