use core::ops::{Add, Mul, Neg, Sub};
#[inline]
pub fn mul<'out, T>(out: &'out mut [T; 4], a: &[T; 4], b: &[T; 4]) -> &'out mut [T; 4]
where
T: Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
{
out[0] = &a[0] * &b[3] + &a[3] * &b[0] + &a[1] * &b[2] - &a[2] * &b[1];
out[1] = &a[1] * &b[3] + &a[3] * &b[1] + &a[2] * &b[0] - &a[0] * &b[2];
out[2] = &a[2] * &b[3] + &a[3] * &b[2] + &a[0] * &b[1] - &a[1] * &b[0];
out[3] = &a[3] * &b[3] - &a[0] * &b[0] - &a[1] * &b[1] - &a[2] * &b[2];
out
}
#[inline]
pub fn rmul_mut<'out, T>(out: &'out mut [T; 4], a: &[T; 4]) -> &'out mut [T; 4]
where
T: Clone + Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
{
let tmp = out.clone();
mul(out, a, &tmp)
}
#[inline]
pub fn lmul_mut<'out, T>(out: &'out mut [T; 4], a: &[T; 4]) -> &'out mut [T; 4]
where
T: Clone + Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
{
let tmp = out.clone();
mul(out, &tmp, a)
}
#[inline]
pub fn div<'out, T>(out: &'out mut [T; 4], a: &[T; 4], b: &[T; 4]) -> &'out mut [T; 4]
where
T: Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T> + Neg<Output = T>,
{
out[0] = &a[0] * &b[3] + &a[3] * &-&b[0] + &a[1] * &-&b[2] - &a[2] * &-&b[1];
out[1] = &a[1] * &b[3] + &a[3] * &-&b[1] + &a[2] * &-&b[0] - &a[0] * &-&b[2];
out[2] = &a[2] * &b[3] + &a[3] * &-&b[2] + &a[0] * &-&b[1] - &a[1] * &-&b[0];
out[3] = &a[3] * &b[3] - &a[0] * &-&b[0] - &a[1] * &-&b[1] - &a[2] * &-&b[2];
out
}
#[inline]
pub fn rdiv_mut<'out, T>(out: &'out mut [T; 4], a: &[T; 4]) -> &'out mut [T; 4]
where
T: Clone + Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T> + Neg<Output = T>,
{
let tmp = out.clone();
div(out, a, &tmp)
}
#[inline]
pub fn ldiv_mut<'out, T>(out: &'out mut [T; 4], a: &[T; 4]) -> &'out mut [T; 4]
where
T: Clone + Add<T, Output = T> + Sub<T, Output = T>,
for<'a, 'b> &'a T: Mul<&'b T, Output = T> + Neg<Output = T>,
{
let tmp = out.clone();
div(out, &tmp, a)
}