[go: up one dir, main page]

randomize 2.2.0

A dead simple to use randomization library for rust.
Documentation
//! Module for MCGs with permuted output.
//!
//! An MCG is just an LCG without the add step. This makes them ever so slightly
//! faster. One whole add operation faster.
//!
//! Note: MCGs must have a non-zero state value, so they are not uniform
//! generators.

#![deprecated(since = "2.0.1", note = "You really shouldn't use these. It was a mistake to make them structs.")]

use super::*;

const DEFAULT_MCG_SEED: u128 = 0xcafef00dd15ea5e5;

/// An MCG with 8 bits of state
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MCGU8 {
  state: NonZeroU8,
}
impl MCGU8 {
  /// Seeds the generator
  pub const fn seed(seed: u8) -> Self {
    Self {
      state: unsafe { NonZeroU8::new_unchecked(seed | 1) },
    }
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: NonZeroU8) -> Self {
    Self { state }
  }
  /// Gives the next same-size output.
  pub fn next_u8(&mut self) -> u8 {
    let output = rxs_m_xs_8_8(self.state.get());
    let next_state = unsafe { NonZeroU8::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_8)) };
    self.state = next_state;
    output
  }
}
impl From<u64> for MCGU8 {
  fn from(seed: u64) -> Self {
    Self::seed(seed as u8)
  }
}
impl Default for MCGU8 {
  fn default() -> Self {
    Self::seed(DEFAULT_MCG_SEED as u8)
  }
}

/// An MCG with 16 bits of state
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MCGU16 {
  state: NonZeroU16,
}
impl MCGU16 {
  /// Seeds the generator
  pub const fn seed(seed: u16) -> Self {
    Self {
      state: unsafe { NonZeroU16::new_unchecked(seed | 1) },
    }
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: NonZeroU16) -> Self {
    Self { state }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u8(&mut self) -> u8 {
    let output = xsh_rr_16_8(self.state.get());
    let next_state = unsafe { NonZeroU16::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_16)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u8shift(&mut self) -> u8 {
    let output = xsh_rs_16_8(self.state.get());
    let next_state = unsafe { NonZeroU16::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_16)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u16(&mut self) -> u16 {
    let output = rxs_m_xs_16_16(self.state.get());
    let next_state = unsafe { NonZeroU16::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_16)) };
    self.state = next_state;
    output
  }
}
impl From<u64> for MCGU16 {
  fn from(seed: u64) -> Self {
    Self::seed(seed as u16)
  }
}
impl Default for MCGU16 {
  fn default() -> Self {
    Self::seed(DEFAULT_MCG_SEED as u16)
  }
}

/// An MCG with 32 bits of state
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MCGU32 {
  state: NonZeroU32,
}
impl MCGU32 {
  /// Seeds the generator
  pub const fn seed(seed: u32) -> Self {
    Self {
      state: unsafe { NonZeroU32::new_unchecked(seed | 1) },
    }
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: NonZeroU32) -> Self {
    Self { state }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u16(&mut self) -> u16 {
    let output = xsh_rr_32_16(self.state.get());
    let next_state = unsafe { NonZeroU32::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_32)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u16shift(&mut self) -> u16 {
    let output = xsh_rs_32_16(self.state.get());
    let next_state = unsafe { NonZeroU32::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_32)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u32(&mut self) -> u32 {
    let output = rxs_m_xs_32_32(self.state.get());
    let next_state = unsafe { NonZeroU32::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_32)) };
    self.state = next_state;
    output
  }
}
impl From<u64> for MCGU32 {
  fn from(seed: u64) -> Self {
    Self::seed(seed as u32)
  }
}
impl Default for MCGU32 {
  fn default() -> Self {
    Self::seed(DEFAULT_MCG_SEED as u32)
  }
}

/// An MCG with 64 bits of state
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MCGU64 {
  state: NonZeroU64,
}
impl MCGU64 {
  /// Seeds the generator
  pub const fn seed(seed: u64) -> Self {
    Self {
      state: unsafe { NonZeroU64::new_unchecked(seed | 1) },
    }
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: NonZeroU64) -> Self {
    Self { state }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u32(&mut self) -> u32 {
    let output = xsh_rr_64_32(self.state.get());
    let next_state = unsafe { NonZeroU64::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_64)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u32shift(&mut self) -> u32 {
    let output = xsh_rs_64_32(self.state.get());
    let next_state = unsafe { NonZeroU64::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_64)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using xsl rr
  pub fn next_u32xslrr(&mut self) -> u32 {
    let output = xsl_rr_64_32(self.state.get());
    let next_state = unsafe { NonZeroU64::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_64)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u64(&mut self) -> u64 {
    let output = rxs_m_xs_64_64(self.state.get());
    let next_state = unsafe { NonZeroU64::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_64)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output, using xsl rr rr
  pub fn next_u64xsl2rr(&mut self) -> u64 {
    let output = xsl_rr_rr_64_64(self.state.get());
    let next_state = unsafe { NonZeroU64::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_64)) };
    self.state = next_state;
    output
  }
}
impl From<u64> for MCGU64 {
  fn from(seed: u64) -> Self {
    Self::seed(seed)
  }
}
impl Default for MCGU64 {
  fn default() -> Self {
    Self::seed(DEFAULT_MCG_SEED as u64)
  }
}

/// An MCG with 128 bits of state
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct MCGU128 {
  state: NonZeroU128,
}
impl MCGU128 {
  /// Seeds the generator
  pub const fn seed(seed: u128) -> Self {
    Self {
      state: unsafe { NonZeroU128::new_unchecked(seed | 1) },
    }
  }
  /// Gives a generator of the exact values you put in
  pub const fn exact(state: NonZeroU128) -> Self {
    Self { state }
  }
  /// Gives the next half-size output, using rotation
  pub fn next_u64(&mut self) -> u64 {
    let output = xsh_rr_128_64(self.state.get());
    let next_state = unsafe { NonZeroU128::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_128)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using a shift
  pub fn next_u64shift(&mut self) -> u64 {
    let output = xsh_rs_128_64(self.state.get());
    let next_state = unsafe { NonZeroU128::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_128)) };
    self.state = next_state;
    output
  }
  /// Gives the next half-size output, using xsl rr
  pub fn next_u64xslrr(&mut self) -> u64 {
    let output = xsl_rr_128_64(self.state.get());
    let next_state = unsafe { NonZeroU128::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_128)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output.
  pub fn next_u128(&mut self) -> u128 {
    let output = rxs_m_xs_128_128(self.state.get());
    let next_state = unsafe { NonZeroU128::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_128)) };
    self.state = next_state;
    output
  }
  /// Gives the next same-size output, using xsl rr rr
  pub fn next_u128xsl2rr(&mut self) -> u128 {
    let output = xsl_rr_rr_128_128(self.state.get());
    let next_state = unsafe { NonZeroU128::new_unchecked(self.state.get().wrapping_mul(PCG_DEFAULT_MULTIPLIER_128)) };
    self.state = next_state;
    output
  }
}
impl From<u64> for MCGU128 {
  fn from(seed: u64) -> Self {
    Self::seed(seed as u128)
  }
}
impl Default for MCGU128 {
  fn default() -> Self {
    Self::seed(DEFAULT_MCG_SEED)
  }
}