Skip to main content

HashableScalar

Struct HashableScalar 

Source
pub struct HashableScalar<ScalarType: FpScalar> { /* private fields */ }
Expand description

Wrapper type that makes floating-point scalars hashable for use in hash-based collections.

§Purpose

Real or complex floating-point types (f32, f64, Complex<f32>, Complex<f64> and validated wrappers like RealNative64StrictFinite, ComplexNative64StrictFinite, RealRugStrictFinite<PRECISION>, ComplexRugStrictFinite<PRECISION>, etc.) are not hashable by default in Rust because of the presence of NaN values, which violate the requirements for hashing. Specifically, IEEE 754 defines that NaN != NaN, which means that two identical NaN values would not be considered equal, leading to inconsistent hashing behavior. do not implement Hash by default because IEEE 754 defines NaN != NaN, violating the requirement that a == b implies hash(a) == hash(b). This type enforces that only finite floating-point values can be hashed, making them safe for use in:

  • HashMap and HashSet
  • DashMap for concurrent caching
  • Any algorithm requiring consistent hashing of numerical values

§Invariants

  • Only finite values allowed: HashableScalar::try_new() rejects values that are not finite (not NaN or ±∞).
  • Hash consistency: Values are hashed via their raw bit representation (RawScalarTrait::compute_hash_raw_scalar), ensuring bitwise-identical values produce identical hashes.
  • Equality semantics: Implements Eq by delegating to the underlying scalar’s PartialEq, which is safe because we exclude NaN.

§Type Parameters

§Examples

§Basic Usage with f64 and Complex<f64>

use num_valid::scalars::HashableScalar;
use num::Complex;
use std::collections::HashSet;

let x = HashableScalar::new(3.14);
let y = HashableScalar::new(2.71);
let z = HashableScalar::new(3.14);

let mut set_real = HashSet::new();
set_real.insert(x);
set_real.insert(y);
set_real.insert(z); // Duplicate, won't be added

assert_eq!(set_real.len(), 2);

let a = HashableScalar::new(Complex::new(3.14, 2.0));
let b = HashableScalar::new(Complex::new(2.71, 1.0));
let c = HashableScalar::new(Complex::new(3.14, 2.0));

let mut set_complex = HashSet::new();
set_complex.insert(a);
set_complex.insert(b);
set_complex.insert(c); // Duplicate, won't be added

assert_eq!(set_complex.len(), 2);

§Use in Caching Structures

use num_valid::scalars::HashableScalar;
use std::collections::HashMap;

// Cache computed values indexed by floating-point parameters
let mut cache: HashMap<HashableScalar<f64>, String> = HashMap::new();

let key = HashableScalar::new(1.5);
cache.insert(key, "result_for_1.5".to_string());

let retrieved = cache.get(&HashableScalar::new(1.5));
assert_eq!(retrieved, Some(&"result_for_1.5".to_string()));

§With Validated Scalar Types

The wrapper works with any type implementing FpScalar, including validated types from the num_valid crate:

use num_valid::scalars::HashableScalar;
use std::collections::HashSet;

// Works with any FpScalar type
let mut set = HashSet::new();
set.insert(HashableScalar::new(1.0_f64));
set.insert(HashableScalar::new(2.0_f64));
set.insert(HashableScalar::new(1.0_f64)); // Duplicate

assert_eq!(set.len(), 2);

§Invalid Values

Fallible construction rejects non-finite values:

use num_valid::scalars::HashableScalar;

let invalid = HashableScalar::try_new(f64::NAN);
assert!(invalid.is_err());

§Implementation Notes

  • Serialization: Supports serde serialization/deserialization with bounds to ensure the wrapped type can be serialized.
  • Extraction: Implements IntoInner for consuming the wrapper and extracting the underlying scalar via .into_inner().
  • Zero-cost abstraction: The wrapper is #[repr(transparent)] equivalent (single field), so there is no runtime overhead.

§See Also

Implementations§

Source§

impl<ScalarType: FpScalar> HashableScalar<ScalarType>

Source

pub fn new(value: ScalarType) -> Self

Creates a new hashable scalar from a finite value.

§Panics

Panics if the value is not finite (NaN or infinite). Use Self::try_new when the input is not already trusted.

Source

pub fn try_new(value: ScalarType) -> Result<Self, ErrorsHashableScalar>

Attempts to create a hashable scalar from a finite value.

Returns ErrorsHashableScalar::NonFiniteValue when value is NaN or infinite.

Trait Implementations§

Source§

impl<ScalarType: FpScalar> AsRef<ScalarType> for HashableScalar<ScalarType>

Source§

fn as_ref(&self) -> &ScalarType

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<ScalarType: Clone + FpScalar> Clone for HashableScalar<ScalarType>

Source§

fn clone(&self) -> HashableScalar<ScalarType>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<ScalarType: Debug + FpScalar> Debug for HashableScalar<ScalarType>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, ScalarType> Deserialize<'de> for HashableScalar<ScalarType>
where ScalarType: for<'a> Deserialize<'a> + FpScalar,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<ScalarType: FpScalar> Eq for HashableScalar<ScalarType>

Source§

impl<ScalarType: FpScalar> Hash for HashableScalar<ScalarType>

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<ScalarType: FpScalar> IntoInner for HashableScalar<ScalarType>

Source§

type InnerType = ScalarType

The type of the inner value that will be extracted.
Source§

fn into_inner(self) -> ScalarType

Consumes the wrapper and returns the inner value.
Source§

impl<ScalarType: PartialEq + FpScalar> PartialEq for HashableScalar<ScalarType>

Source§

fn eq(&self, other: &HashableScalar<ScalarType>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<ScalarType: PartialOrd + FpScalar> PartialOrd for HashableScalar<ScalarType>

Source§

fn partial_cmp(&self, other: &HashableScalar<ScalarType>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<ScalarType> Serialize for HashableScalar<ScalarType>
where ScalarType: Serialize + FpScalar,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<ScalarType: PartialEq + FpScalar> StructuralPartialEq for HashableScalar<ScalarType>

Auto Trait Implementations§

§

impl<ScalarType> Freeze for HashableScalar<ScalarType>
where ScalarType: Freeze,

§

impl<ScalarType> RefUnwindSafe for HashableScalar<ScalarType>
where ScalarType: RefUnwindSafe,

§

impl<ScalarType> Send for HashableScalar<ScalarType>

§

impl<ScalarType> Sync for HashableScalar<ScalarType>

§

impl<ScalarType> Unpin for HashableScalar<ScalarType>
where ScalarType: Unpin,

§

impl<ScalarType> UnsafeUnpin for HashableScalar<ScalarType>
where ScalarType: UnsafeUnpin,

§

impl<ScalarType> UnwindSafe for HashableScalar<ScalarType>
where ScalarType: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> StrictAs for T

Source§

fn strict_as<Dst>(self) -> Dst
where T: StrictCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> StrictCastFrom<Src> for Dst
where Src: StrictCast<Dst>,

Source§

fn strict_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.