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//! - **`native64`:** 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//-----------------------------------------------------------------------------------------------
61/// A strict finite kernel validation policy for raw real numbers.
62/// This policy ensures that the real numbers are finite and not NaN.
63pub struct NumKernelStrictFinite<RawReal: RawRealTrait, const PRECISION: u32> {
64    _phantom: PhantomData<RawReal>,
65}
66
67impl<RawReal: RawRealTrait, const PRECISION: u32> RawKernel
68    for NumKernelStrictFinite<RawReal, PRECISION>
69{
70    type RawReal = RawReal;
71    type RawComplex = RawReal::RawComplex;
72}
73
74impl<RawReal: RawRealTrait, const PRECISION: u32> NumKernel
75    for NumKernelStrictFinite<RawReal, PRECISION>
76where
77    StrictFinitePolicy<RawReal, PRECISION>: ValidationPolicyReal<Value = RawReal>,
78    StrictFinitePolicy<RawReal::RawComplex, PRECISION>:
79        ValidationPolicyComplex<Value = RawReal::RawComplex>,
80{
81    type RealPolicy = StrictFinitePolicy<RawReal, PRECISION>;
82
83    type ComplexPolicy = StrictFinitePolicy<RawReal::RawComplex, PRECISION>;
84
85    type Real = RealValidated<Self>;
86    type Complex = ComplexValidated<Self>;
87}
88//-----------------------------------------------------------------------------------------------
89
90//-----------------------------------------------------------------------------------------------
91/// A debug-only strict finite kernel validation policy for raw real numbers.
92///
93/// This kernel applies [`StrictFinitePolicy`] validation only in debug builds.
94/// In release builds, validation is skipped for maximum performance.
95///
96/// ## Use Cases
97///
98/// - Performance-critical code where validation overhead is unacceptable in production
99/// - Code that has been thoroughly tested with [`NumKernelStrictFinite`] in debug mode
100///
101/// ## Comparison with `NumKernelStrictFinite`
102///
103/// | Aspect | `NumKernelStrictFinite` | `NumKernelStrictFiniteInDebug` |
104/// |--------|-------------------------|--------------------------------|
105/// | Debug validation | ✅ Yes | ✅ Yes |
106/// | Release validation | ✅ Yes | ❌ No |
107/// | `Eq + Hash + Ord` | ✅ Yes | ❌ No (not safe without validation) |
108/// | Performance | Slower | Faster in release |
109///
110/// ## Safety Note
111///
112/// Since validation is skipped in release builds, this kernel does NOT implement
113/// the [`GuaranteesFiniteRealValues`](crate::core::traits::validation::GuaranteesFiniteRealValues)
114/// marker trait, meaning it cannot be used with `HashMap`, `BTreeMap`, or other
115/// collections requiring `Eq` + `Hash` + `Ord`.
116pub struct NumKernelStrictFiniteInDebug<RawReal: RawRealTrait, const PRECISION: u32> {
117    _phantom: PhantomData<RawReal>,
118}
119
120impl<RawReal: RawRealTrait, const PRECISION: u32> RawKernel
121    for NumKernelStrictFiniteInDebug<RawReal, PRECISION>
122{
123    type RawReal = RawReal;
124    type RawComplex = RawReal::RawComplex;
125}
126
127impl<RawReal: RawRealTrait, const PRECISION: u32> NumKernel
128    for NumKernelStrictFiniteInDebug<RawReal, PRECISION>
129where
130    StrictFinitePolicy<RawReal, PRECISION>: ValidationPolicyReal<Value = RawReal>,
131    StrictFinitePolicy<RawReal::RawComplex, PRECISION>:
132        ValidationPolicyComplex<Value = RawReal::RawComplex>,
133{
134    type RealPolicy = DebugValidationPolicy<StrictFinitePolicy<RawReal, PRECISION>>;
135
136    type ComplexPolicy = DebugValidationPolicy<StrictFinitePolicy<RawReal::RawComplex, PRECISION>>;
137
138    type Real = RealValidated<Self>;
139    type Complex = ComplexValidated<Self>;
140}
141
142//-----------------------------------------------------------------------------------------------