use scirs2_core::ndarray::Array1;
use sklears_core::{error::Result, types::Float};
#[allow(dead_code)]
pub struct SimdSignalOps;
#[allow(dead_code)]
impl SimdSignalOps {
pub fn simd_correlate(
signal1: &Array1<Float>,
signal2: &Array1<Float>,
) -> Result<Array1<Float>> {
let n1 = signal1.len();
let n2 = signal2.len();
let output_len = n1 + n2 - 1;
let mut result = Array1::<Float>::zeros(output_len);
for i in 0..output_len {
let mut sum = 0.0;
for j in 0..n1 {
let k = i as i32 - j as i32;
if k >= 0 && k < n2 as i32 {
sum += signal1[j] * signal2[k as usize];
}
}
result[i] = sum;
}
Ok(result)
}
pub fn simd_convolve(signal: &Array1<Float>, kernel: &Array1<Float>) -> Result<Array1<Float>> {
Self::simd_correlate(signal, kernel)
}
pub fn simd_elementwise_multiply(
a: &Array1<Float>,
b: &Array1<Float>,
) -> Result<Array1<Float>> {
if a.len() != b.len() {
return Err(sklears_core::error::SklearsError::InvalidInput(
"Arrays must have same length".to_string(),
));
}
let result: Vec<Float> = a.iter().zip(b.iter()).map(|(&x, &y)| x * y).collect();
Ok(Array1::from_vec(result))
}
}
#[allow(non_snake_case)]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simd_correlate() {
let signal1 = Array1::from_vec(vec![1.0, 2.0, 3.0]);
let signal2 = Array1::from_vec(vec![1.0, 1.0]);
let result =
SimdSignalOps::simd_correlate(&signal1, &signal2).expect("operation should succeed");
assert_eq!(result.len(), 4);
}
#[test]
fn test_simd_elementwise_multiply() {
let a = Array1::from_vec(vec![1.0, 2.0, 3.0]);
let b = Array1::from_vec(vec![2.0, 3.0, 4.0]);
let result =
SimdSignalOps::simd_elementwise_multiply(&a, &b).expect("operation should succeed");
assert_eq!(result.len(), 3);
assert_eq!(result[0], 2.0);
assert_eq!(result[1], 6.0);
assert_eq!(result[2], 12.0);
}
}