1
+ use ndarray:: Array2 ;
2
+ use num:: { complex:: ComplexFloat , NumCast , One } ;
3
+ use option_trait:: { Maybe , StaticMaybe } ;
4
+
5
+ use crate :: { quantities:: { ContainerOrSingle , List , ListOrSingle , Lists , Matrix , MatrixOrSingle , MaybeList , MaybeLists , MaybeOwnedList , OwnedList , OwnedListOrSingle } , systems:: { Sos , Ss , SsAMatrix , SsBMatrix , SsCMatrix , SsDMatrix , Tf , Zpk } , transforms:: system:: ToSs , util:: TwoSidedRange , System } ;
6
+
7
+ use super :: SimS ;
8
+
9
+ pub trait StepS < L > : System
10
+ where
11
+ L : List < <Self :: Set as ComplexFloat >:: Real > ,
12
+ <L :: Length as StaticMaybe < usize > >:: Opposite : Sized
13
+ {
14
+ type OutputI : Lists < Self :: Set > + ListOrSingle < L :: Mapped < Self :: Set > > ;
15
+ type Output : MatrixOrSingle < L :: Mapped < Self :: Set > > ;
16
+
17
+ fn step_s < T , W > ( self , t : T , numtaps : <L :: Length as StaticMaybe < usize > >:: Opposite , w : W )
18
+ -> ( L , Self :: Output )
19
+ where
20
+ T : TwoSidedRange < <Self :: Set as ComplexFloat >:: Real > + Clone ,
21
+ W : Maybe < Vec < Self :: Set > > ;
22
+ }
23
+
24
+ impl < T , A , B , C , D , L , YY > StepS < L > for Ss < T , A , B , C , D >
25
+ where
26
+ T : ComplexFloat ,
27
+ A : SsAMatrix < T , B , C , D > ,
28
+ B : SsBMatrix < T , A , C , D > ,
29
+ C : SsCMatrix < T , A , B , D > ,
30
+ D : for < ' a > SsDMatrix < T , A , B , C , RowView < ' a > : List < T > > ,
31
+ L : OwnedList < T :: Real , Mapped < T > = YY > ,
32
+ <L :: Length as StaticMaybe < usize > >:: Opposite : Sized + Clone ,
33
+ D :: RowsMapped < YY > : Lists < T > ,
34
+ YY : OwnedList < T , Length = L :: Length > + Clone ,
35
+ L :: Mapped < Vec < T > > : OwnedList < Vec < T > , Length : StaticMaybe < usize , Opposite : Sized > > ,
36
+ for < ' a > Ss < T , A :: View < ' a > , B :: View < ' a > , C :: View < ' a > , D :: View < ' a > > : System < Set = T > + SimS < T , Array2 < T > , Output = D :: RowsMapped < Vec < T > > > ,
37
+ for < ' a > A :: View < ' a > : SsAMatrix < T , B :: View < ' a > , C :: View < ' a > , D :: View < ' a > > ,
38
+ for < ' a > B :: View < ' a > : SsBMatrix < T , A :: View < ' a > , C :: View < ' a > , D :: View < ' a > > ,
39
+ for < ' a > C :: View < ' a > : SsCMatrix < T , A :: View < ' a > , B :: View < ' a > , D :: View < ' a > > ,
40
+ for < ' a > D :: View < ' a > : SsDMatrix < T , A :: View < ' a > , B :: View < ' a > , C :: View < ' a > > ,
41
+ D :: RowsMapped < Vec < T > > : ListOrSingle < Vec < T > , Mapped < YY > : Into < D :: RowsMapped < YY > > > ,
42
+ <D :: Transpose as MaybeLists < T > >:: RowsMapped < D :: RowsMapped < YY > > : OwnedListOrSingle < D :: RowsMapped < YY > , Length : StaticMaybe < usize , Opposite : Sized > > + Lists < YY > ,
43
+ <<D :: Transpose as MaybeLists < T > >:: RowsMapped < D :: RowsMapped < YY > > as Lists < YY > >:: CoercedMatrix : Matrix < YY >
44
+ {
45
+ type OutputI = D :: RowsMapped < YY > ;
46
+ type Output = <<D :: Transpose as MaybeLists < T > >:: RowsMapped < Self :: OutputI > as Lists < YY > >:: CoercedMatrix ;
47
+
48
+ fn step_s < TT , W > ( self , t : TT , numtaps : <L :: Length as StaticMaybe < usize > >:: Opposite , w : W )
49
+ -> ( L , Self :: Output )
50
+ where
51
+ TT : TwoSidedRange < T :: Real > + Clone ,
52
+ W : Maybe < Vec < T > >
53
+ {
54
+ let w = w. into_option ( ) ;
55
+
56
+ let n = numtaps. into_option ( )
57
+ . unwrap_or ( L :: LENGTH ) ;
58
+ let nuf = <T :: Real as NumCast >:: from ( n) . unwrap ( ) ;
59
+ let numaybem1 = if t. is_end_inclusive ( )
60
+ {
61
+ nuf - T :: Real :: one ( )
62
+ }
63
+ else
64
+ {
65
+ nuf
66
+ } ;
67
+
68
+ let dt = ( * t. end ( ) - * t. start ( ) ) /numaybem1;
69
+
70
+ let tt = OwnedListOrSingle :: from_len_fn ( StaticMaybe :: maybe_from_fn ( || n) , |i| {
71
+ let i = <T :: Real as NumCast >:: from ( i) . unwrap ( ) ;
72
+ * t. start ( ) + i* dt
73
+ } ) ;
74
+
75
+ let dn = self . d . matrix_dim ( ) . 1 . max ( self . b . matrix_dim ( ) . 1 ) ;
76
+ let y = <D :: Transpose as MaybeLists < T > >:: RowsMapped :: < Self :: OutputI > :: from_len_fn ( StaticMaybe :: maybe_from_fn ( || dn) , |i| {
77
+ let ( _, y, _) = self . as_view ( )
78
+ . sim_s (
79
+ t. clone ( ) ,
80
+ Array2 :: from_shape_fn ( ( dn, n) , |( k, _) | if i == k { T :: one ( ) } else { T :: zero ( ) } ) ,
81
+ w. clone ( ) ,
82
+ false
83
+ ) ;
84
+
85
+ let y: Self :: OutputI = y. map_into_owned ( |y| {
86
+ let ny = y. len ( ) ;
87
+ let mut y = y. into_iter ( ) ;
88
+ OwnedListOrSingle :: from_len_fn ( StaticMaybe :: maybe_from_fn ( || ny) , |_| y. next ( ) . unwrap ( ) )
89
+ } ) . into ( ) ;
90
+ y
91
+ } )
92
+ . coerce_into_matrix ( || panic ! ( "Matrix is not correctly shaped" ) ) ;
93
+
94
+ ( tt, y)
95
+ }
96
+ }
97
+
98
+ impl < T , B , A , L > StepS < L > for Tf < T , B , A >
99
+ where
100
+ T : ComplexFloat ,
101
+ B : MaybeLists < T > ,
102
+ A : MaybeList < T > ,
103
+ L : List < T :: Real > ,
104
+ <L :: Length as StaticMaybe < usize > >:: Opposite : Sized ,
105
+ B :: RowsMapped < L :: Mapped < T > > : Lists < T > + OwnedListOrSingle < L :: Mapped < T > , Length : StaticMaybe < usize , Opposite : Sized > > ,
106
+ Self : System < Set = T > + ToSs < T , Array2 < T > , Array2 < T > , Array2 < T > , Array2 < T > > ,
107
+ Array2 < T > : SsAMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsBMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsCMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsDMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > ,
108
+ Ss < T , Array2 < T > , Array2 < T > , Array2 < T > , Array2 < T > > : StepS < L , Output = Array2 < L :: Mapped < T > > > + System < Set = T >
109
+ {
110
+ type OutputI = B :: RowsMapped < L :: Mapped < T > > ;
111
+ type Output = B :: RowsMapped < L :: Mapped < T > > ;
112
+
113
+ fn step_s < TT , W > ( self , t : TT , numtaps : <L :: Length as StaticMaybe < usize > >:: Opposite , w : W )
114
+ -> ( L , Self :: Output )
115
+ where
116
+ TT : TwoSidedRange < T :: Real > + Clone ,
117
+ W : Maybe < Vec < T > >
118
+ {
119
+ let ( t, y) = self . to_ss ( )
120
+ . step_s ( t, numtaps, w) ;
121
+
122
+ let q = y. len ( ) ;
123
+ let mut y = y. into_iter ( ) ;
124
+
125
+ (
126
+ t,
127
+ OwnedListOrSingle :: from_len_fn ( StaticMaybe :: maybe_from_fn ( || q) , |_| y. next ( ) . unwrap ( ) )
128
+ )
129
+ }
130
+ }
131
+
132
+ impl < T , Z , P , K , L > StepS < L > for Zpk < T , Z , P , K >
133
+ where
134
+ T : ComplexFloat ,
135
+ Z : MaybeList < T > ,
136
+ P : MaybeList < T > ,
137
+ K : ComplexFloat < Real = T :: Real > ,
138
+ L : List < T :: Real > ,
139
+ <L :: Length as StaticMaybe < usize > >:: Opposite : Sized ,
140
+ L :: Mapped < K > : List < K > + ListOrSingle < L :: Mapped < K > > ,
141
+ Self : System < Set = K > + ToSs < K , Array2 < K > , Array2 < K > , Array2 < K > , Array2 < K > > ,
142
+ Array2 < K > : SsAMatrix < K , Array2 < K > , Array2 < K > , Array2 < K > > + SsBMatrix < K , Array2 < K > , Array2 < K > , Array2 < K > > + SsCMatrix < K , Array2 < K > , Array2 < K > , Array2 < K > > + SsDMatrix < K , Array2 < K > , Array2 < K > , Array2 < K > > ,
143
+ Ss < K , Array2 < K > , Array2 < K > , Array2 < K > , Array2 < K > > : System < Set = K > + StepS < L , Output = Array2 < L :: Mapped < K > > >
144
+ {
145
+ type OutputI = L :: Mapped < K > ;
146
+ type Output = L :: Mapped < K > ;
147
+
148
+ fn step_s < TT , W > ( self , t : TT , numtaps : <L :: Length as StaticMaybe < usize > >:: Opposite , w : W )
149
+ -> ( L , Self :: Output )
150
+ where
151
+ TT : TwoSidedRange < T :: Real > + Clone ,
152
+ W : Maybe < Vec < K > >
153
+ {
154
+ let ( t, y) = self . to_ss ( )
155
+ . step_s ( t, numtaps, w) ;
156
+
157
+ (
158
+ t,
159
+ y. into_iter ( )
160
+ . next ( )
161
+ . unwrap ( )
162
+ )
163
+ }
164
+ }
165
+
166
+ impl < T , B , A , S , L > StepS < L > for Sos < T , B , A , S >
167
+ where
168
+ T : ComplexFloat ,
169
+ B : Maybe < [ T ; 3 ] > + MaybeOwnedList < T > ,
170
+ A : Maybe < [ T ; 3 ] > + MaybeOwnedList < T > ,
171
+ S : MaybeList < Tf < T , B , A > > ,
172
+ L : List < T :: Real > ,
173
+ <L :: Length as StaticMaybe < usize > >:: Opposite : Sized ,
174
+ L :: Mapped < T > : List < T > + ListOrSingle < L :: Mapped < T > > ,
175
+ Self : System < Set = T > + ToSs < T , Array2 < T > , Array2 < T > , Array2 < T > , Array2 < T > > ,
176
+ Array2 < T > : SsAMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsBMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsCMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > + SsDMatrix < T , Array2 < T > , Array2 < T > , Array2 < T > > ,
177
+ Ss < T , Array2 < T > , Array2 < T > , Array2 < T > , Array2 < T > > : System < Set = T > + StepS < L , Output = Array2 < L :: Mapped < T > > >
178
+ {
179
+ type OutputI = L :: Mapped < T > ;
180
+ type Output = L :: Mapped < T > ;
181
+
182
+ fn step_s < TT , W > ( self , t : TT , numtaps : <L :: Length as StaticMaybe < usize > >:: Opposite , w : W )
183
+ -> ( L , Self :: Output )
184
+ where
185
+ TT : TwoSidedRange < T :: Real > + Clone ,
186
+ W : Maybe < Vec < T > >
187
+ {
188
+ let ( t, y) = self . to_ss ( )
189
+ . step_s ( t, numtaps, w) ;
190
+
191
+ (
192
+ t,
193
+ y. into_iter ( )
194
+ . next ( )
195
+ . unwrap ( )
196
+ )
197
+ }
198
+ }
199
+
200
+ #[ cfg( test) ]
201
+ mod test
202
+ {
203
+ use core:: f64:: consts:: TAU ;
204
+
205
+ use array_math:: ArrayOps ;
206
+
207
+ use crate :: { analysis:: StepS , gen:: filter:: { BesselF , FilterGenPlane , FilterGenType } , plot, systems:: Tf } ;
208
+
209
+ #[ test]
210
+ fn test ( )
211
+ {
212
+ let h = Tf :: besself ( 5 , [ TAU * 12.0 ] , FilterGenType :: LowPass , FilterGenPlane :: S )
213
+ . unwrap ( ) ;
214
+
215
+ const T : f64 = 1.25 ;
216
+ const N : usize = 200 ;
217
+ let ( t, y) : ( [ _ ; N ] , _ ) = h. step_s ( 0.0 ..T , ( ) , ( ) ) ;
218
+
219
+ plot:: plot_curves ( "y(t)" , "plots/y_t_step_s.png" , [ & t. zip ( y) ] )
220
+ . unwrap ( ) ;
221
+ }
222
+ }
0 commit comments