use num::{self, NumCast};
use std::vec::Vec;
use thiserror::Error;
#[cfg(not(feature = "parallel"))]
pub trait Integer: NumCast + num::Integer + Copy {}
#[cfg(not(feature = "parallel"))]
impl<T> Integer for T where T: NumCast + num::Integer + Copy {}
#[cfg(feature = "parallel")]
pub trait Integer: NumCast + num::Integer + Copy + std::marker::Send + Sync {}
#[cfg(feature = "parallel")]
impl<T> Integer for T where T: NumCast + num::Integer + Copy + std::marker::Send + Sync {}
#[cfg(not(feature = "parallel"))]
pub trait Float: NumCast + num::Float + Copy {}
#[cfg(not(feature = "parallel"))]
impl<T> Float for T where T: NumCast + num::Float + Copy {}
#[cfg(feature = "parallel")]
pub trait Float: NumCast + num::Float + Copy + std::marker::Send + Sync {}
#[cfg(feature = "parallel")]
impl<T> Float for T where T: NumCast + num::Float + Copy + std::marker::Send + Sync {}
pub fn to_base_fixed<T: Integer>(num: T, base: T, degree: T) -> Vec<T>
where
{
let mut new_base = vec![T::from(0).unwrap(); degree.to_usize().unwrap()];
let mut new_num = num;
for i in 0..degree.to_usize().unwrap() {
let i = i as usize;
new_base[i] = new_num % base;
new_num = new_num / base;
}
new_base
}
pub fn poly_eval<T>(coeffs: &[T], base: T) -> T
where
T: Integer + NumCast + Copy,
{
let mut result: T = T::from(0).unwrap();
for coefficient in coeffs.iter().rev() {
result = (result * base) + *coefficient;
}
result
}
#[derive(Debug)]
pub enum ErrorKind {
InvalidParams,
RuntimeError,
}
#[derive(Debug, Error)]
pub enum OarsError {
#[error("Invalid params supplied to the constructor: {0}")]
InvalidParams(String),
#[error("There was an error pertaining to the shape of a matrix")]
ShapeError {
#[from]
source: ndarray::ShapeError,
},
}
pub type OarsResult<T> = Result<T, OarsError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_base_fixed() {
let num = 5;
let base = 2;
let mut res = to_base_fixed(num, base, 3);
res.reverse();
assert!(res == vec![1, 0, 1]);
let num = 1;
let base = 2;
let mut res = to_base_fixed(num, base, 3);
res.reverse();
assert!(res == vec![0, 0, 1]);
let num = 9;
let base = 2;
let mut res = to_base_fixed(num, base, 5);
res.reverse();
assert!(res == vec![0, 1, 0, 0, 1]);
let num = 7;
let base = 3;
let mut res = to_base_fixed(num, base, 2);
res.reverse();
assert!(res == vec![2, 1]);
}
#[test]
fn test_poly_eval() {
let coeffs = vec![1, 1, 1, 1];
let base = 2;
let result = poly_eval(&coeffs, base);
assert!(result == 15);
let coeffs = vec![1, 2];
let base = 3;
let result = poly_eval(&coeffs, base);
assert!(result == 7);
let coeffs = vec![1, 0, 0, 1];
let base = 2;
let result = poly_eval(&coeffs, base);
assert!(result == 9);
let coeffs = vec![0, 0, 1];
let base = 3;
let result = poly_eval(&coeffs, base);
assert!(result == 9);
}
}