Skip to main content

num_valid/functions/
neg_assign.rs

1#![deny(rustdoc::broken_intra_doc_links)]
2
3//! In-place negation operations.
4//!
5//! This module provides the [`NegAssign`] trait for negating a value in place,
6//! which is more efficient than creating a new negated value for heap-allocated types.
7
8use crate::core::traits::validation::sealed;
9use num::Complex;
10
11//-------------------------------------------------------------
12/// Compound negation and assignment.
13pub trait NegAssign {
14    /// Performs the negation.
15    fn neg_assign(&mut self);
16}
17
18impl<T: sealed::NativeReal> NegAssign for T {
19    /// Performs the negation of `self`.
20    fn neg_assign(&mut self) {
21        *self = -*self;
22    }
23}
24
25impl<T: sealed::NativeReal> NegAssign for Complex<T> {
26    /// Performs the negation of `self`.
27    fn neg_assign(&mut self) {
28        *self = -*self;
29    }
30}
31
32//-------------------------------------------------------------
33
34//-------------------------------------------------------------
35#[cfg(test)]
36mod tests {
37    use super::*;
38    use num::Complex;
39
40    mod native {
41        use super::*;
42
43        #[test]
44        fn test_neg_assign_f64() {
45            let mut value = 1.0_f64;
46            value.neg_assign();
47            let expected_value = -1.0_f64;
48            assert_eq!(value, expected_value);
49
50            let mut value = -2.0_f64;
51            value.neg_assign();
52            let expected_value = 2.0_f64;
53            assert_eq!(value, expected_value);
54        }
55
56        #[test]
57        fn test_neg_assign_complex_f64() {
58            let mut value = Complex::new(1.0, -2.0);
59            value.neg_assign();
60            let expected_value = Complex::new(-1.0, 2.0);
61            assert_eq!(value, expected_value);
62
63            let mut value = Complex::new(-3.0, 4.0);
64            value.neg_assign();
65            let expected_value = Complex::new(3.0, -4.0);
66            assert_eq!(value, expected_value);
67        }
68    }
69
70    #[cfg(feature = "rug")]
71    mod rug53 {
72        use super::*;
73        use crate::backends::rug::validated::{ComplexRugStrictFinite, RealRugStrictFinite};
74        use rug::Float;
75        use try_create::TryNew;
76
77        const PRECISION: u32 = 53;
78
79        #[test]
80        fn test_neg_assign_real_rug() {
81            let mut value =
82                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, 1.0)).unwrap();
83            value.neg_assign();
84            let expected_value =
85                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, -1.0))
86                    .unwrap();
87            assert_eq!(value, expected_value);
88
89            let mut value =
90                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, -2.0))
91                    .unwrap();
92            value.neg_assign();
93            let expected_value =
94                RealRugStrictFinite::<PRECISION>::try_new(Float::with_val(PRECISION, 2.0)).unwrap();
95            assert_eq!(value, expected_value);
96        }
97
98        #[test]
99        fn test_neg_assign_complex_rug() {
100            let mut value = ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
101                PRECISION,
102                (
103                    Float::with_val(PRECISION, 1.0),
104                    Float::with_val(PRECISION, -2.0),
105                ),
106            ))
107            .unwrap();
108            value.neg_assign();
109            let expected_value =
110                ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
111                    PRECISION,
112                    (
113                        Float::with_val(PRECISION, -1.0),
114                        Float::with_val(PRECISION, 2.0),
115                    ),
116                ))
117                .unwrap();
118            assert_eq!(value, expected_value);
119
120            let mut value = ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
121                PRECISION,
122                (
123                    Float::with_val(PRECISION, -3.0),
124                    Float::with_val(PRECISION, 4.0),
125                ),
126            ))
127            .unwrap();
128            value.neg_assign();
129            let expected_value =
130                ComplexRugStrictFinite::<PRECISION>::try_new(rug::Complex::with_val(
131                    PRECISION,
132                    (
133                        Float::with_val(PRECISION, 3.0),
134                        Float::with_val(PRECISION, -4.0),
135                    ),
136                ))
137                .unwrap();
138            assert_eq!(value, expected_value);
139        }
140    }
141}
142//-------------------------------------------------------------