use candle_core::{IndexOp, Tensor};
use crate::error::Result;
pub fn second_argmax(input: &Tensor) -> Result<Tensor> {
let sorted_indices = input.arg_sort_last_dim(false)?;
let second = sorted_indices.i((.., 1))?;
Ok(second)
}
pub fn argmedian(input: &Tensor) -> Result<Tensor> {
let (_, seq_len) = input.dims2()?;
let sorted_indices = input.arg_sort_last_dim(true)?;
let median_idx = seq_len / 2;
let median_pos = sorted_indices.i((.., median_idx))?;
Ok(median_pos)
}
pub fn median(input: &Tensor) -> Result<Tensor> {
let (_, seq_len) = input.dims2()?;
let (sorted, _indices) = input.sort_last_dim(true)?;
let median_idx = seq_len / 2;
let median_val = sorted.i((.., median_idx))?;
Ok(median_val)
}
pub fn longest_cycle(input: &Tensor) -> Result<Tensor> {
let input_vec: Vec<Vec<u32>> = input.to_vec2()?;
let mut results = Vec::with_capacity(input_vec.len());
for row in &input_vec {
let n = row.len();
let mut visited = vec![false; n];
let mut max_cycle = 0_u32;
for start in 0..n {
#[allow(clippy::indexing_slicing)]
if visited[start] {
continue;
}
let mut pos = start;
let mut cycle_len = 0_u32;
#[allow(clippy::indexing_slicing)]
while !visited[pos] {
visited[pos] = true;
#[allow(clippy::as_conversions)]
let next = row[pos] as usize;
pos = next;
cycle_len += 1;
}
if cycle_len > max_cycle {
max_cycle = cycle_len;
}
}
results.push(max_cycle);
}
Ok(Tensor::new(&results[..], input.device())?)
}