conflux/core/math/
norm_ndarray.rs1use crate::core::math::FPNorm;
2use ndarray::Array1;
3use num::integer::Roots;
4use num_complex::Complex;
5
6macro_rules! make_norm_float {
7 ($t:ty) => {
8 impl FPNorm<$t> for Array1<$t> {
9 #[inline]
10 fn norm(&self) -> $t {
11 self.iter().map(|x| x.powi(2)).sum::<$t>().sqrt()
12 }
13 }
14 };
15}
16
17macro_rules! make_norm_complex_float {
18 ($t:ty) => {
19 impl FPNorm<Complex<$t>> for Array1<Complex<$t>> {
20 #[inline]
21 fn norm(&self) -> Complex<$t> {
22 self.iter().map(|a| a.powf(2.0)).sum::<Complex<$t>>().sqrt()
23 }
24 }
25
26 impl FPNorm<$t> for Array1<Complex<$t>> {
27 #[inline]
28 fn norm(&self) -> $t {
29 self.iter()
30 .map(|a| a.powf(2.0))
31 .sum::<Complex<$t>>()
32 .sqrt()
33 .norm()
34 }
35 }
36 };
37}
38
39macro_rules! make_norm_integer {
40 ($t:ty) => {
41 impl FPNorm<$t> for Array1<$t> {
42 #[inline]
43 fn norm(&self) -> $t {
44 self.iter().map(|a| a.pow(2)).sum::<$t>().sqrt()
45 }
46 }
47 };
48}
49
50make_norm_integer!(isize);
51make_norm_integer!(usize);
52make_norm_integer!(i8);
53make_norm_integer!(i16);
54make_norm_integer!(i32);
55make_norm_integer!(i64);
56make_norm_integer!(u8);
57make_norm_integer!(u16);
58make_norm_integer!(u32);
59make_norm_integer!(u64);
60make_norm_float!(f32);
61make_norm_float!(f64);
62make_norm_complex_float!(f32);
63make_norm_complex_float!(f64);
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use ndarray::{array, Array1};
69 use paste::item;
70
71 macro_rules! make_test {
72 ($t:ty) => {
73 item! {
74 #[test]
75 fn [<test_norm_ $t>]() {
76 let a = array![4 as $t, 3 as $t];
77 let res = <Array1<$t> as FPNorm<$t>>::norm(&a);
78 let target = 5 as $t;
79 assert!(((target - res) as f64).abs() < std::f64::EPSILON);
80 }
81 }
82 };
83 }
84
85 macro_rules! make_test_signed {
86 ($t:ty) => {
87 item! {
88 #[test]
89 fn [<test_norm_signed_ $t>]() {
90 let a = array![-4 as $t, -3 as $t];
91 let res = <Array1<$t> as FPNorm<$t>>::norm(&a);
92 let target = 5 as $t;
93 assert!(((target - res) as f64).abs() < std::f64::EPSILON);
94 }
95 }
96 };
97 }
98
99 make_test!(isize);
100 make_test!(usize);
101 make_test!(i8);
102 make_test!(u8);
103 make_test!(i16);
104 make_test!(u16);
105 make_test!(i32);
106 make_test!(u32);
107 make_test!(i64);
108 make_test!(u64);
109 make_test!(f32);
110 make_test!(f64);
111
112 make_test_signed!(isize);
113 make_test_signed!(i8);
114 make_test_signed!(i16);
115 make_test_signed!(i32);
116 make_test_signed!(i64);
117 make_test_signed!(f32);
118 make_test_signed!(f64);
119}