Reputation: 307
I'm trying to implement a spectral correlation function to plot with the surf function. I think I understand the idea of the SCF as described in a paper I read, but I'm having trouble implementing my function in Matlab. I've been following these instructions:
I'm mostly having trouble shifting my pieces of the data properly. Is there an easy way to achieve step 3?
Here's what I tried in my code:
function [output] = spectral(x, N)
% This function does cyclostationary spectral analysis
% on a data set and returns some features
t = length(x);
samplesPerFrame = floor(t / N);
count = 1;
for alpha = -1:0.01:1
% Split up the samples into frames
% Have to leave some samples out if unevenly split
for i = 1:N+1
frange = ((i - 1) * samplesPerFrame + 1):(i * samplesPerFrame);
if i == N+1
break;
end
xFrame(i, :) = x(frange);
ts = [1:length(xFrame(i,:))];
shiftLeft = fft(xFrame(i, :) .* exp(-1 * 2 * pi * 1i * (alpha / 2) .* ts));
shiftRight = fft(xFrame(i, :).* exp(2 * pi * 1i * (alpha / 2) .* ts));
S(i,:) = (1 / samplesPerFrame) .* shiftLeft .* conj(shiftRight);
end
Savg(count, :) = mean(S, 1);
Ssmooth(count, :) = smooth(Savg(count,:), 'moving');
count = count + 1;
end
output = Ssmooth;
end
Upvotes: 0
Views: 1520
Reputation: 39
The method of spectral correlation estimation you are attempting is something I refer to as the Time-Smoothing Method of spectral correlation estimation, or the TSM. The code you posted cannot provide the correct answer except in some trivial cases such as alpha = 0. The reason is that you need to adjust the cyclic periodogram for each frame by a complex phase factor to compensate for the fact that each data block is a delayed version of the one preceding it.
If you replace the line
S(i,:) = (1 / samplesPerFrame) .* shiftLeft .* conj(shiftRight);
with the two lines
S(i,:) = (1 / samplesPerFrame) .* shiftLeft .* conj(shiftRight);
S(i, :) = S(i, :) * exp(-1i * 2 * pi * alpha * i * samplesPerFrame);
you'll be able to estimate the SCF. I confirmed this by applying your original code and the modified code to a BPSK signal with bit rate (normalized) of 1/10. In this case, one of your alpha values in the loop over alpha will exactly coincide with the true cycle frequency of 1/10. Only the modified code gives the correct SCF for the bit-rate cycle frequency.
Please see my blog cyclostationary.wordpress.com for more detail and examples. In particular, I have a post on the TSM at http://cyclostationary.blog/2015/12/18/csp-estimators-the-time-smoothing-method. (Corrected this link 5/2/17.)
Upvotes: 1
Reputation: 12689
It looks good actually.
You may also try circshift(fft(xFrame(i, :)),[1,a])
to achieve shiftRight
, and circshift(fft(xFrame(i, :)),[1,-a])
to get shiftLeft
. Please note here a
is integer, indicates the elements in xFrame(i, :)
that you wish to move, and corresponds to Fs*a
in frequency domain where Fs
is your sampling rate.
Upvotes: 1