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//-----------------------------------------------------------------------------------------------