cfavml 0.3.0

CF's Accelerated Vector Math Library providing SIMD optimzied routines for vector operations
Documentation
use rand::distributions::{Distribution, Standard};
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;

use crate::danger::cosine;
use crate::math::{AutoMath, Math};

const SEED: u64 = 34535345353;

pub fn get_sample_vectors<T>(size: usize) -> (Vec<T>, Vec<T>)
where
    T: Copy,
    AutoMath: Math<T>,
    Standard: Distribution<T>,
{
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);

    let mut x = Vec::new();
    let mut y = Vec::new();
    for _ in 0..size {
        let mut v1 = rng.gen();
        let mut v2 = rng.gen();

        if AutoMath::cmp_eq(v1, AutoMath::zero()) {
            v1 = AutoMath::one();
        }

        if AutoMath::cmp_eq(v2, AutoMath::zero()) {
            v2 = AutoMath::one();
        }

        x.push(v1);
        y.push(v2);
    }

    (x, y)
}

pub fn simple_dot<T>(x: &[T], y: &[T]) -> T
where
    T: Copy,
    AutoMath: Math<T>,
{
    let mut dot_product = AutoMath::zero();

    for i in 0..x.len() {
        dot_product = AutoMath::add(dot_product, AutoMath::mul(x[i], y[i]));
    }

    dot_product
}

pub fn simple_cosine<T>(x: &[T], y: &[T]) -> T
where
    T: Copy,
    AutoMath: Math<T>,
{
    let mut dot_product = AutoMath::zero();
    let mut norm_x = AutoMath::zero();
    let mut norm_y = AutoMath::zero();

    for i in 0..x.len() {
        dot_product = AutoMath::add(dot_product, AutoMath::mul(x[i], y[i]));
        norm_x = AutoMath::add(norm_x, AutoMath::mul(x[i], x[i]));
        norm_y = AutoMath::add(norm_y, AutoMath::mul(y[i], y[i]));
    }

    cosine::<_, AutoMath>(dot_product, norm_x, norm_y)
}

pub fn simple_euclidean<T>(x: &[T], y: &[T]) -> T
where
    T: Copy,
    AutoMath: Math<T>,
{
    let mut dist = AutoMath::zero();

    for i in 0..x.len() {
        let diff = AutoMath::sub(x[i], y[i]);
        dist = AutoMath::add(dist, AutoMath::mul(diff, diff));
    }

    dist
}