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