1
- use super :: interpolation:: Linear ;
2
1
use super :: { InterpolationMethod , SignalAbs } ;
3
2
use crate :: signals:: Signal ;
4
3
5
- impl < T > core:: ops:: Neg for Signal < T >
6
- where
7
- T : core:: ops:: Neg < Output = T > ,
8
- {
9
- type Output = Signal < T > ;
10
-
11
- fn neg ( self ) -> Self :: Output {
12
- use Signal :: * ;
13
- match self {
14
- Empty => Signal :: Empty ,
15
- Constant { value } => Signal :: constant ( value. neg ( ) ) ,
16
- Sampled { values, time_points } => time_points. into_iter ( ) . zip ( values. into_iter ( ) . map ( |v| -v) ) . collect ( ) ,
17
- }
18
- }
19
- }
20
-
21
- impl < T > core:: ops:: Neg for & Signal < T >
22
- where
23
- for < ' a > & ' a T : core:: ops:: Neg < Output = T > ,
24
- {
25
- type Output = Signal < T > ;
26
-
27
- fn neg ( self ) -> Self :: Output {
28
- use Signal :: * ;
29
- match self {
30
- Empty => Signal :: Empty ,
31
- Constant { value } => Signal :: constant ( value. neg ( ) ) ,
32
- Sampled { values, time_points } => time_points
33
- . iter ( )
34
- . copied ( )
35
- . zip ( values. iter ( ) . map ( |v| v. neg ( ) ) )
36
- . collect ( ) ,
37
- }
38
- }
39
- }
40
-
41
- impl < T > core:: ops:: Add < & Signal < T > > for Signal < T >
42
- where
43
- T : Clone ,
44
- for < ' a , ' b > & ' a T : core:: ops:: Add < & ' b T , Output = T > ,
45
- Linear : InterpolationMethod < T > ,
46
- {
47
- type Output = Signal < T > ;
48
-
49
- /// Add the given signal with another
50
- fn add ( self , other : & Signal < T > ) -> Signal < T > {
51
- self . binary_op :: < _ , _ , Linear > ( other, |lhs, rhs| lhs + rhs)
52
- }
53
- }
54
-
55
- impl < T > core:: ops:: Add < & Signal < T > > for & Signal < T >
56
- where
57
- T : Clone ,
58
- for < ' a , ' b > & ' a T : core:: ops:: Add < & ' b T , Output = T > ,
59
- Linear : InterpolationMethod < T > ,
60
- {
61
- type Output = Signal < T > ;
62
-
63
- /// Add the given signal with another
64
- fn add ( self , other : & Signal < T > ) -> Signal < T > {
65
- self . binary_op :: < _ , _ , Linear > ( other, |lhs, rhs| lhs + rhs)
66
- }
67
- }
68
-
69
- impl < T > core:: ops:: Mul < & Signal < T > > for Signal < T >
70
- where
71
- for < ' a , ' b > & ' a T : core:: ops:: Mul < & ' b T , Output = T > ,
72
- T : Clone ,
73
- Linear : InterpolationMethod < T > ,
74
- {
75
- type Output = Signal < T > ;
76
-
77
- /// Multiply the given signal with another
78
- fn mul ( self , rhs : & Signal < T > ) -> Signal < T > {
79
- self . binary_op :: < _ , _ , Linear > ( rhs, |lhs, rhs| lhs * rhs)
4
+ impl < T > Signal < T > {
5
+ /// Perform sample-wise arithmetic negation over the signal.
6
+ pub fn negate < U > ( & self ) -> Signal < U >
7
+ where
8
+ for < ' a > & ' a T : core:: ops:: Neg < Output = U > ,
9
+ {
10
+ self . unary_op ( |v| -v)
80
11
}
81
- }
82
12
83
- impl < T > core :: ops :: Mul < & Signal < T > > for & Signal < T >
84
- where
85
- for < ' a , ' b > & ' a T : core :: ops :: Mul < & ' b T , Output = T > ,
86
- T : Clone ,
87
- Linear : InterpolationMethod < T > ,
88
- {
89
- type Output = Signal < T > ;
90
-
91
- /// Multiply the given signal with another
92
- fn mul ( self , rhs : & Signal < T > ) -> Signal < T > {
93
- self . binary_op :: < _ , _ , Linear > ( rhs , |lhs , rhs| lhs * rhs )
13
+ /// Perform sample-wise addition of the two signals.
14
+ ///
15
+ /// Here, a new point is computed for all signal points where either of the signals
16
+ /// are sampled and where they intersect (using interpolation).
17
+ pub fn add < U , I > ( & self , other : & Signal < T > ) -> Signal < U >
18
+ where
19
+ for < ' t > & ' t T : core :: ops :: Add < Output = U > ,
20
+ T : Clone ,
21
+ I : InterpolationMethod < T > ,
22
+ {
23
+ self . binary_op :: < _ , _ , I > ( other , |u , v| u + v )
94
24
}
95
- }
96
25
97
- impl < T > core:: ops:: Sub < & Signal < T > > for & Signal < T >
98
- where
99
- for < ' a , ' b > & ' a T : core:: ops:: Sub < & ' b T , Output = T > ,
100
- T : Clone + PartialOrd ,
101
- Linear : InterpolationMethod < T > ,
102
- {
103
- type Output = Signal < T > ;
104
-
105
- /// Subtract the given signal with another
106
- fn sub ( self , other : & Signal < T > ) -> Signal < T > {
107
- // This has to be manually implemented and cannot use the binary_op functions.
108
- // This is because if we have two signals that cross each other, then there is
109
- // an intermediate point where the two signals are equal. This point must be
110
- // added to the signal appropriately.
111
- use Signal :: * ;
112
- match ( self , other) {
113
- // If either of the signals are empty, we return an empty signal.
114
- ( Empty , _) | ( _, Empty ) => Signal :: Empty ,
115
- ( Constant { value : v1 } , Constant { value : v2 } ) => Signal :: constant ( v1 - v2) ,
116
- ( lhs, rhs) => {
117
- // the union of the sample points in self and other
118
- let sync_points = lhs. sync_with_intersection :: < Linear > ( rhs) . unwrap ( ) ;
119
- sync_points
120
- . into_iter ( )
121
- . map ( |t| {
122
- let lhs = lhs. interpolate_at :: < Linear > ( t) . unwrap ( ) ;
123
- let rhs = rhs. interpolate_at :: < Linear > ( t) . unwrap ( ) ;
124
- ( t, & lhs - & rhs)
125
- } )
126
- . collect ( )
127
- }
128
- }
26
+ /// Perform sample-wise multiplication of the two signals.
27
+ ///
28
+ /// Here, a new point is computed for all signal points where either of the signals
29
+ /// are sampled and where they intersect (using interpolation).
30
+ pub fn mul < U , I > ( & self , other : & Signal < T > ) -> Signal < U >
31
+ where
32
+ for < ' t > & ' t T : core:: ops:: Mul < Output = U > ,
33
+ T : Clone ,
34
+ I : InterpolationMethod < T > ,
35
+ {
36
+ self . binary_op :: < _ , _ , I > ( other, |u, v| u * v)
129
37
}
130
- }
131
38
132
- impl < T > core :: ops :: Sub < & Signal < T > > for Signal < T >
133
- where
134
- for < ' a , ' b > & ' a T : core :: ops :: Sub < & ' b T , Output = T > ,
135
- T : Clone + PartialOrd ,
136
- Linear : InterpolationMethod < T > ,
137
- {
138
- type Output = Signal < T > ;
139
-
140
- /// Subtract the given signal with another
141
- fn sub ( self , other : & Signal < T > ) -> Signal < T > {
142
- < & Self as core :: ops :: Sub > :: sub ( & self , other )
39
+ /// Perform sample-wise subtraction of the two signals.
40
+ ///
41
+ /// Here, a new point is computed for all signal points where either of the signals
42
+ /// are sampled and where they intersect (using interpolation).
43
+ pub fn sub < U , I > ( & self , other : & Signal < T > ) -> Signal < U >
44
+ where
45
+ for < ' t > & ' t T : core :: ops :: Sub < Output = U > ,
46
+ T : Clone ,
47
+ I : InterpolationMethod < T > ,
48
+ {
49
+ self . binary_op :: < _ , _ , I > ( other , |u , v| u - v )
143
50
}
144
- }
145
51
146
- impl < T > core :: ops :: Div < & Signal < T > > for Signal < T >
147
- where
148
- for < ' a , ' b > & ' a T : core :: ops :: Div < & ' b T , Output = T > ,
149
- T : Clone ,
150
- Linear : InterpolationMethod < T > ,
151
- {
152
- type Output = Signal < T > ;
153
-
154
- /// Divide the given signal with another
155
- fn div ( self , rhs : & Signal < T > ) -> Self {
156
- self . binary_op :: < _ , _ , Linear > ( rhs , |lhs , rhs| lhs / rhs )
52
+ /// Perform sample-wise division of the two signals.
53
+ ///
54
+ /// Here, a new point is computed for all signal points where either of the signals
55
+ /// are sampled and where they intersect (using interpolation).
56
+ pub fn div < U , I > ( & self , other : & Signal < T > ) -> Signal < U >
57
+ where
58
+ for < ' t > & ' t T : core :: ops :: Div < Output = U > ,
59
+ T : Clone ,
60
+ I : InterpolationMethod < T > ,
61
+ {
62
+ self . binary_op :: < _ , _ , I > ( other , |u , v| u / v )
157
63
}
158
- }
159
64
160
- impl < T > core:: ops:: Div < & Signal < T > > for & Signal < T >
161
- where
162
- for < ' a , ' b > & ' a T : core:: ops:: Div < & ' b T , Output = T > ,
163
- T : Clone ,
164
- Linear : InterpolationMethod < T > ,
165
- {
166
- type Output = Signal < T > ;
167
-
168
- /// Divide the given signal with another
169
- fn div ( self , rhs : & Signal < T > ) -> Signal < T > {
170
- self . binary_op :: < _ , _ , Linear > ( rhs, |lhs, rhs| lhs / rhs)
65
+ /// Perform sample-wise exponentiation of the two signals.
66
+ ///
67
+ /// Here, a new point is computed for all signal points where either of the signals
68
+ /// are sampled and where they intersect (using interpolation).
69
+ pub fn pow < U , I > ( & self , exponent : & Signal < T > ) -> Signal < U >
70
+ where
71
+ for < ' a , ' b > & ' a T : num_traits:: Pow < & ' b T , Output = U > ,
72
+ T : Clone ,
73
+ I : InterpolationMethod < T > ,
74
+ {
75
+ use num_traits:: Pow ;
76
+ self . binary_op :: < _ , _ , I > ( exponent, |u, v| u. pow ( v) )
171
77
}
172
- }
173
78
174
- impl < T > Signal < T >
175
- where
176
- for < ' a , ' b > & ' a T : num_traits:: Pow < & ' b T , Output = T > ,
177
- T : Clone ,
178
- Linear : InterpolationMethod < T > ,
179
- {
180
- /// Returns the values in `self` to the power of the values in `other`
181
- pub fn pow ( & self , other : & Self ) -> Self {
182
- use num_traits:: Pow ;
183
- self . binary_op :: < _ , _ , Linear > ( other, |lhs, rhs| lhs. pow ( rhs) )
79
+ /// Perform sample-wise absolute difference of the two signals.
80
+ ///
81
+ /// Here, a new point is computed for all signal points where either of the signals
82
+ /// are sampled and where they intersect (using interpolation).
83
+ pub fn abs_diff < U , I > ( & self , other : & Signal < T > ) -> Signal < U >
84
+ where
85
+ for < ' t > & ' t T : core:: ops:: Sub < Output = U > ,
86
+ T : Clone + PartialOrd ,
87
+ I : InterpolationMethod < T > ,
88
+ {
89
+ self . binary_op :: < _ , _ , I > ( other, |u, v| if u < v { v - u } else { u - v } )
184
90
}
185
91
}
186
92
@@ -202,6 +108,6 @@ signal_abs_impl!(i64, f32, f64);
202
108
impl SignalAbs for Signal < u64 > {
203
109
/// Return the absolute value for each sample in the signal
204
110
fn abs ( self ) -> Signal < u64 > {
205
- self . unary_op ( |v| v)
111
+ self . unary_op ( |& v| v)
206
112
}
207
113
}
0 commit comments