argmin_math/primitives/
zero.rs

1// Copyright 2018-2024 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::{ArgminZero, ArgminZeroLike};
9use num_complex::Complex;
10
11macro_rules! make_zero {
12    ($t:ty) => {
13        impl ArgminZero for $t {
14            #[allow(clippy::cast_lossless)]
15            #[inline]
16            fn zero() -> $t {
17                0 as $t
18            }
19        }
20        impl ArgminZeroLike for $t {
21            #[allow(clippy::cast_lossless)]
22            #[inline]
23            fn zero_like(&self) -> $t {
24                0 as $t
25            }
26        }
27    };
28}
29
30macro_rules! make_complex_zero {
31    ($t:ty) => {
32        impl ArgminZero for Complex<$t> {
33            #[allow(clippy::cast_lossless)]
34            #[inline]
35            fn zero() -> Complex<$t> {
36                Complex::new(0 as $t, 0 as $t)
37            }
38        }
39        impl ArgminZeroLike for Complex<$t> {
40            #[allow(clippy::cast_lossless)]
41            #[inline]
42            fn zero_like(&self) -> Complex<$t> {
43                Complex::new(0 as $t, 0 as $t)
44            }
45        }
46    };
47}
48
49make_zero!(f32);
50make_zero!(f64);
51make_zero!(i8);
52make_zero!(i16);
53make_zero!(i32);
54make_zero!(i64);
55make_zero!(u8);
56make_zero!(u16);
57make_zero!(u32);
58make_zero!(u64);
59make_complex_zero!(f32);
60make_complex_zero!(f64);
61make_complex_zero!(i8);
62make_complex_zero!(i16);
63make_complex_zero!(i32);
64make_complex_zero!(i64);
65make_complex_zero!(u8);
66make_complex_zero!(u16);
67make_complex_zero!(u32);
68make_complex_zero!(u64);
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use approx::assert_relative_eq;
74    use paste::item;
75
76    macro_rules! make_test {
77        ($t:ty) => {
78            item! {
79                #[test]
80                fn [<test_zero_ $t>]() {
81                    let a = <$t as ArgminZero>::zero();
82                    assert_relative_eq!(0 as f64, a as f64, epsilon = f64::EPSILON);
83                }
84            }
85
86            item! {
87                #[test]
88                fn [<test_zero_complex_ $t>]() {
89                    let a = <Complex<$t> as ArgminZero>::zero();
90                    assert_relative_eq!(0 as f64, a.re as f64, epsilon = f64::EPSILON);
91                    assert_relative_eq!(0 as f64, a.im as f64, epsilon = f64::EPSILON);
92                }
93            }
94
95            item! {
96                #[test]
97                fn [<test_zero_like_ $t>]() {
98                    let a = (42 as $t).zero_like();
99                    assert_relative_eq!(0 as f64, a as f64, epsilon = f64::EPSILON);
100                }
101            }
102
103            item! {
104                #[test]
105                fn [<test_zero_like_complex_ $t>]() {
106                    let a = Complex::new(42 as $t, 12 as $t).zero_like();
107                    assert_relative_eq!(0 as f64, a.re as f64, epsilon = f64::EPSILON);
108                    assert_relative_eq!(0 as f64, a.im as f64, epsilon = f64::EPSILON);
109                }
110            }
111        };
112    }
113
114    make_test!(i8);
115    make_test!(u8);
116    make_test!(i16);
117    make_test!(u16);
118    make_test!(i32);
119    make_test!(u32);
120    make_test!(i64);
121    make_test!(u64);
122    make_test!(f32);
123    make_test!(f64);
124}