num_valid/kernels/
validated.rs

1#![deny(rustdoc::broken_intra_doc_links)]
2
3use crate::{
4    ACos, ACosH, ASin, ASinH, ATan, ATan2, ATanH, Abs, Arg, Arithmetic, ComplexScalar,
5    ComplexScalarConstructors, ComplexScalarGetParts, ComplexScalarMutateParts,
6    ComplexScalarSetParts, Conjugate, Constants, Cos, CosH, Exp, FpChecks, FpScalar,
7    HyperbolicFunctions, Ln, Log2, Log10, LogarithmFunctions, Max, Min, MulAddRef, NegAssign,
8    NeumaierAddable, Pow, PowIntExponent, RealNative64StrictFinite,
9    RealNative64StrictFiniteInDebug, RealScalar, Reciprocal, Sin, SinH, Sqrt, Tan, TanH,
10    TrigonometricFunctions,
11    functions::{
12        ACosComplexErrors, ACosHErrors, ACosHInputErrors, ACosRealErrors, ACosRealInputErrors,
13        ASinComplexErrors, ASinHErrors, ASinRealErrors, ASinRealInputErrors, ATan2Errors,
14        ATan2InputErrors, ATanComplexErrors, ATanComplexInputErrors, ATanHErrors, ATanHInputErrors,
15        ATanRealErrors, AbsComplexErrors, AbsRealErrors, ArgErrors, ArgInputErrors, Clamp,
16        Classify, CosErrors, CosHErrors, ExpErrors, ExpM1, Hypot, Ln1p, LogarithmComplexErrors,
17        LogarithmComplexInputErrors, LogarithmRealErrors, LogarithmRealInputErrors,
18        PowComplexBaseRealExponentErrors, PowComplexBaseRealExponentInputErrors,
19        PowIntExponentErrors, PowIntExponentInputErrors, PowRealBaseRealExponentErrors,
20        PowRealBaseRealExponentInputErrors, ReciprocalErrors, ReciprocalInputErrors, Rounding,
21        Sign, SinErrors, SinHErrors, SqrtComplexErrors, SqrtRealErrors, SqrtRealInputErrors,
22        TanComplexErrors, TanHComplexErrors, TanHComplexInputErrors, TanHRealErrors, TanRealErrors,
23        TanRealInputErrors, TotalCmp,
24    },
25    kernels::{NumKernel, RawComplexTrait, RawRealTrait, RawScalarTrait},
26    neumaier_compensated_sum::NeumaierSum,
27    scalar_kind,
28    validation::{
29        ErrorsTryFromf64, ValidationPolicyComplex, ValidationPolicyReal, capture_backtrace,
30    },
31};
32use bytemuck::CheckedBitPattern;
33use derive_more::with_trait::{AsRef, Debug, Display, LowerExp};
34use duplicate::duplicate_item;
35use num::{One, Zero};
36use paste::paste;
37use rand::{
38    Rng,
39    distr::{Distribution, StandardUniform},
40};
41use serde::{Deserialize, Serialize};
42use std::{
43    cmp::Ordering,
44    iter::Sum,
45    marker::PhantomData,
46    num::FpCategory,
47    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
48};
49use try_create::{IntoInner, New, TryNew, TryNewValidated, ValidationPolicy};
50
51// --- MACRO HELPER 1: For the binary operations like: Add, Sub, Mul, Div ---
52// Generates the 4 implementations (T op T, &T op T, T op &T, &T op &T)
53macro_rules! __impl_validated_arithmetic_op {
54    (
55        $StructName:ident, $PolicyType:ident, $trait_name:ident, $method_name:ident, $msg:literal,
56        // This is an optional block of code that can be used to perform pre-checks before the operation like division by zero
57        // e.g., `debug_assert!(!rhs.is_zero(), "Division by zero!");`
58        {$($pre_check:tt)*}
59    ) => {
60        // T op T
61        impl<K: NumKernel> $trait_name<$StructName<K>> for $StructName<K> {
62            type Output = Self;
63            #[inline(always)]
64            fn $method_name(self, rhs: Self) -> Self::Output {
65                let _ = $($pre_check)*(&rhs);
66                Self::try_new_validated(self.value.$method_name(rhs.value)).expect($msg)
67            }
68        }
69        // &T op T
70        impl<'a, K: NumKernel> $trait_name<$StructName<K>> for &'a $StructName<K> {
71            type Output = $StructName<K>;
72            #[inline(always)]
73            fn $method_name(self, rhs: $StructName<K>) -> Self::Output {
74                let _ = $($pre_check)*(&rhs);
75                $StructName::<K>::try_new_validated(self.value.clone().$method_name(rhs.value)).expect($msg)
76            }
77        }
78        // T op &T
79        impl<'a, K: NumKernel> $trait_name<&'a $StructName<K>> for $StructName<K> {
80            type Output = Self;
81            #[inline(always)]
82            fn $method_name(self, rhs: &'a Self) -> Self::Output {
83                let _ = $($pre_check)*(rhs);
84                Self::try_new_validated(self.value.$method_name(&rhs.value)).expect($msg)
85            }
86        }
87        // &T op &T
88        impl<'a, K: NumKernel> $trait_name<&'a $StructName<K>> for &'a $StructName<K> {
89            type Output = $StructName<K>;
90            #[inline(always)]
91            fn $method_name(self, rhs: &'a $StructName<K>) -> Self::Output {
92                let _ = $($pre_check)*(rhs);
93                $StructName::<K>::try_new_validated(self.value.clone().$method_name(&rhs.value)).expect($msg)
94            }
95        }
96    };
97}
98
99// --- MACRO HELPER 2: For the assignment operations like: AddAssign, SubAssign, etc. ---
100// Generates the 2 implementations (T op= T, T op= &T)
101macro_rules! __impl_validated_arithmetic_op_assign {
102    (
103        $StructName:ident, $PolicyType:ident, $trait_name:ident, $method_name:ident, $msg:literal,
104        {$($pre_check:tt)*}
105    ) => {
106        // T op= T
107        impl<K: NumKernel> $trait_name<$StructName<K>> for $StructName<K> {
108            #[inline(always)]
109            fn $method_name(&mut self, rhs: Self) {
110                let _ = $($pre_check)*(&rhs);
111                self.value.$method_name(rhs.value);
112                let _ = K::$PolicyType::validate_ref(&self.value).expect($msg);
113            }
114        }
115        // T op= &T
116        impl<'a, K: NumKernel> $trait_name<&'a $StructName<K>> for $StructName<K> {
117            #[inline(always)]
118            fn $method_name(&mut self, rhs: &'a Self) {
119                let _ = $($pre_check)*(rhs);
120                self.value.$method_name(&rhs.value);
121                let _ = K::$PolicyType::validate_ref(&self.value).expect($msg);
122            }
123        }
124    };
125}
126
127// --- MACRO HELPER 3: For both op and assignment op ---
128macro_rules! __impl_validated_arithmetic_op_and_op_assign {
129    (
130        $StructName:ident, $PolicyType:ident, $trait_name:ident, $method_name:ident, $msg:literal,
131        {$($pre_check:tt)*}
132    ) => {
133        paste! {
134            // First, implement the binary operation
135            __impl_validated_arithmetic_op!(
136                $StructName,
137                $PolicyType,
138                $trait_name,
139                $method_name,
140                $msg,
141                {$($pre_check)*}
142            );
143            // Then, implement the assignment operation (we use the crate "paste" to generate the correct trait and method names)
144            __impl_validated_arithmetic_op_assign!(
145                $StructName,
146                $PolicyType,
147                [<$trait_name Assign>], // attach the string "Assign" at the end of the $trait_name
148                [<$method_name _assign>], // attach the string "_assign" at the end of the $method_name
149                $msg,
150                {$($pre_check)*}
151            );
152        }
153    };
154}
155
156/// A macro to define a validated numeric struct (`RealValidated` or `ComplexValidated`)
157/// and implement a host of standard traits for it.
158///
159/// This macro is the cornerstone of the validated type system. It generates:
160/// 1.  The struct definition itself (e.g., `pub struct RealValidated<K>`).
161/// 2.  Core trait impls: `IntoInner`, `Clone`, `PartialEq`, `Zero`, `One`, `FpChecks`.
162/// 3.  Constructor impls: `TryNewValidated`, `TryNew`, `New` (with debug-only checks).
163/// 4.  Arithmetic impls: `Add`, `Sub`, `Mul`, `Div` and their `*Assign` variants
164///     for all four reference combinations (T op T, &T op T, etc.).
165/// 5.  `Neg`, `NegAssign`, and `MulAddRef` implementations.
166/// 6.  `Sum` implementation using a compensated Neumaier summation algorithm for accuracy.
167macro_rules! define_validated_struct {
168    (
169        // The name of the struct to define (e.g., RealValidated)
170        $StructName:ident,
171        // The associated policy type on NumKernel (e.g., RealPolicy)
172        $PolicyType:ident,
173        // The type of the value inside the struct (e.g., RawReal or RawComplex)
174        $RawType:ident,
175        // The documentation string for the struct
176        $doc:literal,
177        // The string to use in the `Display` and `LowerExp` attributes
178        $display_string:literal
179    ) => {
180        #[doc = $doc]
181        #[repr(transparent)]
182        #[derive(AsRef, Debug, Display, LowerExp, Serialize, Deserialize)]
183        #[display($display_string, value)]
184        #[lower_exp($display_string, value)]
185        pub struct $StructName<K: NumKernel> {
186            #[as_ref]
187            pub(crate) value: K::$RawType,
188
189            pub(crate) _phantom: PhantomData<K>,
190        }
191
192        //------------------------------------------------------------------
193        // Conditional Copy implementation is defined outside the macro
194        // (see the end of this file) because it requires different bounds
195        // for RealValidated (K::RawReal: Copy) vs ComplexValidated (K::RawComplex: Copy).
196        //------------------------------------------------------------------
197
198        impl<K: NumKernel> IntoInner for $StructName<K> {
199            type InnerType = K::$RawType;
200            //type InnerType = <<K as NumKernel>::$PolicyType as ValidationPolicy>::Value;
201
202            #[inline(always)]
203            fn into_inner(self) -> Self::InnerType {
204                self.value
205            }
206        }
207        impl<K: NumKernel> Clone for $StructName<K> {
208            #[inline(always)]
209            fn clone(&self) -> Self {
210                Self {
211                    value: self.value.clone(),
212                    _phantom: PhantomData,
213                }
214            }
215        }
216        impl<K: NumKernel> PartialEq for $StructName<K> {
217            #[inline(always)]
218            fn eq(&self, other: &Self) -> bool {
219                self.value.eq(&other.value)
220            }
221        }
222        impl<K: NumKernel> TryNewValidated for $StructName<K> {
223            type Policy = K::$PolicyType;
224
225            #[inline(always)]
226            fn try_new_validated(value: Self::InnerType) -> Result<Self, Self::Error> {
227                let value = Self::Policy::validate(value)?;
228                Ok(Self {
229                    value,
230                    _phantom: PhantomData,
231                })
232            }
233        }
234        impl<K: NumKernel> TryNew for $StructName<K> {
235            type Error = <<K as NumKernel>::$PolicyType as ValidationPolicy>::Error;
236
237            #[inline(always)]
238            fn try_new(value: Self::InnerType) -> Result<Self, Self::Error> {
239                Self::try_new_validated(value)
240            }
241        }
242        impl<K: NumKernel> New for $StructName<K> {
243            #[inline(always)]
244            fn new(value: Self::InnerType) -> Self {
245                #[cfg(debug_assertions)]
246                {
247                    Self::try_new_validated(value)
248                        .expect("Error calling try_new_validated() inside new() in debug mode")
249                }
250                #[cfg(not(debug_assertions))]
251                {
252                    Self {
253                        value,
254                        _phantom: PhantomData,
255                    }
256                }
257            }
258        }
259        impl<K: NumKernel> Zero for $StructName<K> {
260            #[inline(always)]
261            fn zero() -> Self {
262                Self {
263                    value: <Self as IntoInner>::InnerType::raw_zero(
264                        <K as NumKernel>::$PolicyType::PRECISION,
265                    ),
266                    _phantom: PhantomData,
267                }
268            }
269
270            #[inline(always)]
271            fn is_zero(&self) -> bool {
272                self.value.is_zero()
273            }
274        }
275        impl<K: NumKernel> One for $StructName<K> {
276            #[inline(always)]
277            fn one() -> Self {
278                Self {
279                    value: <Self as IntoInner>::InnerType::raw_one(
280                        <K as NumKernel>::$PolicyType::PRECISION,
281                    ),
282                    _phantom: PhantomData,
283                }
284            }
285        }
286        impl<K: NumKernel> FpChecks for $StructName<K> {
287            /// Returns `true` if `self` is neither infinite nor NaN.
288            #[inline(always)]
289            fn is_finite(&self) -> bool {
290                self.value.is_finite()
291            }
292
293            /// Returns `true` if `self` is positive infinity or negative infinity, and `false` otherwise.
294            #[inline(always)]
295            fn is_infinite(&self) -> bool {
296                self.value.is_infinite()
297            }
298
299            /// Returns `true` if `self` is NaN.
300            #[inline(always)]
301            fn is_nan(&self) -> bool {
302                self.value.is_nan()
303            }
304
305            /// Returns `true` if `self` is *normal* (i.e. neither zero, infinite, subnormal, or NaN).
306            #[inline(always)]
307            fn is_normal(&self) -> bool {
308                self.value.is_normal()
309            }
310        }
311        impl<K: NumKernel> NeumaierAddable for $StructName<K> {
312            fn neumaier_compensated_sum(value: Self, sum: &mut Self, compensation: &mut Self) {
313                NeumaierAddable::neumaier_compensated_sum(
314                    value.value,
315                    &mut sum.value,
316                    &mut compensation.value,
317                );
318                let _ = K::$PolicyType::validate_ref(&sum.value)
319                    .expect("Neumaier compensated sum failed validation for sum");
320                let _ = K::$PolicyType::validate_ref(&compensation.value)
321                    .expect("Neumaier compensated sum failed validation for compensation");
322            }
323        }
324        impl<K: NumKernel> Sum for $StructName<K> {
325            fn sum<I>(iter: I) -> Self
326            where
327                I: Iterator<Item = Self>,
328            {
329                // Using Neumaier's algorithm for compensated summation.
330                // This algorithm helps to reduce the numerical error in the sum of floating-point numbers.
331                // It maintains a running sum and a compensation term to account for small errors.
332                NeumaierSum::new_sequential(iter).sum()
333            }
334        }
335
336        // --- Implementations of the core traits for arithmetic operations, delegated to the Macro Helpers ---
337        __impl_validated_arithmetic_op_and_op_assign!(
338            $StructName,
339            $PolicyType,
340            Add,
341            add,
342            "Addition failed validation",
343            {}
344        );
345
346        __impl_validated_arithmetic_op_and_op_assign!(
347            $StructName,
348            $PolicyType,
349            Sub,
350            sub,
351            "Subtraction failed validation",
352            {}
353        );
354
355        __impl_validated_arithmetic_op_and_op_assign!(
356            $StructName,
357            $PolicyType,
358            Mul,
359            mul,
360            "Multiplication failed validation",
361            {}
362        );
363
364        __impl_validated_arithmetic_op_and_op_assign!(
365            $StructName,
366            $PolicyType,
367            Div,
368            div,
369            "Division failed validation",
370            {} //{debug_assert!(!rhs.is_zero(), "Division by zero!");}
371        );
372
373        // --- Implementation of Neg ---
374        impl<K: NumKernel> Neg for $StructName<K> {
375            type Output = Self;
376            #[inline(always)]
377            fn neg(self) -> Self::Output {
378                // Negation of a valid number is assumed to be valid (e.g., finite -> finite)
379                Self {
380                    value: -self.value,
381                    _phantom: PhantomData,
382                }
383            }
384        }
385        impl<K: NumKernel> NegAssign for $StructName<K> {
386            /// Performs the negation of `self`.
387            #[inline(always)]
388            fn neg_assign(&mut self) {
389                self.value.neg_assign();
390            }
391        }
392
393        // --- Implementation of MulAddRef ---
394        impl<K: NumKernel> MulAddRef for $StructName<K> {
395            /// Multiplies and adds in one fused operation, rounding to the nearest with only one rounding error.
396            ///
397            /// `a.mul_add(b, c)` produces a result like `a * &b + &c`.
398            #[inline(always)]
399            fn mul_add_ref(self, b: &Self, c: &Self) -> Self {
400                Self::try_new_validated(self.value.unchecked_mul_add(&b.value, &c.value))
401                    .expect("MulAddRef failed validation")
402            }
403        }
404    };
405}
406
407//----------------------------------------------------------------------------------
408// Now, use the macro to generate everything for the RealValidated struct
409define_validated_struct!(
410    RealValidated,
411    RealPolicy,
412    RawReal,
413    "A validated real number that is guaranteed to conform to a specific [`NumKernel`].",
414    "RealValidated({})"
415);
416
417impl<K: NumKernel> PartialOrd for RealValidated<K> {
418    #[inline(always)]
419    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
420        self.value.partial_cmp(&other.value)
421    }
422}
423
424impl<K: NumKernel> PartialEq<f64> for RealValidated<K> {
425    #[inline(always)]
426    fn eq(&self, other: &f64) -> bool {
427        self.value.eq(other)
428    }
429}
430
431impl<K: NumKernel> PartialOrd<f64> for RealValidated<K> {
432    #[inline(always)]
433    fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
434        self.value.partial_cmp(other)
435    }
436}
437
438impl<K: NumKernel> Sqrt for RealValidated<K> {
439    type Error = SqrtRealErrors<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
440
441    #[inline(always)]
442    fn try_sqrt(self) -> Result<Self, Self::Error> {
443        let value = self.value;
444        if value < 0.0 {
445            Err(SqrtRealInputErrors::NegativeValue {
446                value,
447                backtrace: capture_backtrace(),
448            }
449            .into())
450        } else {
451            Self::try_new_validated(value.unchecked_sqrt())
452                .map_err(|e| SqrtRealErrors::Output { source: e })
453        }
454    }
455
456    #[inline(always)]
457    fn sqrt(self) -> Self {
458        self.try_sqrt().expect(
459            "Error raised by the function Sqrt::try_sqrt() inside the function Sqrt::sqrt()",
460        )
461    }
462}
463
464impl<K: NumKernel> Sign for RealValidated<K> {
465    /// Returns `true` if the value is negative, −0 or NaN with a negative sign.
466    #[inline(always)]
467    fn kernel_is_sign_negative(&self) -> bool {
468        self.value.kernel_is_sign_negative()
469    }
470
471    /// Returns `true` if the value is positive, +0 or NaN with a positive sign.
472    #[inline(always)]
473    fn kernel_is_sign_positive(&self) -> bool {
474        self.value.kernel_is_sign_positive()
475    }
476
477    /// Returns a number with the magnitude of `self` and the sign of `sign`.
478    #[inline(always)]
479    fn kernel_copysign(self, sign: &Self) -> Self {
480        Self {
481            value: self.value.kernel_copysign(&sign.value),
482            _phantom: PhantomData,
483        }
484    }
485
486    /// Returns the signum of the number.
487    #[inline(always)]
488    fn kernel_signum(self) -> Self {
489        Self {
490            value: self.value.kernel_signum(),
491            _phantom: PhantomData,
492        }
493    }
494}
495
496impl<K: NumKernel> Rounding for RealValidated<K> {
497    /// Returns the smallest integer greater than or equal to `self`.
498    #[inline(always)]
499    fn kernel_ceil(self) -> Self {
500        Self::try_new_validated(self.value.kernel_ceil()).expect(
501            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_ceil()",
502        )
503    }
504
505    /// Returns the largest integer smaller than or equal to `self`.
506    #[inline(always)]
507    fn kernel_floor(self) -> Self {
508        Self::try_new_validated(self.value.kernel_floor()).expect(
509            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_floor()",
510        )
511    }
512
513    /// Returns the fractional part of `self`.
514    #[inline(always)]
515    fn kernel_fract(self) -> Self {
516        Self::try_new_validated(self.value.kernel_fract()).expect(
517            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_fract()",
518        )
519    }
520
521    /// Rounds `self` to the nearest integer, rounding half-way cases away from zero.
522    #[inline(always)]
523    fn kernel_round(self) -> Self {
524        Self::try_new_validated(self.value.kernel_round()).expect(
525            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_round()",
526        )
527    }
528
529    /// Returns the nearest integer to a number. Rounds half-way cases to the number with an even least significant digit.
530    ///
531    /// This function always returns the precise result.
532    ///
533    /// # Examples
534    /// ```
535    /// use num_valid::{
536    ///     functions::Rounding,
537    ///     RealNative64StrictFinite,
538    /// };
539    /// use try_create::TryNew;
540    ///
541    /// let f = RealNative64StrictFinite::try_new(3.3).unwrap();
542    /// let g = RealNative64StrictFinite::try_new(-3.3).unwrap();
543    /// let h = RealNative64StrictFinite::try_new(3.5).unwrap();
544    /// let i = RealNative64StrictFinite::try_new(-4.5).unwrap();
545    ///
546    /// assert_eq!(f.kernel_round_ties_even(), RealNative64StrictFinite::try_new(3.).unwrap());
547    /// assert_eq!(g.kernel_round_ties_even(), RealNative64StrictFinite::try_new(-3.).unwrap());
548    /// assert_eq!(h.kernel_round_ties_even(), RealNative64StrictFinite::try_new(4.).unwrap());
549    /// assert_eq!(i.kernel_round_ties_even(), RealNative64StrictFinite::try_new(-4.).unwrap());
550    /// ```
551    #[inline(always)]
552    fn kernel_round_ties_even(self) -> Self {
553        Self::try_new_validated(self.value.kernel_round_ties_even()).expect(
554            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_round_ties_even()",
555        )
556    }
557
558    /// Returns the integer part of `self`. This means that non-integer numbers are always truncated towards zero.
559    ///    
560    /// # Examples
561    /// ```
562    /// use num_valid::{
563    ///     functions::Rounding,
564    ///     RealNative64StrictFinite,
565    /// };
566    /// use try_create::TryNew;
567    ///
568    /// let f = RealNative64StrictFinite::try_new(3.7).unwrap();
569    /// let g = RealNative64StrictFinite::try_new(3.).unwrap();
570    /// let h = RealNative64StrictFinite::try_new(-3.7).unwrap();
571    ///
572    /// assert_eq!(f.kernel_trunc(), RealNative64StrictFinite::try_new(3.).unwrap());
573    /// assert_eq!(g.kernel_trunc(), RealNative64StrictFinite::try_new(3.).unwrap());
574    /// assert_eq!(h.kernel_trunc(), RealNative64StrictFinite::try_new(-3.).unwrap());
575    /// ```
576    #[inline(always)]
577    fn kernel_trunc(self) -> Self {
578        Self::try_new_validated(self.value.kernel_trunc()).expect(
579            "Error raised by RealValidated::try_new_validated() inside the function Rounding::kernel_trunc()",
580        )
581    }
582}
583
584impl<K: NumKernel> RealValidated<K> {
585    /// Creates a new `RealValidated` instance from a raw value using the provided factory function.
586    ///
587    /// # Arguments
588    /// * `raw_factory` - A function that takes a precision and returns a raw real value.
589    /// * `err_msg` - A static error message to use if validation fails.
590    ///
591    /// # Returns
592    /// A `RealValidated<K>` instance if the raw value is valid, otherwise it panics with the provided error message.
593    #[inline(always)]
594    fn from_raw_factory<F: Fn(u32) -> K::RawReal>(raw_factory: F, err_msg: &'static str) -> Self {
595        // This is a (private) factory function that creates a RealValidated instance from a raw value.
596        // It uses the raw_factory function to get the raw value based on the precision defined in
597        // the policy, and then attempts to create a RealValidated instance with that value.
598        let raw_value = raw_factory(<K::RealPolicy as ValidationPolicyReal>::PRECISION);
599
600        Self::try_new_validated(raw_value).expect(err_msg)
601    }
602}
603
604impl<K: NumKernel> Constants for RealValidated<K> {
605    #[duplicate_item(
606        func           raw_func;
607        [pi]           [raw_pi];
608        [two_pi]       [raw_two_pi];
609        [pi_div_2]     [raw_pi_div_2];
610        [one_div_2]    [raw_one_div_2];
611        [two]          [raw_two];
612        [max_finite]   [raw_max_finite];
613        [min_finite]   [raw_min_finite];
614        [epsilon]      [raw_epsilon];
615        [negative_one] [raw_negative_one];
616        [ln_2]         [raw_ln_2];
617        [ln_10]        [raw_ln_10];
618        [log2_e]       [raw_log2_e];
619        [log10_e]      [raw_log10_e];
620        [e]            [raw_e];
621        [log2_10]      [raw_log2_10];
622        [log10_2]      [raw_log10_2];
623    )]
624    #[inline(always)]
625    fn func() -> Self {
626        // Use `paste` to generate the error message dynamically.
627        // This creates a compile-time string like:
628        // "Error raised by RealValidated::try_new_validated() inside RealValidated::pi()"
629        paste::paste! {
630            Self::from_raw_factory(
631                K::RawReal::raw_func,
632                concat!("Error raised by RealValidated::try_new_validated() inside RealValidated::", stringify!([<func>]), "()"))
633        }
634    }
635}
636
637//----------------------------------------------------------------------------------
638
639//----------------------------------------------------------------------------------
640// Now, use the macro to generate everything for the ComplexValidated struct
641define_validated_struct!(
642    ComplexValidated,
643    ComplexPolicy,
644    RawComplex,
645    "A validated complex number that is guaranteed to conform to a specific [`NumKernel`].",
646    "ComplexValidated({})"
647);
648
649impl<K: NumKernel> Conjugate for ComplexValidated<K> {
650    #[inline(always)]
651    fn conjugate(self) -> Self {
652        Self {
653            value: self.value.conjugate(),
654            _phantom: PhantomData,
655        }
656    }
657}
658
659impl<K: NumKernel> Sqrt for ComplexValidated<K> {
660    type Error = SqrtComplexErrors<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
661
662    #[inline(always)]
663    fn try_sqrt(self) -> Result<Self, Self::Error> {
664        Self::try_new_validated(self.value.unchecked_sqrt())
665            .map_err(|e| SqrtComplexErrors::Output { source: e })
666    }
667
668    #[inline(always)]
669    fn sqrt(self) -> Self {
670        self.try_sqrt().expect(
671            "Error raised by the function Sqrt::try_sqrt() inside the function Sqrt::sqrt()",
672        )
673    }
674}
675
676//----------------------------------------------------------------------------------
677
678//----------------------------------------------------------------------------------
679impl<K: NumKernel> Arithmetic for RealValidated<K> {}
680impl<K: NumKernel> Arithmetic for ComplexValidated<K> {}
681//----------------------------------------------------------------------------------
682
683//----------------------------------------------------------------------------------
684// --- MACRO HELPER: For mixed operations Complex op Real ---
685macro_rules! __impl_complex_real_arithmetic {
686    (
687        $op_trait:ident, $op_method:ident,
688        $assign_trait:ident, $assign_method:ident,
689        $msg:literal,
690        {$($pre_check:tt)*}
691    ) => {
692        // --- Implementation of mixed arithmetic operations (Complex op Real) ---
693        // Complex op Real
694        impl<K: NumKernel> $op_trait<RealValidated<K>> for ComplexValidated<K>
695        where
696            // Bound: The raw complex type must support the operation with the raw real type
697            <K::ComplexPolicy as ValidationPolicy>::Value: $op_trait<<K::RealPolicy as ValidationPolicy>::Value, Output = <K::ComplexPolicy as ValidationPolicy>::Value>,
698        {
699            type Output = ComplexValidated<K>;
700            #[inline(always)]
701            fn $op_method(self, rhs: RealValidated<K>) -> Self::Output {
702                let _ = $($pre_check)*(rhs);
703                Self::try_new_validated(self.value.$op_method(rhs.value)).expect($msg)
704            }
705        }
706        // Complex op &Real
707        impl<'a, K: NumKernel> $op_trait<&'a RealValidated<K>> for ComplexValidated<K>
708        where
709             <K::ComplexPolicy as ValidationPolicy>::Value: $op_trait<&'a <K::RealPolicy as ValidationPolicy>::Value, Output = <K::ComplexPolicy as ValidationPolicy>::Value>,
710        {
711            type Output = ComplexValidated<K>;
712            #[inline(always)]
713            fn $op_method(self, rhs: &'a RealValidated<K>) -> Self::Output {
714                let _ = $($pre_check)*(rhs);
715                ComplexValidated::<K>::try_new_validated(self.value.$op_method(&rhs.value)).expect($msg)
716            }
717        }
718        /*
719        // &Complex op &Real
720        impl<'a, K: NumKernel> $op_trait<&'a RealValidated<K>> for &'a ComplexValidated<K>
721        where
722             <K::ComplexPolicy as ValidationPolicy>::Value: $op_trait<&'a <K::RealPolicy as ValidationPolicy>::Value, Output = <K::ComplexPolicy as ValidationPolicy>::Value>,
723        {
724            type Output = ComplexValidated<K>;
725            #[inline(always)]
726            fn $op_method(self, rhs: &'a RealValidated<K>) -> Self::Output {
727                $($pre_check)*(rhs);
728                ComplexValidated::<K>::try_new_validated(self.value.clone().$op_method(rhs.as_ref())).expect($msg)
729            }
730        }
731        */
732
733        // --- Implementazione dell'operazione di assegnamento (es. Complex *= Real) ---
734        // Complex op= Real
735        impl<K: NumKernel> $assign_trait<RealValidated<K>> for ComplexValidated<K>
736        where
737            // Bound: Il tipo complesso grezzo deve supportare l'operazione di assegnamento con il tipo reale grezzo
738            <K::ComplexPolicy as ValidationPolicy>::Value: $assign_trait<<K::RealPolicy as ValidationPolicy>::Value>,
739        {
740            #[inline(always)]
741            fn $assign_method(&mut self, rhs: RealValidated<K>) {
742                let _ = $($pre_check)*(rhs);
743                self.value.$assign_method(rhs.value);
744                let _ = K::ComplexPolicy::validate_ref(&self.value).expect(concat!($msg, " (assign)"));
745            }
746        }
747        // Complex op= &Real
748        impl<'a, K: NumKernel> $assign_trait<&'a RealValidated<K>> for ComplexValidated<K>
749        where
750            <K::ComplexPolicy as ValidationPolicy>::Value: $assign_trait<&'a <K::RealPolicy as ValidationPolicy>::Value>,
751        {
752            #[inline(always)]
753            fn $assign_method(&mut self, rhs: &'a RealValidated<K>) {
754                let _ = $($pre_check)*(rhs);
755                self.value.$assign_method(&rhs.value);
756                let _ = K::ComplexPolicy::validate_ref(&self.value).expect(concat!($msg, " (assign)"));
757            }
758        }
759    };
760}
761
762// --- MACRO HELPER: For mixed operations Real op Complex ---
763macro_rules! __impl_real_complex_arithmetic {
764    (
765        $op_trait:ident, $op_method:ident,
766        $assign_trait:ident, $assign_method:ident,
767        $msg:literal,
768        {$($pre_check:tt)*}
769    ) => {
770        // --- Implementation of mixed arithmetic operations (Real op Complex) ---
771        // Real op Complex
772        impl<K: NumKernel> $op_trait<ComplexValidated<K>> for RealValidated<K>
773        where
774            // Bound: The raw real type must support the operation with the raw complex type
775            <K::RealPolicy as ValidationPolicy>::Value: $op_trait<<K::ComplexPolicy as ValidationPolicy>::Value, Output = <K::ComplexPolicy as ValidationPolicy>::Value>,
776        {
777            type Output = ComplexValidated<K>;
778            #[inline(always)]
779            fn $op_method(self, rhs: ComplexValidated<K>) -> Self::Output {
780                let _ = $($pre_check)*(rhs);
781                Self::Output::try_new_validated(self.value.$op_method(rhs.value)).expect($msg)
782            }
783        }
784        // &Real op Complex
785        impl<'a, K: NumKernel> $op_trait<ComplexValidated<K>> for &'a RealValidated<K>
786        where
787            // Bound: The raw real type must support the operation with the raw complex type
788            <K::RealPolicy as ValidationPolicy>::Value: $op_trait<<K::ComplexPolicy as ValidationPolicy>::Value, Output = <K::ComplexPolicy as ValidationPolicy>::Value>,
789        {
790            type Output = ComplexValidated<K>;
791            #[inline(always)]
792            fn $op_method(self, rhs: ComplexValidated<K>) -> Self::Output {
793                let _ = $($pre_check)*(rhs);
794                Self::Output::try_new_validated(self.value.clone().$op_method(rhs.value)).expect($msg)
795            }
796        }
797    };
798}
799//----------------------------------------------------------------------------------
800
801//----------------------------------------------------------------------------------
802// --- Implementation of mixed arithmetic operations (Complex op Real) ---
803//----------------------------------------------------------------------------------
804__impl_complex_real_arithmetic!(
805    Add,
806    add,
807    AddAssign,
808    add_assign,
809    "Complex + Real failed validation",
810    {}
811);
812__impl_complex_real_arithmetic!(
813    Sub,
814    sub,
815    SubAssign,
816    sub_assign,
817    "Complex - Real failed validation",
818    {}
819);
820__impl_complex_real_arithmetic!(
821    Mul,
822    mul,
823    MulAssign,
824    mul_assign,
825    "Complex * Real failed validation",
826    {}
827);
828__impl_complex_real_arithmetic!(
829    Div,
830    div,
831    DivAssign,
832    div_assign,
833    "Complex / Real failed validation",
834    {} //{debug_assert!(!rhs.is_zero(), "Division of complex by zero real!");}
835);
836
837//----------------------------------------------------------------------------------
838// --- Implementation of mixed arithmetic operations (Real op Complex) ---
839//----------------------------------------------------------------------------------
840__impl_real_complex_arithmetic!(
841    Mul,
842    mul,
843    MulAssign,
844    mul_assign,
845    "Real * Complex failed validation",
846    {}
847);
848//----------------------------------------------------------------------------------
849
850//----------------------------------------------------------------------------------
851// --- Implementation of the Abs trait ---
852#[duplicate_item(
853    T E;
854    [RealValidated]    [AbsRealErrors<<K::RealPolicy as ValidationPolicy>::Value>];
855    [ComplexValidated] [AbsComplexErrors<<K::ComplexPolicy as ValidationPolicy>::Value>];
856)]
857impl<K: NumKernel> Abs for T<K> {
858    type Output = RealValidated<K>;
859    type Error = E;
860
861    #[inline(always)]
862    fn try_abs(self) -> Result<Self::Output, Self::Error> {
863        Self::Output::try_new_validated(self.value.unchecked_abs())
864            .map_err(|e| Self::Error::Output { source: e })
865    }
866
867    /// Returns the *absolute value* of `self`.
868    #[inline(always)]
869    fn abs(self) -> Self::Output {
870        self.try_abs()
871            .expect("Error raised by the function Abs::try_abs() inside the function Abs::abs()")
872    }
873}
874
875//----------------------------------------------------------------------------------
876
877//------------------------------------------------------------------------------------------------
878// --- Implementation of the Reciprocal trait ---
879#[duplicate_item(
880    T;
881    [RealValidated];
882    [ComplexValidated];
883)]
884impl<K: NumKernel> Reciprocal for T<K> {
885    type Error = ReciprocalErrors<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
886
887    #[inline(always)]
888    fn try_reciprocal(self) -> Result<Self, Self::Error> {
889        if self.value.is_zero() {
890            Err(ReciprocalInputErrors::DivisionByZero {
891                backtrace: capture_backtrace(),
892            }
893            .into())
894        } else {
895            Self::try_new_validated(self.value.unchecked_reciprocal())
896                .map_err(|e| Self::Error::Output { source: e })
897        }
898    }
899
900    #[inline(always)]
901    fn reciprocal(self) -> Self {
902        self.try_reciprocal().expect("Error raised by the function Reciprocal::try_reciprocal() inside the function Reciprocal::reciprocal()")
903    }
904}
905//------------------------------------------------------------------------------------------------
906
907//----------------------------------------------------------------------------------
908//impl<K: NumKernel> FpScalar for RealValidated<K> {}
909//impl<K: NumKernel> FpScalar for ComplexValidated<K> {}
910//----------------------------------------------------------------------------------
911
912//------------------------------------------------------------------------------------------------
913/// Macro to implement a unary operation for a type that can be validated.
914/// This macro generates an implementation of a trait for a type, providing methods to try the operation
915/// and to perform the operation directly, handling errors appropriately.
916///
917/// The macro takes the trait name, the method names for trying and performing the operation,
918/// the error type, and the type itself as parameters.
919/// The `try_method` returns a `Result` with the type or an error, while the `method` returns the type directly,
920/// panicking if an error occurs.
921/// This is useful for types that require validation before performing operations, such as `rug::Float` or `rug::Complex`.
922///
923/// Note: this macro does not perform any check on the validity of the domain of the operation.
924/// It is the responsibility of the caller to ensure that the input is valid for the operation.
925macro_rules! impl_validated_unary_op {
926    ($Trait:ident, $method:ident, $Err:ident, $StructName:ty) => {
927        paste! {
928            impl<K: NumKernel> $Trait for $StructName<K> {
929                type Error = $Err<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
930
931                #[inline(always)]
932                fn [<try_ $method>](self) -> Result<Self, Self::Error> {
933                    Self::try_new_validated(self.value.[<unchecked_ $method>]())
934                        .map_err(|e| Self::Error::Output { source: e })
935                }
936
937                #[inline(always)]
938                fn $method(self) -> Self {
939                    self.[<try_ $method>]().expect(concat!(
940                        "Error raised by the function ",
941                        stringify!($Trait),
942                        "::",
943                        stringify!($try_method),
944                        "()",
945                        " in the function ",
946                        stringify!($Trait),
947                        "::",
948                        stringify!($method),
949                        "()"
950                    ))
951                }
952            }
953        }
954    };
955}
956
957//------------------------------------------------------------------------------------------------
958impl_validated_unary_op!(Exp, exp, ExpErrors, RealValidated);
959impl_validated_unary_op!(Exp, exp, ExpErrors, ComplexValidated);
960//------------------------------------------------------------------------------------------------
961
962//------------------------------------------------------------------------------------------------
963impl_validated_unary_op!(Sin, sin, SinErrors, RealValidated);
964impl_validated_unary_op!(Sin, sin, SinErrors, ComplexValidated);
965//------------------------------------------------------------------------------------------------
966
967//------------------------------------------------------------------------------------------------
968impl_validated_unary_op!(Cos, cos, CosErrors, RealValidated);
969impl_validated_unary_op!(Cos, cos, CosErrors, ComplexValidated);
970//------------------------------------------------------------------------------------------------
971
972//------------------------------------------------------------------------------------------------
973impl_validated_unary_op!(SinH, sinh, SinHErrors, RealValidated);
974impl_validated_unary_op!(SinH, sinh, SinHErrors, ComplexValidated);
975//------------------------------------------------------------------------------------------------
976
977//------------------------------------------------------------------------------------------------
978impl_validated_unary_op!(ASinH, asinh, ASinHErrors, RealValidated);
979impl_validated_unary_op!(ASinH, asinh, ASinHErrors, ComplexValidated);
980//------------------------------------------------------------------------------------------------
981
982//------------------------------------------------------------------------------------------------
983impl_validated_unary_op!(CosH, cosh, CosHErrors, RealValidated);
984impl_validated_unary_op!(CosH, cosh, CosHErrors, ComplexValidated);
985//------------------------------------------------------------------------------------------------
986
987//------------------------------------------------------------------------------------------------
988impl_validated_unary_op!(ATan, atan, ATanRealErrors, RealValidated);
989//------------------------------------------------------------------------------------------------
990
991//------------------------------------------------------------------------------------------------
992impl_validated_unary_op!(TanH, tanh, TanHRealErrors, RealValidated);
993//------------------------------------------------------------------------------------------------
994
995//------------------------------------------------------------------------------------------------
996impl_validated_unary_op!(ASin, asin, ASinComplexErrors, ComplexValidated);
997//------------------------------------------------------------------------------------------------
998
999//------------------------------------------------------------------------------------------------
1000impl_validated_unary_op!(ACos, acos, ACosComplexErrors, ComplexValidated);
1001//------------------------------------------------------------------------------------------------
1002
1003//------------------------------------------------------------------------------------------------
1004impl_validated_unary_op!(Tan, tan, TanComplexErrors, ComplexValidated);
1005//------------------------------------------------------------------------------------------------
1006
1007//------------------------------------------------------------------------------------------------
1008impl<K: NumKernel> ATan2 for RealValidated<K> {
1009    type Error = ATan2Errors<K::RawReal>;
1010
1011    fn try_atan2(self, denominator: &Self) -> Result<Self, Self::Error> {
1012        let numerator = self.value;
1013        let denominator = &denominator.value;
1014        if RawScalarTrait::is_zero(&numerator) && RawScalarTrait::is_zero(denominator) {
1015            Err(ATan2InputErrors::ZeroOverZero {
1016                backtrace: capture_backtrace(),
1017            }
1018            .into())
1019        } else {
1020            Self::try_new_validated(numerator.unchecked_atan2(denominator))
1021                .map_err(|e| Self::Error::Output { source: e })
1022        }
1023    }
1024
1025    fn atan2(self, denominator: &Self) -> Self {
1026        self.try_atan2(denominator).expect(
1027            "Error raised by the function ATan2::try_atan2() inside the function ATan2::atan2()",
1028        )
1029    }
1030}
1031//------------------------------------------------------------------------------------------------
1032
1033//------------------------------------------------------------------------------------------------
1034#[duplicate_item(
1035    T                  Trait  try_func   func   unchecked_func   E                   ErrIn                    value_is_a_pole;
1036    [RealValidated]    [Tan]  [try_tan]  [tan]  [unchecked_tan]  [TanRealErrors]     [TanRealInputErrors]     [self.value.clone().unchecked_cos().is_zero()];
1037    [ComplexValidated] [ATan] [try_atan] [atan] [unchecked_atan] [ATanComplexErrors] [ATanComplexInputErrors] [*self.value.raw_real_part() == 0. && (*self.value.raw_imag_part() == 1. || *self.value.raw_imag_part() == -1.)]
1038)]
1039impl<K: NumKernel> Trait for T<K> {
1040    type Error = E<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
1041
1042    #[inline(always)]
1043    fn try_func(self) -> Result<Self, Self::Error> {
1044        if value_is_a_pole {
1045            Err(ErrIn::ArgumentIsPole {
1046                value: self.value,
1047                backtrace: capture_backtrace(),
1048            }
1049            .into())
1050        } else {
1051            Self::try_new_validated(self.value.unchecked_func())
1052                .map_err(|e| Self::Error::Output { source: e })
1053        }
1054    }
1055
1056    #[inline(always)]
1057    fn func(self) -> Self {
1058        self.try_func().unwrap()
1059    }
1060}
1061//------------------------------------------------------------------------------------------------
1062
1063//------------------------------------------------------------------------------------------------
1064#[duplicate_item(
1065    T                  Trait   try_func    func    unchecked_func    E                   ErrIn                    value_is_not_in_domain;
1066    [RealValidated]    [ACosH] [try_acosh] [acosh] [unchecked_acosh] [ACosHErrors]       [ACosHInputErrors]       [self.value < 1.];
1067    [ComplexValidated] [ACosH] [try_acosh] [acosh] [unchecked_acosh] [ACosHErrors]       [ACosHInputErrors]       [self.value.raw_imag_part() == &0. && self.value.raw_real_part() < &1.];
1068    [RealValidated]    [ATanH] [try_atanh] [atanh] [unchecked_atanh] [ATanHErrors]       [ATanHInputErrors]       [self.value <= -1. || self.value >= 1.];
1069    [ComplexValidated] [ATanH] [try_atanh] [atanh] [unchecked_atanh] [ATanHErrors]       [ATanHInputErrors]       [self.value.raw_imag_part() == &0. && (self.value.raw_real_part() <= &-1. || self.value.raw_real_part() >= &1.)];
1070    [ComplexValidated] [TanH]  [try_tanh]  [tanh]  [unchecked_tanh]  [TanHComplexErrors] [TanHComplexInputErrors] [RawScalarTrait::is_zero(&self.value.clone().unchecked_cosh())];
1071    [RealValidated]    [ASin]  [try_asin]  [asin]  [unchecked_asin]  [ASinRealErrors]    [ASinRealInputErrors]    [self.value < -1.0 || self.value > 1.0];
1072    [RealValidated]    [ACos]  [try_acos]  [acos]  [unchecked_acos]  [ACosRealErrors]    [ACosRealInputErrors]    [self.value < -1.0 || self.value > 1.0];
1073)]
1074impl<K: NumKernel> Trait for T<K> {
1075    type Error = E<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
1076
1077    #[inline(always)]
1078    fn try_func(self) -> Result<Self, Self::Error> {
1079        if value_is_not_in_domain {
1080            Err(ErrIn::OutOfDomain {
1081                value: self.value,
1082                backtrace: capture_backtrace(),
1083            }
1084            .into())
1085        } else {
1086            Self::try_new_validated(self.value.unchecked_func())
1087                .map_err(|e| Self::Error::Output { source: e })
1088        }
1089    }
1090
1091    #[inline(always)]
1092    fn func(self) -> Self {
1093        self.try_func().unwrap()
1094    }
1095}
1096//------------------------------------------------------------------------------------------------
1097
1098//------------------------------------------------------------------------------------------------
1099/// Implement the [`ComplexScalarConstructors`] trait for the [`ComplexValidated`] type.
1100impl<K: NumKernel> ComplexScalarConstructors for ComplexValidated<K> {
1101    type RawComplex = K::RawComplex;
1102
1103    fn try_new_complex(
1104        real_part: K::RawReal,
1105        imag_part: K::RawReal,
1106    ) -> Result<Self, <Self::RawComplex as RawScalarTrait>::ValidationErrors> {
1107        let complex = K::RawComplex::new_unchecked_raw_complex(real_part, imag_part);
1108        Self::try_new_validated(complex)
1109    }
1110}
1111//------------------------------------------------------------------------------------------------
1112
1113//------------------------------------------------------------------------------------------------
1114/// Implement the [`ComplexScalarGetParts`] trait for the [`ComplexValidated`] type.
1115impl<K: NumKernel> ComplexScalarGetParts for ComplexValidated<K> {
1116    /// Get the real part of the complex number.
1117    #[inline(always)]
1118    fn real_part(&self) -> RealValidated<K> {
1119        RealValidated {
1120            value: self.value.raw_real_part().clone(),
1121            _phantom: PhantomData,
1122        }
1123    }
1124
1125    /// Get the imaginary part of the complex number.
1126    #[inline(always)]
1127    fn imag_part(&self) -> RealValidated<K> {
1128        RealValidated {
1129            value: self.value.raw_imag_part().clone(),
1130            _phantom: PhantomData,
1131        }
1132    }
1133
1134    #[inline(always)]
1135    fn raw_real_part(&self) -> &K::RawReal {
1136        self.value.raw_real_part()
1137    }
1138
1139    #[inline(always)]
1140    fn raw_imag_part(&self) -> &K::RawReal {
1141        self.value.raw_imag_part()
1142    }
1143}
1144//------------------------------------------------------------------------------------------------
1145
1146//------------------------------------------------------------------------------------------------
1147/// Implement the [`ComplexScalarSetParts`] trait for the [`ComplexValidated`] type.
1148impl<K: NumKernel> ComplexScalarSetParts for ComplexValidated<K> {
1149    /// Set the value of the real part.
1150    #[inline(always)]
1151    fn set_real_part(&mut self, real_part: RealValidated<K>) {
1152        *self.value.mut_raw_real_part() = real_part.value;
1153    }
1154
1155    /// Set the value of the imaginary part.
1156    #[inline(always)]
1157    fn set_imaginary_part(&mut self, imag_part: RealValidated<K>) {
1158        *self.value.mut_raw_imag_part() = imag_part.value;
1159    }
1160}
1161//------------------------------------------------------------------------------------------------
1162
1163//------------------------------------------------------------------------------------------------
1164/// Implement the [`ComplexScalarMutateParts`] trait for the [`ComplexValidated`] type.
1165impl<K: NumKernel> ComplexScalarMutateParts for ComplexValidated<K> {
1166    /// Add the value of the the real coefficient `c` to real part of `self`.
1167    #[inline(always)]
1168    fn add_to_real_part(&mut self, c: &RealValidated<K>) {
1169        let real_part = self.value.mut_raw_real_part();
1170        *real_part += &c.value;
1171        K::RealPolicy::validate_ref(real_part)
1172            .expect("Error raised by validate_ref() inside ComplexValidated::add_to_real_part()");
1173    }
1174
1175    /// Add the value of the the real coefficient `c` to imaginary part of `self`.
1176    #[inline(always)]
1177    fn add_to_imaginary_part(&mut self, c: &RealValidated<K>) {
1178        let imag_part = self.value.mut_raw_imag_part();
1179        *imag_part += &c.value;
1180        K::RealPolicy::validate_ref(imag_part).expect(
1181            "Error raised by validate_ref() inside ComplexValidated::add_to_imaginary_part()",
1182        );
1183    }
1184
1185    /// Multiply the value of the real part by the real coefficient `c`.
1186    #[inline(always)]
1187    fn multiply_real_part(&mut self, c: &RealValidated<K>) {
1188        let real_part = self.value.mut_raw_real_part();
1189        *real_part *= &c.value;
1190        K::RealPolicy::validate_ref(real_part)
1191            .expect("Error raised by validate_ref() inside ComplexValidated::multiply_real_part()");
1192    }
1193
1194    /// Multiply the value of the imaginary part by the real coefficient `c`.
1195    #[inline(always)]
1196    fn multiply_imaginary_part(&mut self, c: &RealValidated<K>) {
1197        let imag_part = self.value.mut_raw_imag_part();
1198        *imag_part *= &c.value;
1199        K::RealPolicy::validate_ref(imag_part).expect(
1200            "Error raised by validate_ref() inside ComplexValidated::multiply_imaginary_part()",
1201        );
1202    }
1203}
1204
1205//------------------------------------------------------------------------------------------------
1206
1207//------------------------------------------------------------------------------------------------
1208impl<K: NumKernel> Arg for ComplexValidated<K> {
1209    type Output = RealValidated<K>;
1210    type Error = ArgErrors<K::RawComplex>;
1211
1212    #[inline(always)]
1213    fn try_arg(self) -> Result<Self::Output, Self::Error> {
1214        if RawScalarTrait::is_zero(&self.value) {
1215            Err(ArgInputErrors::Zero {
1216                backtrace: capture_backtrace(),
1217            }
1218            .into())
1219        } else {
1220            Self::Output::try_new_validated(self.value.unchecked_arg())
1221                .map_err(|e| Self::Error::Output { source: e })
1222        }
1223    }
1224
1225    #[inline(always)]
1226    fn arg(self) -> RealValidated<K> {
1227        self.try_arg()
1228            .expect("Error calling ComplexValidated::try_arg() inside ComplexValidated::arg()")
1229    }
1230}
1231//------------------------------------------------------------------------------------------------
1232
1233//------------------------------------------------------------------------------------------------
1234#[duplicate_item(
1235    trait_name try_func    func    unchecked_func;
1236    [Ln]       [try_ln]    [ln]    [unchecked_ln];
1237    [Log10]    [try_log10] [log10] [unchecked_log10];
1238    [Log2]     [try_log2]  [log2]  [unchecked_log2];
1239)]
1240impl<K: NumKernel> trait_name for RealValidated<K> {
1241    type Error =
1242        LogarithmRealErrors<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
1243
1244    #[inline(always)]
1245    fn try_func(self) -> Result<Self, Self::Error> {
1246        if self.value < 0.0 {
1247            Err(LogarithmRealInputErrors::NegativeArgument {
1248                value: self.value,
1249                backtrace: capture_backtrace(),
1250            }
1251            .into())
1252        } else if self.value == 0. {
1253            Err(LogarithmRealInputErrors::ZeroArgument {
1254                backtrace: capture_backtrace(),
1255            }
1256            .into())
1257        } else {
1258            Self::try_new_validated(self.value.unchecked_func())
1259                .map_err(|e| Self::Error::Output { source: e })
1260        }
1261    }
1262
1263    #[inline(always)]
1264    fn func(self) -> Self {
1265        self.try_func().unwrap()
1266    }
1267}
1268
1269#[duplicate_item(
1270    trait_name try_func    func    unchecked_func;
1271    [Ln]       [try_ln]    [ln]    [unchecked_ln];
1272    [Log10]    [try_log10] [log10] [unchecked_log10];
1273    [Log2]     [try_log2]  [log2]  [unchecked_log2];
1274)]
1275impl<K: NumKernel> trait_name for ComplexValidated<K> {
1276    type Error =
1277        LogarithmComplexErrors<<<Self as TryNewValidated>::Policy as ValidationPolicy>::Value>;
1278
1279    #[inline(always)]
1280    fn try_func(self) -> Result<Self, Self::Error> {
1281        if RawScalarTrait::is_zero(&self.value) {
1282            Err(LogarithmComplexInputErrors::ZeroArgument {
1283                backtrace: capture_backtrace(),
1284            }
1285            .into())
1286        } else {
1287            Self::try_new_validated(self.value.unchecked_func())
1288                .map_err(|e| Self::Error::Output { source: e })
1289        }
1290    }
1291
1292    #[inline(always)]
1293    fn func(self) -> Self {
1294        self.try_func().unwrap()
1295    }
1296}
1297//------------------------------------------------------------------------------------------------
1298
1299//------------------------------------------------------------------------------------------------
1300impl<K: NumKernel> Pow<&RealValidated<K>> for RealValidated<K> {
1301    type Error = PowRealBaseRealExponentErrors<K::RawReal>;
1302
1303    #[inline(always)]
1304    fn try_pow(self, exponent: &Self) -> Result<Self, Self::Error> {
1305        if self.value < 0.0 {
1306            Err(PowRealBaseRealExponentInputErrors::NegativeBase {
1307                base: self.value,
1308                exponent: exponent.value.clone(),
1309                backtrace: capture_backtrace(),
1310            }
1311            .into())
1312        } else {
1313            Self::try_new(self.value.unchecked_pow_exponent_real(&exponent.value))
1314                .map_err(|e| Self::Error::Output { source: e })
1315        }
1316    }
1317
1318    /// Raises th number `self` to the power `exponent`.
1319    #[inline(always)]
1320    fn pow(self, exponent: &Self) -> Self {
1321        self.try_pow(exponent)
1322            .expect("Error raised by the function Pow::try_pow() in the function Pow::pow()!")
1323    }
1324}
1325
1326impl<K: NumKernel> Pow<&RealValidated<K>> for ComplexValidated<K> {
1327    type Error = PowComplexBaseRealExponentErrors<K::RawComplex>;
1328
1329    #[inline(always)]
1330    fn try_pow(self, exponent: &RealValidated<K>) -> Result<Self, Self::Error> {
1331        if self.is_zero() {
1332            if *exponent < 0.0 {
1333                Err(
1334                    PowComplexBaseRealExponentInputErrors::ZeroBaseNegativeExponent {
1335                        exponent: exponent.value.clone(),
1336                        backtrace: capture_backtrace(),
1337                    }
1338                    .into(),
1339                )
1340            } else if *exponent == 0.0 {
1341                Ok(Self::one())
1342            } else {
1343                Ok(Self::zero())
1344            }
1345        } else {
1346            Self::try_new_validated(self.value.unchecked_pow_exponent_real(&exponent.value))
1347                .map_err(|e| Self::Error::Output { source: e })
1348        }
1349    }
1350
1351    /// Raises th number `self` to the power `exponent`.
1352    #[inline(always)]
1353    fn pow(self, exponent: &RealValidated<K>) -> Self {
1354        self.try_pow(exponent)
1355            .expect("Error raised by the function Pow::try_pow() in the function Pow::pow()!")
1356    }
1357}
1358//------------------------------------------------------------------------------------------------
1359
1360//------------------------------------------------------------------------------------------------
1361#[duplicate_item(
1362    T exponent_type unchecked_func;
1363    duplicate!{
1364        [struct_name; [RealValidated]; [ComplexValidated]]
1365        [struct_name] [i8]    [unchecked_pow_exponent_i8];
1366        [struct_name] [i16]   [unchecked_pow_exponent_i16];
1367        [struct_name] [i32]   [unchecked_pow_exponent_i32];
1368        [struct_name] [i64]   [unchecked_pow_exponent_i64];
1369        [struct_name] [i128]  [unchecked_pow_exponent_i128];
1370        [struct_name] [isize] [unchecked_pow_exponent_isize];
1371    }
1372)]
1373impl<K: NumKernel> Pow<exponent_type> for T<K> {
1374    type Error = PowIntExponentErrors<
1375        <<Self as TryNewValidated>::Policy as ValidationPolicy>::Value,
1376        exponent_type,
1377    >;
1378
1379    fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
1380        if RawScalarTrait::is_zero(&self.value) && exponent < 0 {
1381            Err(PowIntExponentInputErrors::ZeroBaseNegativeExponent {
1382                exponent,
1383                backtrace: capture_backtrace(),
1384            }
1385            .into())
1386        } else {
1387            Self::try_new_validated(self.value.unchecked_func(&exponent))
1388                .map_err(|e| Self::Error::Output { source: e })
1389        }
1390    }
1391
1392    /// Raises th number `self` to the power `exponent`.
1393    #[inline(always)]
1394    fn pow(self, exponent: exponent_type) -> Self {
1395        self.try_pow(exponent)
1396            .expect("Error raised by the function Pow::try_pow() in the function Pow::pow()!")
1397    }
1398}
1399
1400#[duplicate_item(
1401    T exponent_type unchecked_func;
1402    duplicate!{
1403        [struct_name; [RealValidated]; [ComplexValidated]]
1404        [struct_name] [u8]    [unchecked_pow_exponent_u8];
1405        [struct_name] [u16]   [unchecked_pow_exponent_u16];
1406        [struct_name] [u32]   [unchecked_pow_exponent_u32];
1407        [struct_name] [u64]   [unchecked_pow_exponent_u64];
1408        [struct_name] [u128]  [unchecked_pow_exponent_u128];
1409        [struct_name] [usize] [unchecked_pow_exponent_usize];
1410    }
1411)]
1412impl<K: NumKernel> Pow<exponent_type> for T<K> {
1413    type Error = PowIntExponentErrors<
1414        <<Self as TryNewValidated>::Policy as ValidationPolicy>::Value,
1415        exponent_type,
1416    >;
1417
1418    fn try_pow(self, exponent: exponent_type) -> Result<Self, Self::Error> {
1419        Self::try_new_validated(self.value.unchecked_func(&exponent))
1420            .map_err(|e| Self::Error::Output { source: e })
1421    }
1422
1423    /// Raises th number `self` to the power `exponent`.
1424    #[inline(always)]
1425    fn pow(self, exponent: exponent_type) -> Self {
1426        self.try_pow(exponent)
1427            .expect("Error raised by the function Pow::try_pow() in the function Pow::pow()!")
1428    }
1429}
1430
1431impl<K: NumKernel> PowIntExponent for RealValidated<K> {
1432    type RawType = K::RawReal;
1433}
1434
1435impl<K: NumKernel> PowIntExponent for ComplexValidated<K> {
1436    type RawType = K::RawComplex;
1437}
1438//------------------------------------------------------------------------------------------------
1439
1440//------------------------------------------------------------------------------------------------
1441impl<K: NumKernel> Max for RealValidated<K> {}
1442impl<K: NumKernel> Min for RealValidated<K> {}
1443//------------------------------------------------------------------------------------------------
1444
1445//------------------------------------------------------------------------------------------------
1446impl<K: NumKernel> Clamp for RealValidated<K> {
1447    /// Clamps the value within the specified bounds.
1448    #[inline(always)]
1449    fn clamp(self, min: &Self, max: &Self) -> Self {
1450        Self::try_new_validated(self.value.raw_clamp(&min.value, &max.value)).expect(
1451            "Error raised by RealValidated::try_new_validated() inside RealValidated::clamp()",
1452        )
1453    }
1454}
1455
1456impl<K: NumKernel> Classify for RealValidated<K> {
1457    /// Returns the floating point category of the number. If only one property is going to be tested,
1458    /// it is generally faster to use the specific predicate instead.
1459    /// ```
1460    /// use num_valid::{
1461    ///     functions::Classify,
1462    ///     kernels::native64_validated::RealNative64StrictFinite,
1463    /// };
1464    /// use std::num::FpCategory;
1465    /// use try_create::TryNew;
1466    ///
1467    /// let num = RealNative64StrictFinite::try_new(12.4).unwrap();
1468    ///
1469    /// assert_eq!(num.classify(), FpCategory::Normal);
1470    /// ```
1471    #[inline(always)]
1472    fn classify(&self) -> FpCategory {
1473        self.value.raw_classify()
1474    }
1475}
1476
1477impl<K: NumKernel> ExpM1 for RealValidated<K> {
1478    /// Returns `e^(self) - 1`` in a way that is accurate even if the number is close to zero.
1479    #[inline(always)]
1480    fn exp_m1(self) -> Self {
1481        Self::try_new_validated(self.value.unchecked_exp_m1()).expect(
1482            "Error raised by RealValidated::try_new_validated() inside RealValidated::exp_m1()",
1483        )
1484    }
1485}
1486
1487impl<K: NumKernel> Ln1p for RealValidated<K> {
1488    /// Returns `ln(1. + self)` (natural logarithm) more accurately than if the operations were performed separately.
1489    #[inline(always)]
1490    fn ln_1p(self) -> Self {
1491        Self::try_new_validated(self.value.unchecked_ln_1p()).expect(
1492            "Error raised by RealValidated::try_new_validated() inside RealValidated::ln_1p()",
1493        )
1494    }
1495}
1496
1497impl<K: NumKernel> Hypot for RealValidated<K> {
1498    /// Compute the distance between the origin and a point (`self`, `other`) on the Euclidean plane.
1499    /// Equivalently, compute the length of the hypotenuse of a right-angle triangle with other sides having length `self.abs()` and `other.abs()`.
1500    #[inline(always)]
1501    fn hypot(self, other: &Self) -> Self {
1502        Self::try_new_validated(self.value.unchecked_hypot(&other.value)).expect(
1503            "Error raised by RealValidated::try_new_validated() inside RealValidated::hypot()",
1504        )
1505    }
1506}
1507
1508impl<K: NumKernel> TotalCmp for RealValidated<K> {
1509    #[inline(always)]
1510    fn total_cmp(&self, other: &Self) -> Ordering {
1511        self.value.raw_total_cmp(&other.value)
1512    }
1513}
1514
1515impl<K: NumKernel> RealScalar for RealValidated<K> {
1516    type RawReal = K::RawReal;
1517
1518    /// Multiplies two products and adds them in one fused operation, rounding to the nearest with only one rounding error.
1519    /// `a.kernel_mul_add_mul_mut(&b, &c, &d)` produces a result like `&a * &b + &c * &d`, but stores the result in `a` using its precision.
1520    #[inline(always)]
1521    fn kernel_mul_add_mul_mut(&mut self, mul: &Self, add_mul1: &Self, add_mul2: &Self) {
1522        self.value
1523            .unchecked_mul_add_mul_mut(&mul.value, &add_mul1.value, &add_mul2.value);
1524    }
1525
1526    /// Multiplies two products and subtracts them in one fused operation, rounding to the nearest with only one rounding error.
1527    /// `a.kernel_mul_sub_mul_mut(&b, &c, &d)` produces a result like `&a * &b - &c * &d`, but stores the result in `a` using its precision.
1528    #[inline(always)]
1529    fn kernel_mul_sub_mul_mut(&mut self, mul: &Self, sub_mul1: &Self, sub_mul2: &Self) {
1530        self.value
1531            .unchecked_mul_sub_mul_mut(&mul.value, &sub_mul1.value, &sub_mul2.value);
1532    }
1533
1534    /// Try to build a [`RealValidated`] instance from a [`f64`].
1535    /// The returned value is `Ok` if the input `value` is valid w.r.t. the [`ValidationPolicy`] `V`,
1536    /// otherwise the returned value is `ErrorsTryFromf64`.
1537    ///
1538    /// # Examples
1539    ///
1540    /// ```
1541    /// use num_valid::{RealNative64StrictFinite, RealScalar};
1542    ///
1543    /// // Valid value
1544    /// let x = RealNative64StrictFinite::try_from_f64(3.14).unwrap();
1545    /// assert_eq!(x.as_ref(), &3.14);
1546    ///
1547    /// // Invalid value (NaN)
1548    /// assert!(RealNative64StrictFinite::try_from_f64(f64::NAN).is_err());
1549    /// ```
1550    #[inline(always)]
1551    fn try_from_f64(value: f64) -> Result<Self, ErrorsTryFromf64<K::RawReal>> {
1552        let v_as_raw_real = K::RawReal::try_new_raw_real_from_f64::<K::RealPolicy>(value)?;
1553        Ok(Self {
1554            value: v_as_raw_real,
1555            _phantom: PhantomData,
1556        })
1557    }
1558
1559    /// Build a [`RealValidated`] instance from a [`f64`].
1560    ///
1561    /// This is a convenience method that panics if the value is invalid.
1562    /// Use [`try_from_f64`](Self::try_from_f64) for error handling without panics.
1563    ///
1564    /// # Panics
1565    ///
1566    /// Panics if the input value fails validation (e.g., NaN, infinity, or subnormal for strict policies).
1567    ///
1568    /// # Examples
1569    ///
1570    /// ```
1571    /// use num_valid::{RealNative64StrictFinite, RealScalar};
1572    ///
1573    /// // Valid constant - no need for unwrap()
1574    /// let pi = RealNative64StrictFinite::from_f64(std::f64::consts::PI);
1575    /// assert_eq!(pi.as_ref(), &std::f64::consts::PI);
1576    ///
1577    /// let e = RealNative64StrictFinite::from_f64(std::f64::consts::E);
1578    /// assert_eq!(e.as_ref(), &std::f64::consts::E);
1579    /// ```
1580    ///
1581    /// ```should_panic
1582    /// use num_valid::{RealNative64StrictFinite, RealScalar};
1583    ///
1584    /// // This will panic because NaN is invalid
1585    /// let invalid = RealNative64StrictFinite::from_f64(f64::NAN);
1586    /// ```
1587    #[inline(always)]
1588    fn from_f64(value: f64) -> Self {
1589        Self::try_from_f64(value).expect(
1590            "RealScalar::from_f64() failed: invalid f64 value (NaN, infinity, or subnormal)",
1591        )
1592    }
1593}
1594//------------------------------------------------------------------------------------------------
1595
1596//----------------------------------------------------------------------------------
1597#[duplicate_item(
1598    trait_name T;
1599    duplicate!{[
1600        trait_name_nested; [TrigonometricFunctions]; [HyperbolicFunctions]; [LogarithmFunctions];
1601        ]
1602        [trait_name_nested] [RealValidated<K>];
1603        [trait_name_nested] [ComplexValidated<K>];
1604    }
1605)]
1606impl<K: NumKernel> trait_name for T {}
1607//----------------------------------------------------------------------------------
1608
1609//------------------------------------------------------------------------------------------------
1610impl<K: NumKernel> FpScalar for RealValidated<K> {
1611    type Kind = scalar_kind::Real;
1612    type RealType = RealValidated<K>;
1613
1614    /// Returns a reference to the underlying raw real value.
1615    fn as_raw_ref(&self) -> &Self::InnerType {
1616        &self.value
1617    }
1618}
1619
1620impl<K: NumKernel> FpScalar for ComplexValidated<K> {
1621    type Kind = scalar_kind::Complex;
1622    type RealType = RealValidated<K>;
1623
1624    /// Returns a reference to the underlying raw complex value.
1625    fn as_raw_ref(&self) -> &Self::InnerType {
1626        &self.value
1627    }
1628}
1629//------------------------------------------------------------------------------------------------
1630
1631//------------------------------------------------------------------------------------------------
1632impl<K: NumKernel> ComplexScalar for ComplexValidated<K> {
1633    fn into_parts(self) -> (Self::RealType, Self::RealType) {
1634        let real_part = self.value.raw_real_part().clone();
1635        let imag_part = self.value.raw_imag_part().clone();
1636        (RealValidated::new(real_part), RealValidated::new(imag_part))
1637    }
1638}
1639//------------------------------------------------------------------------------------------------
1640
1641//----------------------------------------------------------------------------------
1642/// Implement the [`Distribution`] trait for [`RealValidated`] type
1643/// using the `StandardUniform` distribution.
1644impl<K: NumKernel> Distribution<RealValidated<K>> for StandardUniform {
1645    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> RealValidated<K> {
1646        RealValidated::try_from_f64(rng.random::<f64>())
1647            .expect("Error raised by RealValidated::try_from_f64() inside Distribution::sample()")
1648    }
1649}
1650
1651/// Implement the [`Distribution`] trait for [`ComplexValidated`] type
1652/// using the `StandardUniform` distribution.
1653impl<K: NumKernel> Distribution<ComplexValidated<K>> for StandardUniform {
1654    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ComplexValidated<K> {
1655        let real_part = rng.random::<RealValidated<K>>();
1656        let imag_part = rng.random::<RealValidated<K>>();
1657        ComplexValidated::<K>::new_complex(real_part, imag_part)
1658    }
1659}
1660//----------------------------------------------------------------------------------
1661
1662//----------------------------------------------------------------------------------
1663// Conditional Copy implementations for validated types.
1664//
1665// These implementations are only available when the underlying raw type
1666// (`K::RawReal` for real, `K::RawComplex` for complex) implements `Copy`.
1667// This enables zero-cost pass-by-value semantics for types like
1668// `RealNative64StrictFinite` (backed by `f64`) and `ComplexNative64StrictFinite`
1669// (backed by `Complex<f64>`) while correctly requiring `Clone` for non-`Copy`
1670// types like `rug::Float` and `rug::Complex`.
1671//
1672// # Example
1673//
1674// ```rust
1675// use num_valid::RealNative64StrictFinite;
1676// use try_create::TryNew;
1677//
1678// let x = RealNative64StrictFinite::try_new(3.14).unwrap();
1679// let y = x; // Copy, not move!
1680// let z = x; // x is still valid because it was copied
1681// assert_eq!(x, y);
1682// assert_eq!(x, z);
1683// ```
1684impl<K: NumKernel> Copy for RealValidated<K> where K::RawReal: Copy {}
1685impl<K: NumKernel> Copy for ComplexValidated<K> where K::RawComplex: Copy {}
1686//----------------------------------------------------------------------------------
1687
1688#[duplicate_item(
1689    T;
1690    [RealNative64StrictFinite];
1691    [RealNative64StrictFiniteInDebug];
1692)]
1693unsafe impl CheckedBitPattern for T {
1694    type Bits = u64;
1695
1696    fn is_valid_bit_pattern(bits: &Self::Bits) -> bool {
1697        let value = f64::from_bits(*bits);
1698        <Self as TryNewValidated>::Policy::validate_ref(&value).is_ok()
1699    }
1700}
1701
1702#[duplicate_item(
1703    T;
1704    [RealNative64StrictFinite];
1705    [RealNative64StrictFiniteInDebug];
1706)]
1707unsafe impl bytemuck::NoUninit for T {}
1708//----------------------------------------------------------------------------------