rsdiff_core/ops/kinds/unary/
specs.rs1use core::ops::Neg;
6use num::Complex;
7use num::traits::{Inv, Num};
8
9pub struct Logistical;
10
11pub 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>]);