use core::ops::{Index, IndexMut};
use core::{fmt::Debug, ops::SubAssign};
use serde::{Deserialize, Serialize};
use crate::{
array_default::ArrayDefault,
array_default::ArrayIterArgmin,
array_default::{ArrayIter, ArrayIterArgmax},
prelude::{precompute_linear_counting, One},
primitive::Primitive,
zeros::Zero,
};
pub trait WordType<const BITS: usize>: Precision {
type Words: Copy
+ Debug
+ IndexMut<usize, Output = u32>
+ Index<usize, Output = u32>
+ Send
+ Sync
+ Eq
+ PartialEq
+ ArrayIter<u32>
+ ArrayDefault<u32>; type Registermulteplicities: Index<usize, Output = Self::NumberOfZeros>
+ IndexMut<usize, Output = Self::NumberOfZeros>
+ Copy
+ Debug
+ Eq
+ ArrayIterArgmin<Self::NumberOfZeros>
+ ArrayIterArgmax<Self::NumberOfZeros>
+ ArrayDefault<Self::NumberOfZeros>
+ ArrayIter<Self::NumberOfZeros>;
}
pub trait Precision: Default + Copy + Eq + Serialize + Debug + Send + Sync {
type NumberOfZeros: Copy
+ Debug
+ Eq
+ PartialEq
+ Primitive<usize>
+ Send
+ Sync
+ Zero
+ One
+ Ord
+ PartialOrd
+ SubAssign;
const EXPONENT: usize;
const NUMBER_OF_REGISTERS: usize = 1 << Self::EXPONENT;
const MAXIMAL: usize;
type SmallCorrections: Index<usize, Output = f32> + Copy;
type Registers: Index<usize, Output = u32> + Copy + ArrayDefault<u32> + ArrayIter<u32>;
const SMALL_CORRECTIONS: Self::SmallCorrections;
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision4;
impl Precision for Precision4 {
type NumberOfZeros = u8;
const EXPONENT: usize = 4;
const MAXIMAL: usize = u8::MAX as usize;
type SmallCorrections = [f32; 16];
type Registers = [u32; 16];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision4 {
type Words = [u32; 1];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision4 {
type Words = [u32; 1];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision4 {
type Words = [u32; 2];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision4 {
type Words = [u32; 2];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision4 {
type Words = [u32; 3];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision4 {
type Words = [u32; 4];
type Registermulteplicities = [Self::NumberOfZeros; 62];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision5;
impl Precision for Precision5 {
type NumberOfZeros = u8;
const EXPONENT: usize = 5;
const MAXIMAL: usize = u8::MAX as usize;
type SmallCorrections = [f32; 32];
type Registers = [u32; 32];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision5 {
type Words = [u32; 1];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision5 {
type Words = [u32; 2];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision5 {
type Words = [u32; 4];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision5 {
type Words = [u32; 4];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision5 {
type Words = [u32; 6];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision5 {
type Words = [u32; 7];
type Registermulteplicities = [Self::NumberOfZeros; 61];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision6;
impl Precision for Precision6 {
type NumberOfZeros = u8;
const EXPONENT: usize = 6;
const MAXIMAL: usize = u8::MAX as usize;
type SmallCorrections = [f32; 64];
type Registers = [u32; 64];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision6 {
type Words = [u32; 2];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision6 {
type Words = [u32; 4];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision6 {
type Words = [u32; 7];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision6 {
type Words = [u32; 8];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision6 {
type Words = [u32; 11];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision6 {
type Words = [u32; 13];
type Registermulteplicities = [Self::NumberOfZeros; 60];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision7;
impl Precision for Precision7 {
type NumberOfZeros = u8;
const EXPONENT: usize = 7;
const MAXIMAL: usize = u8::MAX as usize;
type SmallCorrections = [f32; 128];
type Registers = [u32; 128];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision7 {
type Words = [u32; 4];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision7 {
type Words = [u32; 8];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision7 {
type Words = [u32; 13];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision7 {
type Words = [u32; 16];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision7 {
type Words = [u32; 22];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision7 {
type Words = [u32; 26];
type Registermulteplicities = [Self::NumberOfZeros; 59];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision8;
impl Precision for Precision8 {
type NumberOfZeros = u16;
const EXPONENT: usize = 8;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 256];
type Registers = [u32; 256];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision8 {
type Words = [u32; 8];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision8 {
type Words = [u32; 16];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision8 {
type Words = [u32; 26];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision8 {
type Words = [u32; 32];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision8 {
type Words = [u32; 43];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision8 {
type Words = [u32; 52];
type Registermulteplicities = [Self::NumberOfZeros; 58];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision9;
impl Precision for Precision9 {
type NumberOfZeros = u16;
const EXPONENT: usize = 9;
const MAXIMAL: usize = 65536;
type SmallCorrections = [f32; 512];
type Registers = [u32; 512];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision9 {
type Words = [u32; 16];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision9 {
type Words = [u32; 32];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision9 {
type Words = [u32; 52];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision9 {
type Words = [u32; 64];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision9 {
type Words = [u32; 86];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision9 {
type Words = [u32; 103];
type Registermulteplicities = [Self::NumberOfZeros; 57];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision10;
impl Precision for Precision10 {
type NumberOfZeros = u16;
const EXPONENT: usize = 10;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 1024];
type Registers = [u32; 1024];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision10 {
type Words = [u32; 32];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision10 {
type Words = [u32; 64];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision10 {
type Words = [u32; 103];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision10 {
type Words = [u32; 128];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision10 {
type Words = [u32; 171];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision10 {
type Words = [u32; 205];
type Registermulteplicities = [Self::NumberOfZeros; 56];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision11;
impl Precision for Precision11 {
type NumberOfZeros = u16;
const EXPONENT: usize = 11;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 2048];
type Registers = [u32; 2048];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision11 {
type Words = [u32; 64];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision11 {
type Words = [u32; 128];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision11 {
type Words = [u32; 205];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision11 {
type Words = [u32; 256];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision11 {
type Words = [u32; 342];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision11 {
type Words = [u32; 410];
type Registermulteplicities = [Self::NumberOfZeros; 55];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision12;
impl Precision for Precision12 {
type NumberOfZeros = u16;
const EXPONENT: usize = 12;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 4096];
type Registers = [u32; 4096];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision12 {
type Words = [u32; 128];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision12 {
type Words = [u32; 256];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision12 {
type Words = [u32; 410];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision12 {
type Words = [u32; 512];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision12 {
type Words = [u32; 683];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision12 {
type Words = [u32; 820];
type Registermulteplicities = [Self::NumberOfZeros; 54];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision13;
impl Precision for Precision13 {
type NumberOfZeros = u16;
const EXPONENT: usize = 13;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 8192];
type Registers = [u32; 8192];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision13 {
type Words = [u32; 256];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision13 {
type Words = [u32; 512];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision13 {
type Words = [u32; 820];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision13 {
type Words = [u32; 1024];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision13 {
type Words = [u32; 1366];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision13 {
type Words = [u32; 1639];
type Registermulteplicities = [Self::NumberOfZeros; 53];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision14;
impl Precision for Precision14 {
type NumberOfZeros = u16;
const EXPONENT: usize = 14;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 16384];
type Registers = [u32; 16384];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision14 {
type Words = [u32; 512];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision14 {
type Words = [u32; 1024];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision14 {
type Words = [u32; 1639];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision14 {
type Words = [u32; 2048];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision14 {
type Words = [u32; 2731];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision14 {
type Words = [u32; 3277];
type Registermulteplicities = [Self::NumberOfZeros; 52];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision15;
impl Precision for Precision15 {
type NumberOfZeros = u16;
const EXPONENT: usize = 15;
const MAXIMAL: usize = u16::MAX as usize;
type SmallCorrections = [f32; 32768];
type Registers = [u32; 32768];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision15 {
type Words = [u32; 1024];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision15 {
type Words = [u32; 2048];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision15 {
type Words = [u32; 3277];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision15 {
type Words = [u32; 4096];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision15 {
type Words = [u32; 5462];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision15 {
type Words = [u32; 6554];
type Registermulteplicities = [Self::NumberOfZeros; 51];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision16;
impl Precision for Precision16 {
type NumberOfZeros = u32;
const EXPONENT: usize = 16;
const MAXIMAL: usize = u32::MAX as usize;
type SmallCorrections = [f32; 65536];
type Registers = [u32; 65536];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision16 {
type Words = [u32; 2048];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision16 {
type Words = [u32; 4096];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision16 {
type Words = [u32; 6554];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision16 {
type Words = [u32; 8192];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision16 {
type Words = [u32; 10923];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision16 {
type Words = [u32; 13108];
type Registermulteplicities = [Self::NumberOfZeros; 50];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision17;
impl Precision for Precision17 {
type NumberOfZeros = u32;
const EXPONENT: usize = 17;
const MAXIMAL: usize = u32::MAX as usize;
type SmallCorrections = [f32; 131072];
type Registers = [u32; 131072];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision17 {
type Words = [u32; 4096];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision17 {
type Words = [u32; 8192];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision17 {
type Words = [u32; 13108];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision17 {
type Words = [u32; 16384];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision17 {
type Words = [u32; 21846];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision17 {
type Words = [u32; 26215];
type Registermulteplicities = [Self::NumberOfZeros; 49];
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Precision18;
impl Precision for Precision18 {
type NumberOfZeros = u32;
const EXPONENT: usize = 18;
const MAXIMAL: usize = u32::MAX as usize;
type SmallCorrections = [f32; 262144];
type Registers = [u32; 262144];
const SMALL_CORRECTIONS: Self::SmallCorrections =
precompute_linear_counting::<{ Self::NUMBER_OF_REGISTERS }>();
}
impl WordType<1> for Precision18 {
type Words = [u32; 8192];
type Registermulteplicities = [Self::NumberOfZeros; 2];
}
impl WordType<2> for Precision18 {
type Words = [u32; 16384];
type Registermulteplicities = [Self::NumberOfZeros; 4];
}
impl WordType<3> for Precision18 {
type Words = [u32; 26215];
type Registermulteplicities = [Self::NumberOfZeros; 8];
}
impl WordType<4> for Precision18 {
type Words = [u32; 32768];
type Registermulteplicities = [Self::NumberOfZeros; 16];
}
impl WordType<5> for Precision18 {
type Words = [u32; 43691];
type Registermulteplicities = [Self::NumberOfZeros; 32];
}
impl WordType<6> for Precision18 {
type Words = [u32; 52429];
type Registermulteplicities = [Self::NumberOfZeros; 48];
}