rsdiff_core/ops/kinds/unary/
specs.rs

1/*
2    Appellation: specs <unary>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use core::ops::Neg;
6use num::Complex;
7use num::traits::{Inv, Num};
8
9pub struct Logistical;
10
11///
12pub trait Conjugate {
13    type Complex;
14    type Real;
15
16    fn conj(&self) -> Self::Complex;
17}
18
19macro_rules! impl_conj {
20    ($t:ty) => {
21        impl Conjugate for $t {
22            type Complex = Complex<Self>;
23            type Real = Self;
24
25            fn conj(&self) -> Self::Complex {
26                Complex::new(*self, <$t>::default())
27            }
28        }
29    };
30    ($($t:ty),*) => {
31        $(
32            impl_conj!($t);
33        )*
34    };
35}
36
37impl<T> Conjugate for Complex<T>
38where
39    T: Clone + Neg<Output = T> + Num,
40{
41    type Complex = Self;
42    type Real = T;
43
44    fn conj(&self) -> Self::Complex {
45        Complex::conj(self)
46    }
47}
48
49impl_conj!(i8, i16, i32, i64, i128, isize);
50impl_conj!(f32, f64);
51
52macro_rules! unary_op_trait {
53    ($(($trait:ident, $method:ident)),*) => {
54        $(unary_op_trait!($trait, $method);)*
55    };
56    ($trait:ident, $method:ident) => {
57        pub trait $trait {
58            type Output;
59
60            fn $method(self) -> Self::Output;
61        }
62    };
63    (owned $trait:ident, $method:ident) => {
64        pub trait $trait {
65            type Output;
66
67            fn $method(&self) -> Self::Output;
68        }
69    };
70}
71
72macro_rules! impl_unary_op {
73    ($trait:ident, $method:ident, $t:ty) => {
74        impl $trait for $t {
75            type Output = $t;
76
77            fn $method(self) -> Self::Output {
78                <$t>::$method(self)
79            }
80        }
81    };
82    (generic $trait:ident, $method:ident, s => $s:tt, t => $t:tt) => {
83        impl<S, T> $trait for S where S: $s, T: $t {
84            type Output = T;
85
86            fn $method(self) -> Self::Output {
87                <$t>::$method(self)
88            }
89        }
90    };
91    ($trait:ident, $method:ident; [$($t:ty),*]) => {
92        $(
93            impl_unary_op!($trait, $method, $t);
94        )*
95    };
96    ($trait:ident, $method:ident, $call:ident; $t:ty) => {
97        impl $trait for $t {
98            type Output = $t;
99
100            fn $method(self) -> Self::Output {
101                <$t>::$call(self)
102            }
103        }
104    };
105    (alts $trait:ident, $method:ident, $call:ident; [$($t:ty),*]) => {
106        $(
107            impl_unary_op!($trait, $method, $call; $t);
108        )*
109    };
110}
111
112unary_op_trait!(
113    (Abs, abs),
114    (Cubed, cbd),
115    (CubeRoot, cbrt),
116    (Exp, exp),
117    (Ln, ln),
118    (Recip, recip),
119    (SquareRoot, sqrt),
120    (Square, sqr)
121);
122unary_op_trait!(
123    (Acos, acos),
124    (Acosh, acosh),
125    (Asin, asin),
126    (Asinh, asinh),
127    (Atan, atan),
128    (Atanh, atanh),
129    (Cos, cos),
130    (Cosh, cosh),
131    (Sin, sin),
132    (Sinh, sinh),
133    (Tan, tan),
134    (Tanh, tanh)
135);
136unary_op_trait!((Sigmoid, sigmoid));
137
138impl<T> Abs for Complex<T>
139where
140    T: num::Float,
141{
142    type Output = T;
143
144    fn abs(self) -> Self::Output {
145        self.norm()
146    }
147}
148
149impl<T> Recip for T
150where
151    T: Inv,
152{
153    type Output = <T as Inv>::Output;
154
155    fn recip(self) -> Self::Output {
156        self.inv()
157    }
158}
159
160impl<T> Square for T
161where
162    T: Copy + std::ops::Mul<Self, Output = Self>,
163{
164    type Output = T;
165
166    fn sqr(self) -> Self::Output {
167        self * self
168    }
169}
170
171impl_unary_op!(Abs, abs; [isize, i8, i16, i32, i64, i128, f32, f64]);
172impl_unary_op!(Cos, cos; [f64, f32, Complex<f64>, Complex<f32>]);
173impl_unary_op!(Cosh, cosh; [f64, f32, Complex<f64>, Complex<f32>]);
174impl_unary_op!(Exp, exp; [f64, f32, Complex<f64>, Complex<f32>]);
175impl_unary_op!(Ln, ln; [f64, f32, Complex<f64>, Complex<f32>]);
176impl_unary_op!(Sin, sin; [f64, f32, Complex<f64>, Complex<f32>]);
177impl_unary_op!(Sinh, sinh; [f64, f32, Complex<f64>, Complex<f32>]);
178impl_unary_op!(SquareRoot, sqrt; [f64, f32, Complex<f64>, Complex<f32>]);
179impl_unary_op!(Tan, tan; [f64, f32, Complex<f64>, Complex<f32>]);
180impl_unary_op!(Tanh, tanh; [f64, f32, Complex<f64>, Complex<f32>]);