* A specialzed vector de-mux for estimating power within defined sub-bands of a vector that
* is the output of an FFT+complex-to-MAG
*
* It takes in a fixed-size float vector, and a list of descriptors describing the sub-bands that are to
* be added together to form an output channel. The output is a number of channels (one per descriptor).
*
* Consider the following example:
*
* Input vector: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* ^^^^^^ ^^^^ ^^^^^^^
* CH 0 CH 1 CH 2 (etc)
*
* For simple multi-channel power estimation this is significantly more efficient than many other techniques
* that might be used. Channel-width resolution is based purely on the resolution of the FFT+complex-to-MAG
* that feeds this specialized demux. Resolutions of a few hundred Hz with 25MHz input bandwidths appear to
* be feasible with this technique. For uniformly-spaced channels with relatively-coarse resolution, a PFB
* channel bank might be better.
*
* This "rides" on the fact that the Gnu Radio FFT implementation is very efficient, due to its use of
* FFTW, which provides several overlapping techniques to improve performance including:
*
* o an optimizer
* o aggressive use of SSEx/3DNow! instruction sets
* o multi-threaded FFT calculations (useful for very large FFTs, which are required for fine resolution)
*
* In many situations, the total number of post-FFT ops you need to do is quite modest compared to the FFT,
* since you may be ignoring the vast majority of the input vector. In the application domain of interest
* (multi-channel power estimation for ionospheric measurements), probably 98% of the input vector isn't
* touched. But the channels of interest are:
*
* o not evenly spaced
* o not of uniform bandwidth
* o between 1 and perhaps 10 sub-band "collections" (output channels) might be of interest
*
* invector - input vector of size 'vecsize'
* vec_begins - list of sub-channel start points (offsets from beginning of input vector)
* vec_ends - list of sub-channel end points (offsets from beginning of input vector)
* nchan - number of output channels (or "collections of sub-bands from input")
* outchans - the output channels
*
*/
int
vector_power_estimator_ff (float invector[], int vecsize, int vec_begins[], int vec_ends[], int nchan, float outchans[])
{
int i, j;
/*
* For each output channel descriptor
*/
for (i = 0; i < nchan; i++)
{
/*
* Accumulate an output channel from sub-bands in the input
*/
outchans[i] = 0.0;
for (j = vec_begins[i]; j < vec_ends[i]; j++)
{
if (j < vecsize)
{
/*
* Opportunity for volk-ifying here
*/
outchans[i] += invector[j];
}
}
}
return nchan;
}
Attached is a C implementation of a block I wish was in Gnu Radio.
Anyone done anything similar-enough as a block
in Gnu Radio that would make a decent starting point?
It's basically a block that takes a fixed-size vector input, and a list
of "descriptors" that describe output channels that need to be carved out of
the input vector (a list of start:end which are simply offsets into
the vector). It's intended to be used after a FFT+complex-to-MAG block to
process the resulting vector and select sub-bands and turn them into
power-estimate channels. I see nothing in Gnu Radio that does this,
other than things like the FFT channelizer, PFB channelizer, etc.
Neither of those is efficient in this case, because the channels are of
non-uniform distribution and width, and if the target is simply power
estimation, that part has already basically been done by the
FFT+complex-to-MAG stage.
--
Marcus Leech
Principal Investigator
Shirleys Bay Radio Astronomy Consortium
http://www.sbrac.org
No comments:
Post a Comment