Replies: 2 comments
-
Thanks for these pertinent comments and suggestions.
|
Beta Was this translation helpful? Give feedback.
-
Attached is a toy implementation of polyphase interpolation applied to upsampling RRC filter. No idea how to efficiently implement decimator in tf, probably needs to be part of convolve (for np, I use my own c++ code for both efficient interpolation and decimation). The idea is very simple, the non-efficient way is first compute all the samples y_i, then throw away most of them (downsampling). The efficient way is don't compute the ones you'd throw away.
|
Beta Was this translation helpful? Give feedback.
-
I'm very happy to see that sionna-0.9.0 now has some support for filters. I have a few suggestions about the design. Bear in mind my background is from decades of experience in signal processing and communications, but new to tensorflow (TF) and it's limitations/performance tradeoffs.
Stateless filters (filter function) are fine for burst-mode simulations, but is not convenient for continuous-mode simulations. In that case it is better for filters to be objects with internal state. The state represents the input history, and in the case of decimating filters, the decimation phase. This allows processing to proceed in blocks of some convenient size that will fit in memory.
Efficient design of upsampling (interpolation) and downsampling (decimation) filters is well-known, with all processing at the low sample rate. The use of external upsampling (zero insertion) and downsampling (sample dropping) is not efficient. I don't know if TF would support efficient implementations well. (I'm assuming here the convolution is implemented in the time domain, as it would be for small filters).
Two common use cases in comm. filters are complex x complex -> complex, and complex x real -> complex, the latter needing 1/2 the multiplications and easily implemented as 2 real x real -> real (the common RRC filter is an example). I'm guessing that the easiest way to take advantage of this in TF is to code them as different object types.
In the past I've coded in c++ 9 filter objects: plain filters, decimating, and interpolating: each with 3 types: real x real, complex x real, and complex x complex (the type polymorphism is handled by c++ templates). I could provide this code if it is of interest.
Perhaps a more elegant example (which I didn't write) in Julia is here:
https://github.com/JuliaDSP/DSP.jl/blob/master/src/Filters/stream_filt.jl
which combines interpolation/decimation (my approach is simple brute force).
Thanks again for initiating this effort,
Neal Becker
Beta Was this translation helpful? Give feedback.
All reactions