use super::traits::*;
use crate::Transcendental;
pub fn add_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), b.len());
assert_eq!(a.len(), out.len());
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let b_vec = V::load(&b[start..start + N]);
let result = a_vec + b_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] + b[start + i];
}
}
}
pub fn sub_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), b.len());
assert_eq!(a.len(), out.len());
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let b_vec = V::load(&b[start..start + N]);
let result = a_vec - b_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] - b[start + i];
}
}
}
pub fn mul_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), b.len());
assert_eq!(a.len(), out.len());
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let b_vec = V::load(&b[start..start + N]);
let result = a_vec * b_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] * b[start + i];
}
}
}
pub fn div_slices<T: Transcendental, const N: usize, V>(a: &[T], b: &[T], out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), b.len());
assert_eq!(a.len(), out.len());
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let b_vec = V::load(&b[start..start + N]);
let result = a_vec / b_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] / b[start + i];
}
}
}
pub fn mul_scalar_slice<T: Transcendental, const N: usize, V>(a: &[T], scalar: T, out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), out.len());
let scalar_vec = V::splat(scalar);
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let result = a_vec * scalar_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] * scalar;
}
}
}
pub fn add_scalar_slice<T: Transcendental, const N: usize, V>(a: &[T], scalar: T, out: &mut [T])
where
V: Vector<T, N>,
{
assert_eq!(a.len(), out.len());
let scalar_vec = V::splat(scalar);
let chunks = a.len() / N;
let remainder = a.len() % N;
for i in 0..chunks {
let start = i * N;
let a_vec = V::load(&a[start..start + N]);
let result = a_vec + scalar_vec;
result.store(&mut out[start..start + N]);
}
if remainder > 0 {
let start = chunks * N;
for i in 0..remainder {
out[start + i] = a[start + i] + scalar;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
}