@@ -13,27 +13,25 @@ defmodule NxSignal.Windows do
13
13
14
14
## Options
15
15
16
- * `:n` - the window length
17
16
* `:type` - the output type. Defaults to `s64`
18
17
19
18
## Examples
20
19
21
- iex> NxSignal.Windows.rectangular(n: 5)
20
+ iex> NxSignal.Windows.rectangular(5)
22
21
#Nx.Tensor<
23
22
s64[5]
24
23
[1, 1, 1, 1, 1]
25
24
>
26
25
27
- iex> NxSignal.Windows.rectangular(n: 5, type: :f32)
26
+ iex> NxSignal.Windows.rectangular(5, type: :f32)
28
27
#Nx.Tensor<
29
28
f32[5]
30
29
[1.0, 1.0, 1.0, 1.0, 1.0]
31
30
>
32
31
"""
33
32
@ doc type: :windowing
34
- defn rectangular ( opts \\ [ ] ) do
35
- opts = keyword! ( opts , [ :n , type: :s64 ] )
36
- { n , opts } = pop_window_size ( opts )
33
+ deftransform rectangular ( n , opts \\ [ ] ) when is_integer ( n ) do
34
+ opts = Keyword . validate! ( opts , type: :s64 )
37
35
Nx . broadcast ( Nx . tensor ( 1 , type: opts [ :type ] ) , { n } )
38
36
end
39
37
@@ -44,22 +42,25 @@ defmodule NxSignal.Windows do
44
42
45
43
## Options
46
44
47
- * `:n` - The window length. Mandatory option.
48
45
* `:type` - the output type for the window. Defaults to `{:f, 32}`
49
46
* `:name` - the axis name. Defaults to `nil`
50
47
51
48
## Examples
52
49
53
- iex> NxSignal.Windows.bartlett(n: 3)
50
+ iex> NxSignal.Windows.bartlett(3)
54
51
#Nx.Tensor<
55
52
f32[3]
56
53
[0.0, 0.6666666865348816, 0.6666666269302368]
57
54
>
58
55
"""
59
56
@ doc type: :windowing
60
- defn bartlett ( opts \\ [ ] ) do
61
- opts = keyword! ( opts , [ :n , :name , type: { :f , 32 } ] )
62
- { n , opts } = pop_window_size ( opts )
57
+ deftransform bartlett ( n , opts \\ [ ] ) when is_integer ( n ) do
58
+ opts = Keyword . validate! ( opts , type: { :f , 32 } )
59
+ bartlett_n ( Keyword . put ( opts , :n , n ) )
60
+ end
61
+
62
+ defnp bartlett_n ( opts ) do
63
+ n = opts [ :n ]
63
64
name = opts [ :name ]
64
65
type = opts [ :type ]
65
66
@@ -87,16 +88,20 @@ defmodule NxSignal.Windows do
87
88
88
89
## Examples
89
90
90
- iex> NxSignal.Windows.triangular(n: 3)
91
+ iex> NxSignal.Windows.triangular(3)
91
92
#Nx.Tensor<
92
93
f32[3]
93
94
[0.5, 1.0, 0.5]
94
95
>
95
96
"""
96
97
@ doc type: :windowing
97
- defn triangular ( opts \\ [ ] ) do
98
- opts = keyword! ( opts , [ :n , :name , type: { :f , 32 } ] )
99
- { n , opts } = pop_window_size ( opts )
98
+ deftransform triangular ( n , opts \\ [ ] ) when is_integer ( n ) do
99
+ opts = Keyword . validate! ( opts , [ :name , type: { :f , 32 } ] )
100
+ triangular_n ( Keyword . put ( opts , :n , n ) )
101
+ end
102
+
103
+ defnp triangular_n ( opts ) do
104
+ n = opts [ :n ]
100
105
name = opts [ :name ]
101
106
type = opts [ :type ]
102
107
@@ -126,48 +131,52 @@ defmodule NxSignal.Windows do
126
131
127
132
## Options
128
133
129
- * `:n` - The window length. Mandatory option.
130
134
* `:is_periodic` - If `true`, produces a periodic window,
131
135
otherwise produces a symmetric window. Defaults to `true`
132
136
* `:type` - the output type for the window. Defaults to `{:f, 32}`
133
137
* `:name` - the axis name. Defaults to `nil`
134
138
135
139
## Examples
136
140
137
- iex> NxSignal.Windows.blackman(n: 5, is_periodic: false)
141
+ iex> NxSignal.Windows.blackman(5, is_periodic: false)
138
142
#Nx.Tensor<
139
143
f32[5]
140
144
[-1.4901161193847656e-8, 0.3400000333786011, 0.9999999403953552, 0.3400000333786011, -1.4901161193847656e-8]
141
145
>
142
146
143
- iex> NxSignal.Windows.blackman(n: 5, is_periodic: true)
147
+ iex> NxSignal.Windows.blackman(5, is_periodic: true)
144
148
#Nx.Tensor<
145
149
f32[5]
146
150
[-1.4901161193847656e-8, 0.20077012479305267, 0.8492299318313599, 0.8492299318313599, 0.20077012479305267]
147
151
>
148
152
149
- iex> NxSignal.Windows.blackman(n: 6, is_periodic: true, type: {:f, 32})
153
+ iex> NxSignal.Windows.blackman(6, is_periodic: true, type: {:f, 32})
150
154
#Nx.Tensor<
151
155
f32[6]
152
156
[-1.4901161193847656e-8, 0.12999999523162842, 0.6299999952316284, 0.9999999403953552, 0.6299999952316284, 0.12999999523162842]
153
157
>
154
158
"""
155
159
@ doc type: :windowing
156
- defn blackman ( opts \\ [ ] ) do
157
- opts = keyword! ( opts , [ :n , :name , is_periodic: true , type: { :f , 32 } ] )
158
- { l , opts } = pop_window_size ( opts )
160
+ deftransform blackman ( n , opts \\ [ ] ) when is_integer ( n ) do
161
+ opts = Keyword . validate! ( opts , [ :name , is_periodic: true , type: { :f , 32 } ] )
162
+ blackman_n ( Keyword . put ( opts , :n , n ) )
163
+ end
164
+
165
+ defnp blackman_n ( opts ) do
166
+ n = opts [ :n ]
159
167
name = opts [ :name ]
160
168
type = opts [ :type ]
161
169
is_periodic = opts [ :is_periodic ]
162
170
163
171
l =
164
172
if is_periodic do
165
- l + 1
173
+ n + 1
166
174
else
167
- l
175
+ n
168
176
end
169
177
170
- m = div_ceil ( l , 2 )
178
+ m =
179
+ integer_div_ceil ( l , 2 )
171
180
172
181
n = Nx . iota ( { m } , names: [ name ] , type: type )
173
182
@@ -194,38 +203,41 @@ defmodule NxSignal.Windows do
194
203
195
204
## Options
196
205
197
- * `:n` - The window length. Mandatory option.
198
206
* `:is_periodic` - If `true`, produces a periodic window,
199
207
otherwise produces a symmetric window. Defaults to `true`
200
208
* `:type` - the output type for the window. Defaults to `{:f, 32}`
201
209
* `:name` - the axis name. Defaults to `nil`
202
210
203
211
## Examples
204
212
205
- iex> NxSignal.Windows.hamming(n: 5, is_periodic: true)
213
+ iex> NxSignal.Windows.hamming(5, is_periodic: true)
206
214
#Nx.Tensor<
207
215
f32[5]
208
216
[0.08000001311302185, 0.39785221219062805, 0.9121478796005249, 0.9121478199958801, 0.3978521227836609]
209
217
>
210
- iex> NxSignal.Windows.hamming(n: 5, is_periodic: false)
218
+ iex> NxSignal.Windows.hamming(5, is_periodic: false)
211
219
#Nx.Tensor<
212
220
f32[5]
213
221
[0.08000001311302185, 0.5400000214576721, 1.0, 0.5400000214576721, 0.08000001311302185]
214
222
>
215
223
"""
216
224
@ doc type: :windowing
217
- defn hamming ( opts \\ [ ] ) do
218
- opts = keyword! ( opts , [ :n , :name , is_periodic: true , type: { :f , 32 } ] )
219
- { l , opts } = pop_window_size ( opts )
225
+ deftransform hamming ( n , opts \\ [ ] ) when is_integer ( n ) do
226
+ opts = Keyword . validate! ( opts , [ :name , is_periodic: true , type: { :f , 32 } ] )
227
+ hamming_n ( Keyword . put ( opts , :n , n ) )
228
+ end
229
+
230
+ defnp hamming_n ( opts ) do
231
+ n = opts [ :n ]
220
232
name = opts [ :name ]
221
233
type = opts [ :type ]
222
234
is_periodic = opts [ :is_periodic ]
223
235
224
236
l =
225
237
if is_periodic do
226
- l + 1
238
+ n + 1
227
239
else
228
- l
240
+ n
229
241
end
230
242
231
243
n = Nx . iota ( { l } , names: [ name ] , type: type )
@@ -244,38 +256,41 @@ defmodule NxSignal.Windows do
244
256
245
257
## Options
246
258
247
- * `:n` - The window length. Mandatory option.
248
259
* `:is_periodic` - If `true`, produces a periodic window,
249
260
otherwise produces a symmetric window. Defaults to `true`
250
261
* `:type` - the output type for the window. Defaults to `{:f, 32}`
251
262
* `:name` - the axis name. Defaults to `nil`
252
263
253
264
## Examples
254
265
255
- iex> NxSignal.Windows.hann(n: 5, is_periodic: false)
266
+ iex> NxSignal.Windows.hann(5, is_periodic: false)
256
267
#Nx.Tensor<
257
268
f32[5]
258
269
[0.0, 0.5, 1.0, 0.5, 0.0]
259
270
>
260
- iex> NxSignal.Windows.hann(n: 5, is_periodic: true)
271
+ iex> NxSignal.Windows.hann(5, is_periodic: true)
261
272
#Nx.Tensor<
262
273
f32[5]
263
274
[0.0, 0.34549152851104736, 0.9045085310935974, 0.9045084714889526, 0.3454914391040802]
264
275
>
265
276
"""
266
277
@ doc type: :windowing
267
- defn hann ( opts \\ [ ] ) do
268
- opts = keyword! ( opts , [ :n , :name , is_periodic: true , type: { :f , 32 } ] )
269
- { l , opts } = pop_window_size ( opts )
278
+ deftransform hann ( n , opts \\ [ ] ) when is_integer ( n ) do
279
+ opts = Keyword . validate! ( opts , [ :name , is_periodic: true , type: { :f , 32 } ] )
280
+ hann_n ( Keyword . put ( opts , :n , n ) )
281
+ end
282
+
283
+ defnp hann_n ( opts ) do
284
+ n = opts [ :n ]
270
285
name = opts [ :name ]
271
286
type = opts [ :type ]
272
287
is_periodic = opts [ :is_periodic ]
273
288
274
289
l =
275
290
if is_periodic do
276
- l + 1
291
+ n + 1
277
292
else
278
- l
293
+ n
279
294
end
280
295
281
296
n = Nx . iota ( { l } , names: [ name ] , type: type )
@@ -296,7 +311,6 @@ defmodule NxSignal.Windows do
296
311
297
312
## Options
298
313
299
- * `:n` - The window length. Mandatory option.
300
314
* `:is_periodic` - If `true`, produces a periodic window,
301
315
otherwise produces a symmetric window. Defaults to `true`
302
316
* `:type` - the output type for the window. Defaults to `{:f, 32}`
@@ -305,46 +319,50 @@ defmodule NxSignal.Windows do
305
319
* `:axis_name` - the axis name. Defaults to `nil`
306
320
307
321
## Examples
308
- iex> NxSignal.Windows.kaiser(n: 4, beta: 12.0, is_periodic: true)
322
+ iex> NxSignal.Windows.kaiser(4, beta: 12.0, is_periodic: true)
309
323
#Nx.Tensor<
310
324
f32[4]
311
325
[5.2776191296288744e-5, 0.21566666662693024, 1.0, 0.21566666662693024]
312
326
>
313
327
314
- iex> NxSignal.Windows.kaiser(n: 5, beta: 12.0, is_periodic: true)
328
+ iex> NxSignal.Windows.kaiser(5, beta: 12.0, is_periodic: true)
315
329
#Nx.Tensor<
316
330
f32[5]
317
331
[5.2776191296288744e-5, 0.10171464085578918, 0.7929369807243347, 0.7929369807243347, 0.10171464085578918]
318
332
>
319
333
320
- iex> NxSignal.Windows.kaiser(n: 4, beta: 12.0, is_periodic: false)
334
+ iex> NxSignal.Windows.kaiser(4, beta: 12.0, is_periodic: false)
321
335
#Nx.Tensor<
322
336
f32[4]
323
337
[5.2776191296288744e-5, 0.5188394784927368, 0.5188390612602234, 5.2776191296288744e-5]
324
338
>
325
339
"""
326
340
@ doc type: :windowing
327
- defn kaiser ( opts \\ [ ] ) do
341
+ deftransform kaiser ( n , opts \\ [ ] ) when is_integer ( n ) do
328
342
opts =
329
- keyword! ( opts , [ :n , :axis_name , eps: 1.0e-7 , beta: 12.0 , is_periodic: true , type: { :f , 32 } ] )
343
+ Keyword . validate! ( opts , [ :name , eps: 1.0e-7 , beta: 12.0 , is_periodic: true , type: { :f , 32 } ] )
344
+
345
+ kaiser_n ( Keyword . put ( opts , :n , n ) )
346
+ end
330
347
331
- { l , opts } = pop_window_size ( opts )
332
- name = opts [ :axis_name ]
348
+ defnp kaiser_n ( opts ) do
349
+ n = opts [ :n ]
350
+ name = opts [ :name ]
333
351
type = opts [ :type ]
334
352
beta = opts [ :beta ]
335
353
eps = opts [ :eps ]
336
354
is_periodic = opts [ :is_periodic ]
337
355
338
- window_length = if is_periodic , do: l + 1 , else: l
356
+ window_length = if is_periodic , do: n + 1 , else: n
339
357
340
- ratio = Nx . linspace ( - 1 , 1 , n: window_length , endpoint: true , type: type ) |> Nx . rename ( [ name ] )
358
+ ratio = Nx . linspace ( - 1 , 1 , n: window_length , endpoint: true , type: type , name: name )
341
359
sqrt_arg = Nx . max ( 1 - ratio ** 2 , eps )
342
360
r = beta * Nx . sqrt ( sqrt_arg )
343
361
344
362
window = kaiser_bessel_i0 ( r ) / kaiser_bessel_i0 ( beta )
345
363
346
364
if is_periodic do
347
- Nx . slice ( window , [ 0 ] , [ l ] )
365
+ Nx . slice ( window , [ 0 ] , [ n ] )
348
366
else
349
367
window
350
368
end
@@ -367,17 +385,13 @@ defmodule NxSignal.Windows do
367
385
Nx . select ( abs_x < 3.75 , small_x_result , large_x_result )
368
386
end
369
387
370
- deftransformp pop_window_size ( opts ) do
371
- { n , opts } = Keyword . pop ( opts , :n )
388
+ deftransformp integer_div_ceil ( num , den ) when is_integer ( num ) and is_integer ( den ) do
389
+ rem = rem ( num , den )
372
390
373
- if ! n do
374
- raise "missing :n option"
391
+ if rem == 0 do
392
+ div ( num , den )
393
+ else
394
+ div ( num , den ) + 1
375
395
end
376
-
377
- { n , opts }
378
- end
379
-
380
- deftransformp div_ceil ( num , den ) do
381
- ceil ( num / den )
382
396
end
383
397
end
0 commit comments