Skip to main content

num_valid/
kernels.rs

1#![deny(rustdoc::broken_intra_doc_links)]
2
3//! # Numerical Kernels and Validated Types
4//!
5//! This module is the core of the numerical backend for the [`num-valid`](crate) crate.
6//! It defines the fundamental traits, types, and operations for floating-point arithmetic.
7//!
8//! ## Core Architecture
9//!
10//! The architecture is built on three key concepts:
11//!
12//! 1.  **Raw Traits ([`RawScalarTrait`], [`RawRealTrait`], [`RawComplexTrait`]):**
13//!     These traits define the baseline contract for a "raw" number type (like [`f64`] or
14//!     [`rug::Float`](https://docs.rs/rug/latest/rug/struct.Float.html)).
15//!     They provide a comprehensive set of `unchecked_*` methods for arithmetic and mathematical
16//!     functions. The "unchecked" prefix signifies that these methods do **not** perform
17//!     any validation (e.g., for domain, finiteness, or division by zero) and are intended
18//!     for internal use where validity has already been confirmed.
19//!
20//! 2.  **Validated Structs ([`RealValidated`], [`ComplexValidated`]):**
21//!     These are wrapper types (newtypes) that enforce correctness. An instance of `RealValidated<P>`
22//!     is guaranteed to hold a raw value that has been successfully validated against the policy `P`.
23//!     All operations on these types (addition, `sqrt`, etc.) are designed to preserve this validity,
24//!     either by returning a `Result` or by panicking on failure in debug builds.
25//!
26//! 3.  **Validation Policies ([`NumKernel`]):**
27//!     This trait allows the validation strategy to be generic. A kernel can be configured with
28//!     different policies, such as [`NumKernelStrictFinite`], which ensures all numbers are
29//!     finite (not NaN or Infinity).
30//!
31//! ## Available Kernels
32//!
33//! The library provides concrete kernels that bundle these concepts:
34//!
35//! - **`native`:** Uses Rust's standard [`f64`] and `num::Complex<f64>` as the raw types.
36//!   This is the default, high-performance kernel.
37//!
38//! - **`rug` (feature-gated):** Uses arbitrary-precision types from the [`rug`](https://crates.io/crates/rug) crate,
39//!   ideal for high-precision scientific computing.
40
41pub use crate::core::types::{ComplexValidated, RealValidated};
42
43// Re-export raw traits from core::traits::raw
44pub use crate::core::traits::raw::{
45    RawComplexTrait, RawRealTrait, RawScalarHyperbolic, RawScalarPow, RawScalarTrait,
46    RawScalarTrigonometric,
47};
48
49use crate::core::{
50    policies::{DebugValidationPolicy, StrictFinitePolicy},
51    traits::{
52        NumKernel, RawKernel,
53        validation::{ValidationPolicyComplex, ValidationPolicyReal},
54    },
55};
56use std::marker::PhantomData;
57
58//------------------------------------------------------------------------------------------------------------
59
60//-----------------------------------------------------------------------------------------------
61pub trait PrecisionBits {
62    /// Returns the precision (in bits) of the floating-point type.
63    fn precision_bits(&self) -> u32;
64}
65
66/*
67struct StaticPrecisionBits<const PRECISION: u32>;
68
69impl<const PRECISION: u32> PrecisionBits for StaticPrecisionBits<PRECISION> {
70    fn precision_bits(&self) -> u32 {
71        PRECISION
72    }
73}
74
75struct DynamicPrecisionBits {
76    precision: u32,
77}
78
79impl PrecisionBits for DynamicPrecisionBits {
80    fn precision_bits(&self) -> u32 {
81        self.precision
82    }
83}
84    */
85//------------------------------------------------------------------------------------------------------------
86
87//-----------------------------------------------------------------------------------------------
88/// A strict finite kernel validation policy for raw real numbers.
89/// This policy ensures that the real numbers are finite and not NaN.
90pub struct NumKernelStrictFinite<RawReal: RawRealTrait, const PRECISION: u32> {
91    _phantom: PhantomData<RawReal>,
92}
93
94impl<RawReal, const PRECISION: u32> RawKernel for NumKernelStrictFinite<RawReal, PRECISION>
95where
96    RawReal: RawRealTrait,
97{
98    type RawReal = RawReal;
99    type RawComplex = RawReal::RawComplex;
100}
101
102impl<RawReal, const PRECISION: u32> NumKernel for NumKernelStrictFinite<RawReal, PRECISION>
103where
104    RawReal: RawRealTrait,
105    StrictFinitePolicy<RawReal, PRECISION>: ValidationPolicyReal<Value = RawReal>,
106    StrictFinitePolicy<RawReal::RawComplex, PRECISION>:
107        ValidationPolicyComplex<Value = RawReal::RawComplex>,
108{
109    type RealPolicy = StrictFinitePolicy<RawReal, PRECISION>;
110
111    type ComplexPolicy = StrictFinitePolicy<RawReal::RawComplex, PRECISION>;
112
113    type Real = RealValidated<Self>;
114    type Complex = ComplexValidated<Self>;
115}
116//-----------------------------------------------------------------------------------------------
117
118//-----------------------------------------------------------------------------------------------
119/// A debug-only strict finite kernel validation policy for raw real numbers.
120///
121/// This kernel applies [`StrictFinitePolicy`] validation only in debug builds.
122/// In release builds, validation is skipped for maximum performance.
123///
124/// ## Use Cases
125///
126/// - Performance-critical code where validation overhead is unacceptable in production
127/// - Code that has been thoroughly tested with [`NumKernelStrictFinite`] in debug mode
128///
129/// ## Comparison with `NumKernelStrictFinite`
130///
131/// | Aspect | `NumKernelStrictFinite` | `NumKernelStrictFiniteInDebug` |
132/// |--------|-------------------------|--------------------------------|
133/// | Debug validation | ✅ Yes | ✅ Yes |
134/// | Release validation | ✅ Yes | ❌ No |
135/// | `Eq + Hash + Ord` | ✅ Yes | ❌ No (not safe without validation) |
136/// | Performance | Slower | Faster in release |
137///
138/// ## Safety Note
139///
140/// Since validation is skipped in release builds, this kernel does NOT implement
141/// the [`GuaranteesFiniteRealValues`](crate::core::traits::validation::GuaranteesFiniteRealValues)
142/// marker trait, meaning it cannot be used with `HashMap`, `BTreeMap`, or other
143/// collections requiring `Eq` + `Hash` + `Ord`.
144pub struct NumKernelStrictFiniteInDebug<RawReal: RawRealTrait, const PRECISION: u32> {
145    _phantom: PhantomData<RawReal>,
146}
147
148impl<RawReal, const PRECISION: u32> RawKernel for NumKernelStrictFiniteInDebug<RawReal, PRECISION>
149where
150    RawReal: RawRealTrait,
151{
152    type RawReal = RawReal;
153    type RawComplex = RawReal::RawComplex;
154}
155
156impl<RawReal: RawRealTrait, const PRECISION: u32> NumKernel
157    for NumKernelStrictFiniteInDebug<RawReal, PRECISION>
158where
159    RawReal: RawRealTrait,
160    StrictFinitePolicy<RawReal, PRECISION>: ValidationPolicyReal<Value = RawReal>,
161    StrictFinitePolicy<RawReal::RawComplex, PRECISION>:
162        ValidationPolicyComplex<Value = RawReal::RawComplex>,
163{
164    type RealPolicy = DebugValidationPolicy<StrictFinitePolicy<RawReal, PRECISION>>;
165
166    type ComplexPolicy = DebugValidationPolicy<StrictFinitePolicy<RawReal::RawComplex, PRECISION>>;
167
168    type Real = RealValidated<Self>;
169    type Complex = ComplexValidated<Self>;
170}
171
172//-----------------------------------------------------------------------------------------------