CSP Estimators: The FFT Accumulation Method

Let’s look at another spectral correlation function estimator: the FFT Accumulation Method (FAM). This estimator is in the time-smoothing category, is exhaustive in that it is designed to compute estimates of the spectral correlation function over its entire principal domain, and is efficient, so that it is a competitor to the Strip Spectral Correlation Analyzer (SSCA) method. I implemented my version of the FAM by using the paper by Roberts et al (The Literature [R4]). If you follow the equations closely, you can successfully implement the estimator from that paper. The tricky part, as with the SSCA, is correctly associating the outputs of the coded equations to their proper \displaystyle (f, \alpha) values.

We’ll also implement a coherence computation in our FAM, and use it to automatically detect the significant cycle frequencies, just as we like to do with the SSCA. Finally, we’ll compare outputs between the SSCA and FAM spectral-correlation and spectral-coherence estimation methods. The algorithms’ implementations are not without issues and mysteries, and we’ll point them out too. Please leave corrections, comments, and clarifications in the comment section.

Definition of the FFT Accumulation Method

The method produces a large number of point estimates of the cross spectral correlation function. In [R4], the point estimates are given by

\displaystyle S_{xy_T}^{\alpha_i + q\Delta\alpha} (rL, f_j)_{\Delta\!t} = \sum_{r}X_T(rL, f_k) Y_T^* (rL, f_l) g_c(n-r) e^{-i2\pi r q /P}  \hfill (1)

where the complex demodulates are given by

\displaystyle X_T(n,f) = \sum_{r=-N^\prime/2}^{N^\prime/2} a(r) x(n-r) e^{-i 2 \pi f(n-r)T_s} \hfill (2)

Equation (2) here is Equation (2) in [R4]. I think it should have a sum over N^\prime samples, rather than N^\prime+1,

\displaystyle X_T(n,f) = \sum_{r=-N^\prime/2}^{N^\prime/2-1} a(r) x(n-r) e^{-i 2 \pi f(n-r)T_s} \hfill (3)

In (1), the function g_c(n) is a data-tapering window, which is commonly taken to be a unit-height rectangle (and therefore no actual multiplications are needed), and in (2), the function a(r) is another tapering window, which is often taken to be a Hamming window (can be generated using MATLAB’s hamming.m).

The sampling rate is \displaystyle f_s = 1/T_s. In (2) and (3), \displaystyle T = N^\prime T_s. The channelizer (short-time hopped) Fourier transforms’ tapering window \displaystyle a(r) has width \displaystyle T_s N^\prime, and the output (long-time) Fourier transforms’ tapering window \displaystyle g_c(r) has width NT_s, which is the length of the data-block that is processed.

So the FAM channelizes the input data using short Fourier transforms of length \displaystyle N^\prime, which are hopped in time by L samples. This results in a sequence of transforms that has length

\displaystyle P = N/L \hfill (4)

where here I am assuming that both N and L are dyadic integers, with L \ll N. Therefore, the length of the output Fourier transforms is P.

For (1), [R4] defines the cycle-frequency resolution as

\displaystyle \Delta\alpha = 1/N \hfill (5)

in normalized-frequency units. Finally, the point estimate is associated with the cycle frequency \displaystyle \alpha_i and the spectral frequency \displaystyle f_j, which are defined in terms of the spectral components involved in the output transform:

\displaystyle \alpha_i = f_k - f_l \hfill (6)

and

\displaystyle f_j = (f_k + f_l)/2 \hfill (7)

Basic Steps in Implementing the FAM in Software

Step 1: Find and Arrange the \displaystyle N^\prime-Point Data Subblocks

Thinking in terms of MATLAB coding, we’d like to perform as many vector or matrix operations as possible, and as few for-loop operations as possible. So when we extract our blocks of N^\prime samples, sliding along by L samples, we can place each one in a column of a matrix:

fam_data_blocks

Note that to achieve the full set of P blocks, we’ll need to add a few zeroes to the end of the input x(t). So now we have a matrix with N^\prime rows and P columns.

Step 2: Apply Data-Tapering Window to Subblocks

We will be Fourier transforming each column of the data-block matrix from Step 1, but before that we’ll apply the channelizer data-tapering window called a(\cdot) above. Let’s pick the Hamming window, available in MATLAB as the m-file function hamming.m. Let’s denote this particular choice for a(\cdot) by h(\cdot). Each column of our data-block matrix needs to be multiplied by a Hamming window with length N^\prime:

fam_data_blocks_window

Step 3: Apply Fourier Transform to Windowed Subblocks

Next, apply the Fourier transform to each column. This is easy in MATLAB with fft.m, but there is a complication. The relative delay that exists between each of the blocks in the matrix is lost when fft.m is applied to each column. That is, (2) above is not exactly computed; the phase relationship between the transforms is modified through the use of fft.m, which we want to use for computational efficiency.

fam_channelized

So after the FFT is applied to the data blocks, they need to be phase-shifted. The phase shift for a particular element depends on the frequency f_j and the time index rL. This is similar to what we do in the time-smoothing method of spectral correlation estimation; see this post for details.

Do the same thing for the input y(t). If x(t) == y(t), then don’t bother repeating the computation, otherwise, do so:

fam_channelized_Y

Step 4: Multiply Channelized Subblocks Together and Fourier Transform

Looking back at (1), we now need to multiply (elementwise) one row from the X matrix by one row from the Y matrix, conjugating the latter. This will result in a vector of P complex values, which can then be transformed using the FFT. For example, below I’ve boxed the X values for f_k = f_1 and the Y values for f_l = f_2.

fam_channelized_boxed

fam_channels_Y_boxed

Step 5: Associate Each Fourier Transform Output with the Correct \displaystyle (f, \alpha)

According to (1), the P values that arise from the Fourier transform of the channelizer product vector correspond to the P cycle frequencies

\displaystyle \alpha_i + q\Delta\alpha \hfill (8)

where \displaystyle \Delta\alpha and \displaystyle \alpha_i are defined in (5) and (6), and q ranges over P integers. This association leads to values in the familiar diamond-shaped principal domain of the spectral correlation function; any values that do not lie in that region can be discarded. So at this point, we have a large number of spectral correlation function point estimates for frequencies in the (normalized) range \displaystyle [-0.5, 0.5) and cycle frequencies in the range \displaystyle [-1.0, 1.0).

Extension to the Conjugate Spectral Correlation Function

If \displaystyle x(t) = y(t), then \displaystyle Y_T(t,f) = X_T(t,f), and the estimate produced by (1) corresponds to the (auto) non-conjugate spectral correlation function. If \displaystyle y(t) = x^*(t), then the estimate corresponds to the conjugate spectral correlation function. Otherwise, it is a generic cross spectral correlation function. The extension to the conjugate spectral correlation function is that easy! It’s only a little more complicated to extend the conjugate spectral correlation function to the conjugate coherence than it is to extend the non-conjugate spectral correlation to the non-conjugate coherence.

Extension to Coherence

Recall that the spectral coherence function, or just coherence, is defined for the non-conjugate spectral correlation function by

\displaystyle C_x^\alpha(f) = \frac{S_x^\alpha(f)}{\left[ S_x^0(f+\alpha/2)S_x^0(f-\alpha/2) \right]^{1/2}} \hfill (9)

The conjugate coherence is given by

\displaystyle C_{x^*}^\alpha(f) = \frac{S_{x^*}^\alpha(f)}{\left[ S_x^0(f+\alpha/2) S_x^0(\alpha/2 - f) \right]^{1/2}} \hfill (10)

To compute estimates of the coherence, then, go through the spectral correlation estimates one by one, find the associated spectral frequency f and cycle frequency \alpha from Step 5, and then use a PSD estimate to find the corresponding two PSD values that form the normalization factor. I typically use a side estimate of the PSD that is highly oversampled so it is easy to find the required PSD values for any valid combination of spectral frequency f and cycle-frequency shift \pm\alpha/2. The frequency-smoothing method is a good choice for creating such PSD estimates.

The coherence is especially useful for automatic detection of significant cycle frequencies in a way that is invariant to signal and noise power levels, as described in the comments of the SSCA post.

Examples

Let’s look at the output of the FAM I’ve implemented with an eye toward comparing to the strip spectral correlation analyzer and (of course!) to the known spectral correlation surface for our old friend the rectangular-pulse BPSK signal.

Rectangular-Pulse BPSK (Textbook Signal)

First, let’s review the theoretical spectral correlation function for a rectangular-pulse BPSK signal with independent and identically distributed bits, ten samples per bit, and a carrier offset of 0.05:

ww_ideal_scf_BPSK_fs_1

The signal exhibits non-conjugate cycle frequencies that are multiples of the bit rate, or \displaystyle \alpha = kf_{bit}, k = 0, \pm 1, \pm 2, \ldots, which for \displaystyle f_{bit} = 0.1 is the set \displaystyle \{0, \pm 0.1, \pm 0.2, \ldots\}. Due to symmetry considerations, we ignore the negative non-conjugate cycle frequencies in our plots.

It also exhibits the conjugate cycle frequencies that are the non-conjugate cycle frequencies plus the doubled carrier 2f_c = 2(0.05) = 0.1. The shape of the conjugate spectral correlation function for \alpha = 2f_c is the same as that for the non-conjugate spectral correlation function for \alpha = 0 (the PSD).

Let’s start the progression of FAM results for rectangular-pulse BPSK with the FAM power spectrum estimate together with a TSM-based PSD estimate for comparison:

fam_tsm_psd_plot_bpsk

 

Both PSD estimates look like what we expect for the signal, but you can see a small regular ripple in the FAM estimate, which is not in the TSM estimate, and which we know is not a true feature of the PSD for the signal. So that is a mystery I’ve not yet solved. We’ll see, though, that overall the FAM implementation I’ve created compares well to the SSCA outputs in terms of cycle frequencies, spectral correlation magnitudes, and spectral coherence magnitudes.

Next, I want to show the FAM-based non-conjugate and conjugate spectral correlation surfaces. Let’s first mention the processing parameters:

  • \displaystyle N = 32768
  • \displaystyle N^\prime = 32
  • \displaystyle L = N^\prime / 4
  • \displaystyle P_{FA} = 10^{-9}

The latter parameter is used, together with N and N^\prime, to compute a threshold for the coherence function. Only those point estimates that correspond to a coherence magnitude that exceeds the threshold are included in the following FAM spectral correlation surface plots:

fam_surf_nonconj_bpsk

fam_surf_conj_bpsk

So the FAM surfaces agree with the ideal surfaces in terms of the known cycle frequency values and the variation over spectral frequency f for each coherence-detected \alpha. In other words, it works.

In the following graphs, I show the cyclic domain profiles for the FAM and for the SSCA for comparison:

fam_ssca_cdp_scf_nc_bpskfam_ssca_cdp_scf_c_bpskfam_ssca_cdp_coh_nc_bpskfam_ssca_cdp_coh_c_bpsk

Finally, here are plots of only the coherence-threshold detected cycle frequencies, which is a typical desired output in CSP practice:

fam_ssca_cfs_scf_nc_bpskfam_ssca_cfs_coh_c_bpskfam_ssca_cfs_coh_nc_bpskfam_ssca_cfs_scf_c_bpsk

Only true cycle frequencies are detected by both algorithms. The average values for spectral correlation and coherence for all the other cycle frequencies are about the same between the FAM and the SSCA. Two anomalies are worth mentioning. The first is that the SSCA produces a coherence significantly greater than one for the doubled-carrier conjugate cycle frequency of 0.1. The second is that the FAM produces a few false peaks in the spectral correlation function (near 0.6, 0.7, and 0.8). These all have coherence magnitudes that do not exceed threshold, so they don’t end up getting detected and don’t appear in the later plots. I don’t yet know the origin of these spurious spectral correlation peaks, and if you have an idea about it, feel free to leave a comment below.

Captured DSSS BPSK

Let’s end this post by showing FAM and SSCA results for a non-textbook signal, a captured DSSS BPSK signal. Recall that DSSS BPSK has many cycle frequencies, both non-conjugate and conjugate, and that the number of cycle frequencies increases as the processing gain increases. See the DSSS post and the SCF Gallery post for more details and examples.

In this example, the sampling rate is arbitrarily set to 5 MHz, and the number of processed samples is N = 65536.

fam_tsm_psd_plot_dsss

fam_surf_nonconj_dsssfam_surf_conj_dsssfam_ssca_cdp_scf_nc_dsssfam_ssca_cdp_scf_c_dsssfam_ssca_cdp_coh_nc_dsssfam_ssca_cdp_coh_c_dsssfam_ssca_cfs_scf_nc_dsssfam_ssca_cfs_scf_c_dsssfam_ssca_cfs_coh_nc_dsssfam_ssca_cfs_coh_c_dsss

60 thoughts on “CSP Estimators: The FFT Accumulation Method

  1. Mirko von Leipzig says:

    I’m curious if choosing different window functions would help alleviate the differences between FAM and SSCA. I know that common practice is a window to determine spectral peak location, and a completely different one to accurately determine actual peak power.

    A Hann/Hamming window is a middle ground window AFAIK – a bit of both worlds.

    • That sounds right to me. I actually use a different window on the “channelizer” Fourier transforms in the SSCA than I do in the FAM. I should redo a couple of those FAM/SSCA comparison calculations using a couple different windows–and show a couple where the two algorithms use the same window. Thanks Mirko!

  2. ÖZKAN AKBUNAR says:

    Hi Mr.Spooner
    I couldnt understand how shift phase of data after fft in step (3), it is also not clear in time smoothing post for me. I will be appreciated if you will explain what is it ?

    Best regards.

    • Looking at Eq (1) in the TSM post, we see that the right side is almost the DFT (FFT). The difference is in the argument of the data function x(\cdot), which is t+u. If u=0, the right side is the DFT. So as we slide along in time with u, the increasing value of $u$ causes the appearance of a complex exponential factor multiplying a DFT. When we use the FFT to compute the DFT, this factor is ignored because each call to the FFT function processes a data vector that starts at time equal to zero.

      In other words, take (1) and evaluate (write the equation) it for u=0 and for u= N. You will see that the latter possesses the same form as the former, but also has a complex exponential factor.

      If we use the FFT to compute the transforms of successive blocks, we’ll lose the phase relationship between the frequency components for some f in each block. So we have to compensate for that. The X(u, f+\alpha/2) factor in the cyclic periodogram is shifted by e^{i 2 \pi (f + \alpha/2)u} and the factor X(u, f-\alpha/2) is shifted by e^{-i2\pi(f-\alpha/2)u}. These multiply to yield a factor of e^{i 2 \pi \alpha u}. Since u takes on the values 1, N, 2N, \ldots, JN, \ldots, we need to compensate the jth cyclic periodogram by e^{-i 2 \pi \alpha j N}.

      I may have got some minus signs wrong, but that is the basic idea. The FFT is not a sliding transform.

      Does that help?

      • ÖZKAN AKBUNAR says:

        Thanks Mr.Spooner

        I have some questions again, what should be dimensions of matrix which is result of step 4, actually i cant understand how multiply X(rL,f) and its conjugate. You said elementwise multiplication, but I couldnt catch how to multiply elementwise. For instance, should I multiply first rows of two matrix (then second rows and so on), or else?
        In step 5 mapping to cycle frequency and frequency doesnt clear for me, can i do this mapping as SSCA method or i should use different mapping way?

        • If you want to store the result of Step 4 in a matrix, it would have dimension (N^\prime)^2 x P. Each of the two matrices has N^\prime rows, and you want to multiply all possible pairs of rows. By ‘elementwise multiplication’ I just mean the following. Let X=[x_1 \ x_2\ x_3] and Y=[y_1\ y_2\ y_3]. Then the elementwise multiplication of X and Y is [x_1y_1\ x_2y_2\ x_3y_3].

          The mapping in Step 5 is given by Equations (5), (6), and (8)$. What is your specific question about that?

          • Özkan Akbunar says:

            I understood that formulae but actually I dont understand how i can implement formulae on my matrix in Matlab. This part is not clear for me contrary to first 4 step. Could you explain this part clearly again?

            Also, i found some Matlab codes about this topic and i saw that some peoples takes transpose of matrix which is result of step 4 , is it right?

            Best regards Mr. Spooner

          • I am struggling to understand what you don’t understand. Not enough detail in your question?

            Regarding your question about some found MATLAB code, I can’t comment on what I can’t see. There are lots of ways to implement an equation, typically, so I can’t say if what you found is correct or not. Does it produce the correct result?

  3. Yorgo Giannakis says:

    Hello Mr. Spooner,
    I couldn’t understand how to implement shifted SCFs in Matlab or another simulation environment. For example, let say that alpha and f are equal to 1 an 0.5 respectively. In this situation, f+alpha/2 becomes 1 which is not a value f can take. If f+(or -)alpha/2 exceeds limited region of frequency [-0.5, 0.5), what is the thing I must do?
    Thank for valuable contribution to cyclo-lover society.

    • Thanks Yorgo!

      Well, the principal domain of the spectral correlation function is a diamond in the f-\alpha plane, and the tips of the diamond are at (f, \alpha) = (0, \pm 1). But as you note, if you shift the DFT to the left by \alpha/2 = 0.5 and to the right by \alpha/2 = 0.5, you will not have any overlap between the two DFTs when you go to multiply them together. So \alpha = 1 is a boundary case of little practical importance.

      In general, only use those pairs of frequencies f \pm \alpha/2 for which each frequency lies in [-0.5, 0.5), and ignore the rest.

  4. Yorgo Giannakis says:

    Thanks for your response. I have a new question why we expect the cyclic frequencies at alpha=k*f_bit for integer values of k. I feel that if the PSD is multiplied by PSD shifted with alpha, this multiplication gives a information about SCF. The point I’m wondering is that the PSD is a continuous function of BPSK sign, so why does not the shift of this signal for any alpha value give a peak?

    • The spectral correlation function is not the result of correlating shifted PSDs. It is the correlation between two complex-valued narrowband downconverted components of the input signal. These two narrowband signal components are correlated only when the separation between their center frequencies (before downconversion of course) is equal to a cycle frequency, and the particular cycle frequencies depend on the details of the modulation type of the signal in the input data. Maybe take another look at the introductory post on spectral correlation?

  5. Manuel Da Costa says:

    Hello Mr. Spooner,
    I have some questions about FFT Accumulation Method, firstly, I implemented this method in Matlab to investigate cyclostationary of some basic signal, However, i am stucked at some point, first of all i understood parameter N’ depends on us, or application. I tried my code for different N’ values and I saw a liitle bit different results. What is reason for this and what is optimal way to choose N’ ?
    Secondly, sample size of input data is affects cyclic spectrum of signals importantly, is there any way to compansate effects of lower sample sizes?
    As you know Matlab is very slow program and computational complexity of algorithm is high.
    Thirds, ı investigate cyclic spectrum of OFDM signals especially and i read ur paper which is called “On the Cyclostationarity of OFDM and SC-Linearly Digitally Modulated Signals in Time Dispersive Chnnels: Theoretical Developments and Applications”, but algebra in paper is little bit complex and confusing for me. Can you suggest any resource to understand cyclostationary of OFDM Signals?
    Lastly,I am thankful to you for this blog, it really helps me for my workings.
    Best regards.
    Manuel

    • Manuel, thanks very much for checking out the CSP Blog. I appreciate readers like you.

      Regarding N^\prime, in the FAM it controls the effective spectral resolution \Delta f of the measurement. The total amount of processed data is N samples, which we often call \Delta t. Recall from the post on the resolution product that the variability in an SCF estimate is inversely proportional to the resolution product \Delta t \Delta f.

      We know the estimate should get better the larger N is, and for very small N you won’t even be processing a single period of cyclostationarity (for BPSK, the symbol interval), so small N must result in poor estimates. For N larger than that, but still small, I know of little that can be done except through making \Delta f larger.

      MATLAB isn’t all that slow in my opinion. It really does not like to do ‘for loops’ though, and nested for loops can definitely slow it down. Try to restructure your MATLAB code so that you eliminate as many for loops as possible (use matrix operations). My FAM implementation takes about 10 seconds to compute the full non-conjugate SCF and coherence for N= 65536, N^\prime = 32, and L = 8. And that includes making several plots.

      For the cyclostationarity of OFDM signals, I can only suggest that Google is your friend.

  6. Manuel Da Costa says:

    Hello Mr.Spooner
    Thanks for your reply, i also read your blog about higher order cyclostationary to calculate cyclic cumulant of any kind of signal but i couldnt imagine how to write code to find cyclic cumulants in Matlab. You said that cyclic cumulant is Fourier series coefficient of higher order cumulant. I thought that if i can calculate higher order cumulant of signal then also find Fourier series coefficients of that cumulant, i can get my cyclic cumulant values. However , I cant find any way how to take values of delay vector in cumulant formula. I took delay vector is zero vector and in that case my cumulant result is scalar and i didnt find Fourier series coefficients. If this idea is true, how i should identify delay vector ?
    Secondly, I implemented FAM method as i said in previous comment. I thought, i find cyclic autocorrelation which is second order cyclic cumulant using FAM method, then i also find higher order cyclic cumulunt with this method. Is this idea is true? If this is true how, can you give detailed explanation as in your post FFT Accumulation Method for cyclic autocorrelation and spectral correlation function.
    Thank you.
    Best Regards.
    Manuel

    • i also read your blog about higher order cyclostationary to calculate cyclic cumulant of any kind of signal but i couldnt imagine how to write code to find cyclic cumulants in Matlab. You said that cyclic cumulant is Fourier series coefficient of higher order cumulant. I thought that if i can calculate higher order cumulant of signal then also find Fourier series coefficients of that cumulant, i can get my cyclic cumulant values. However , I cant find any way how to take values of delay vector in cumulant formula. I took delay vector is zero vector and in that case my cumulant result is scalar and i didnt find Fourier series coefficients.

      Do you mean the post on moment and cumulant estimators? I think that is a good place for you to start. There are several types of estimators described there, including one that actually produces the time-varying cyclic cumulant function (using synchronized averaging). The delays in the expressions for temporal moments and cumulants are just the delays applied to the input data block before creating a lag product (sometimes called a delay product) such as L_x(t, \tau_1, \tau_2) = x(t+\tau_1) x^*(t+\tau_2). So you can see that L_x(\cdot) is a function of time (not a scalar), as well as a function of the delays (lags) \tau_j. If the delays are small relative to the block length (a common case), then you can use MATLAB’s circshift.m to implement them with some small loss of fidelity because it is a circular shift rather than a true delay.

      If this idea is true, how i should identify delay vector ?

      The delay vector choice is driven by the form of the theoretical cyclic cumulant for the signal of interest as well as by the algorithm: what are you going to do with the cyclic cumulant estimates. For many signals, the delay consisting of all zeros corresponds to the cyclic cumulant with the largest magnitude over all possible delay vectors.

      Secondly, I implemented FAM method as i said in previous comment. I thought, i find cyclic autocorrelation which is second order cyclic cumulant using FAM method, then i also find higher order cyclic cumulunt with this method. Is this idea is true?

      Well, the FAM produces an estimate of the spectral correlation function, which is not the second-order cyclic cumulant. I suppose you could try to inverse Fourier transform the FAM output to get the cyclic autocorrelation, which is indeed the second-order cyclic cumulant for signals that do not contain finite-strength additive sine-wave components. It is difficult to directly use the FAM or SSCA to find the higher order cyclic cumulants. Probably it is best to start in the time domain instead of trying to use the frequency-domain FAM.

      If this is true how, can you give detailed explanation as in your post FFT Accumulation Method for cyclic autocorrelation and spectral correlation function.

      I think the best thing for you to do is study the post on estimation of higher-order temporal moments and cumulants. Let me know what you think!

  7. Kevin Young says:

    Hi Chad
    Thank you for your very useful blog!
    Here, I have a couple of questions on the implementation of FAM.
    1. I understand that after the first N’-point FFT on the windowed signal (step 3), each row denotes a frequency bin from -fs/2:fs/N’:fs/2-fs/N’. After the second P-point FFT on the multiplication of channelized subblocks (step 4), what does each column correspond to?
    2. After step 4, I have an array with P x N’ x N’ data. shall I just choose those that satisfies -fs<=alpha<=fs and -0.5*fs<=f<=0.5*fs from P x N' x N' data to generate f-alpha plot?
    3. In some thesis (www.dtic.mil/docs/citations/ADA311555), I saw that the author only used P/4:3*P/4 column data (use fft and fftshift) after step 4 to generate f-alpha plot. Do you think it is just for the data filtering purpose?

    • Thanks for your interest and the comment Kevin; I really appreciate readers like you.

      1. I understand that after the first N’-point FFT on the windowed signal (step 3), each row denotes a frequency bin from -fs/2:fs/N’:fs/2-fs/N’. After the second P-point FFT on the multiplication of channelized subblocks (step 4), what does each column correspond to?

      Do you mean other than Eq (8) in the post? I’m wondering if I’ve been clear in Step 5, which tries to explain the meaning of the various values coming out of the P-point transforms…

      2. After step 4, I have an array with P x N’ x N’ data. shall I just choose those that satisfies -fs<=alpha<=fs and -0.5*fs<=f<=0.5*fs from P x N' x N' data to generate f-alpha plot?

      Yes, that’s exactly what I do to produce the various plots that I display in the post.

      3. In some thesis (www.dtic.mil/docs/citations/ADA311555), I saw that the author only used P/4:3*P/4 column data (use fft and fftshift) after step 4 to generate f-alpha plot. Do you think it is just for the data filtering purpose?

      I’m not exactly sure why they chose to do it that way, but I suppose if you carefully do the step above (your question 2, my algorithm Step 5), and keep track of which parts of the P-point transforms you are saving, you might then translate that result into a more efficient step involving the matrix manipulations you mention. I admit that my MATLAB FAM implementation is not optimized for run time; I just wanted to make sure it was essentially correct. I generally use the SSCA for actual CSP work. Good question! Let me know through a comment here if you discover the exact reason why they do what they do in that thesis, and if you agree with it in the end.

      • Kevin says:

        Hi Chad

        Thank you for your reply!

        On your following comment, I believe your description of Step 5 is clear to me except for the range of q value in equation (8). Is it from -P/2 to P/2-1 or from 0 to P-1?

        Do you mean other than Eq (8) in the post? I’m wondering if I’ve been clear in Step 5, which tries to explain the meaning of the various values coming out of the P-point transforms…

        Another question I have is when my signal is composed of two different signals, e.g., one sin and one cos function, is the SCF the sum of SCF of sin and cos?

        Thanks!
        Kevin

        • On your following comment, I believe your description of Step 5 is clear to me except for the range of q value in equation (8). Is it from -P/2 to P/2-1 or from 0 to P-1?

          Well, did you try each way and see whether one gives the expected answer for an input for which you know the correct set of cycle frequencies and spectral correlation function magnitudes? I start from 0, but this question is probably easily answered by you if you’ve got the basic FAM working.

          Another question I have is when my signal is composed of two different signals, e.g., one sin and one cos function, is the SCF the sum of SCF of sin and cos?

          This isn’t a completely clear question to me, but it lies in a subtle area of CSP. When you have the sum of statistically independent zero-mean signals, the SCF of the sum is the sum of the SCFs for each summand in the sum. But every word there is important, and “zero-mean” refers to a mean of zero in the fraction-of-time probability framework. That is, a sine wave is not a zero-mean signal in the FOT framework. But if by “sin and cos” you really mean two modulated sine waves in quadrature (such as in QPSK), then, yes, you can add the SCFs for each of the quadrature components provided the modulating signals are themselves statistically independent (which is generally true for QPSK).

          For discussions of these kinds of subtle issues, I suggest my two-part HOCS paper (My Papers [5,6]) or my doctoral dissertation.

  8. Taymaz says:

    Hi Dear spooner,
    I am working on an FFT algorithm for acquisition and tracking on weak and high dynamic signals in deep space , can you give me some idea?

    • Taymaz:

      Thanks for visiting the CSP Blog.

      Can you elaborate on your request? For example, I can’t tell if your problem involves CSP or not. The signal that you might be tracking could be a simple time-varying sine wave, in which case CSP doesn’t have much to offer over Fourier analysis.

  9. Kevin says:

    Hi Chad

    On the extension to the conjugate spectral correlation function, you explained it based on the auto spectral correlation function. For the cross spectral correlation function x(t)!=y(t), is the conjugate spectral correlation function also calculated by input x(t) and conj(y(t)) using FAM?

    Thanks!
    K

  10. Kevin says:

    Got it. You actually used a frequency shifted BPSK rather than a baseband BPSK in this example.

    BTW, do you have any blogs on the FRESH filters?

    Thanks!
    K

  11. Kevin Burke says:

    Hi Chad,
    A minor typo: comparing (28) in [R4] to equation (1) above suggests there is a missing “equals” sign.
    Thanks, Kevin (A different one than the other posts)

    • Kevin Burke:

      Thanks for checking out the CSP Blog and taking the time to point out that typo! I really appreciate it. Please don’t hesistate to point out any others, here or via email. cmspooner at ieee dot org.

  12. Sunson211 says:

    Dear chad,

    Very nice tutorial here. Allow me to have a question here for normalization of SCF by using the equ 9 in the article. By using the example you first figure plot in this article, f is [-0.5 0.5]. Alpha is [0 0.7], Let’s assume I want to calucate the normalized scf button point (f= -0.5 , alpha = 0.7) by using equ 9. But the in the denominator, f – alpha/2 = -0.5 -0.35 = 0.85 !! Which is outside of range of f, right? The f is only between +-0.5 . So, could you advise me ? I think there is something I missed. Thank you so much for your time and help.

    • Sunson211 says:

      I saw sameone here asked the same question, and your reply is “In general, only use those pairs of frequencies f \pm \alpha/2 for which each frequency lies in [-0.5, 0.5), and ignore the rest.” if my understanding is right, are you saying, i only need to calculate the area if f +- alpha/2 are in [-0.5 0.5]? Could you advise me if I am wrong? Thanks

      • Yes, that’s right. The “principal domain” for the discrete-time/discrete-frequency spectral correlation function is a diamond with vertices (f, \alpha) = \{ (-0.5, 0), (0, 1.0), (0.5, 0), (0, -1.0) \}. Every point outside of that diamond is redundant with a point inside. Notice that that two-dimensional principal domain contains the normal DSP principal domain of [-0.5, 0.5].

        In your example of one comment back, you chose (f, \alpha) = (-0.5, 0.7), which is not in the principal domain. So you ended up trying to find the coherence denominator PSD values for frequencies that lie outside of the principal domain for frequencies [-0.5, 0.5].

        • sunson211 says:

          thank you so much for your help! It’s so helpful!!
          Chad, I have few following questions,

          1. The normalized SCF (equ 9) plot will be almost the same as original SCF (nominator of equ 9)? What I have now is really different. I got a simple 4QAM baseband orignal SCF, it looks like a peak in the middle of plot. After I did the normalization, I got 4 peaks near 4 corners of plot.
          please check the photo link. this is my first time sharing photo, let let me know it works or not.
          https://photos.app.goo.gl/sTdzwcq4QJbm5wUCA

          What i did in the code is,
          1. check the f +- alpha/2 are in the range of [-0.5 0.5] or not. If no, the current scf_norm = 0.
          2. if step 1 is no, then I just find out the current complex value of original scf (equ 9 nominator), then divided by the real number of denominator of equ 9 (the denominator is real number).
          3. then I do abs(equ 9), plot.

          Do you think my understanding is correct ? Thank you. Chad.

          • The posting of the images to Google Photos worked; I am able to see them.

            I don’t see any errors or problems with what you’ve written in your latest comment. However, can you tell me the noise power and the signal power that you used to generate your 4QAM signal? Or, even better, send me the data at cmspooner at ieee dot org.

        • sunson211 says:

          Dear Chad,

          Thank you again for your help. I will send the data and code to your ieee emai. Thank you again.!

  13. Chinmay Hegde says:

    Hello Dr. Spooner, thanks for the excellent blog. I had a question with regards to your comment about using a side PSD estimate that is highly oversampled in estimating the Coherence functions in (9) and (10). I interpreted that comment to mean that there is a very high sample rate channel for estimating the PSD and a lower sample rate channel for SCF estimation. Is this correct? If not then are you estimating a “finer resolution” PSD via zero-padding or some other form of interpolation? Thanks again!

    • Thanks for stopping by, Chinmay.

      I believe you can take the PSD estimate part of the FAM or SSCA output and interpolate it to create the highly oversampled PSD you need for the coherence calculation. But I typically estimate the PSD on the side, using the TSM or FSM. That gives me lots of control over the resolution and the amount of data that I want to use to make the estimate.

      I don’t need two channels–one very high rate and one low–it is just that the resolution of the FAM or SSCA PSD is very coarse. So the original-rate data sequence is just fine.

      • Chinmay Hegde says:

        Ah, ok that is what I did, although I didn’t interpolate the PSD portion of the FAM output. It worked, but I think this might be because I was grossly oversampled to begin with (simulated baseband sample rates of 80-200 MHz compared to baseband signal bandwidths on order of 5-20 MHz).

        I also tried computing coherence via a TSM and FSM estimate of the PSD with “finer resolution”, but this introduced more noise into the PSD estimate relative to the PSD portion of the FAM output which in turn resulted in coherence values that could be slightly > 1. (I was working with SNR of 0 dB). In general I didn’t always get coherence values that were 1?

        I never ran into the issue of coherence values > 1 when using the TSM or FSM methods (I basically looped over cycle-freqs that I wanted to check when using these methods). Although, in my TSM/FSM implementations I used complex phase shifts in the time domain prior to taking an FFT to compute the +/- alpha/2 freq. shifts required by the cyclic periodogram. As a result, I was taking 2 FFT’s per cycle-freq when computing the non-conjugate SCF via TSM/FSM which gave me “exact” PSD estimates every time I needed them. I was ok with computational burden since I just wanted something to double check my implementation of the FAM method. So far, everything is in agreement outside of the coherence values sometimes being > 1 in my FAM method. (I suspect this is user error on my part).

        Thanks again for your reply. And no worries if you are too busy to respond to my most recent queries, your blog has already saved me a lot of time as I try to wrap my head around this stuff.

  14. Chinmay Hegde says:

    Sorry, my previous post ended up getting screwed up when I posted. I meant to ask if it makes sense that one might get coherence values > 1 using the FAM method and a side estimate of PSD. I got coherence to be bounded by 1 when using the PSD portion of the FAM SCF but even then it depended on what freq resolution I used (0.5 MHz with 2^15 samples at 200 MHz worked perfectly, but other parameters still sometimes resulted in cohernce slightly > 1). The reason it was confusing to me was that it never happened using my TSM/FSM implementations as described above.

    Again, my comment about your relative business with regards to being able to answer still stands 🙂 Thanks!

    • I also get coherence magnitudes greater than 1 sometimes, with both the SSCA and the FAM. I think the reason is almost always that the PSD values used in the normalization of the estimated SCF are poorly resolved. That is, no non-parametric spectrum estimator (such as the TSM, FSM, SSCA, and FAM algorithms, focusing on \alpha=0) can adequately resolve certain kinds of spectra, such as those containing unit-step-function-like features or impulses. Moreover, when the input data contains little or no noise (as is possible in the world of simulated signals), the spectrum estimators are trying to estimate zero values, so the coherence quotient becomes ill conditioned. Finally, unlike the case of using the TSM or FSM and then computing the coherence, it is difficult to match the spectral resolution of the SSCA or FAM output with the spectral resolution of the side estimate.

      So in the end, the coherence quotient will sometimes be poorly estimated, and if the denominator PSD estimates are under estimated, then we’ll get too large of a coherence value relative to theory.

      Like spectrum analysis, CSP is a bit of an art, and a bit of a science.

      Comments?

      • Chinmay Hegde says:

        Ah, that is a huge relief to hear! I was convinced I must have done something wrong. Yeah everything you said makes sense to me.

        • sunson211 says:

          Hi Dr Hegde,

          May I have a quick question for you? I am working on this equ 9 for normalization SCF as well. But I got something I dont understand.
          Please check the plot here.
          https://photos.app.goo.gl/LiiT2tQtQNVjBS1x7

          the top one is just original SCF, the button one is the normalized one by using equ 9. However, as you seen, it really looks different from original one. I think this must be wrong. Could you give me some hints which could case this problem ? Btw. acutally, I may get value > 1 for normalized SCF, but I just make it = 0 right now….. Thanks.

          • Chinmay Hegde says:

            Hello sunson,

            Unfortunately I don’t think I can help you by looking at those images. Sorry.

            Btw, I actually don’t have a PhD so I’m just Mr. Hegde. Good luck with your work.

            -Chinmay

  15. MS says:

    Hi Chad,

    Thank you for the interesting post. I have a comment and a question.

    The comment is when I used a low value of N’ (say, 16), I get a coherence magnitude that is much greater than 1. Upon inspection, I see that the features from the FAM method is more smeared out than the features for the generated PSD, which I have tried using both the FSM and TSM methods. Due to the smearing, the coherence magnitude is much higher than 1 at these points. When I used N’ = 64, the features from the FAM method match the PSD better and the coherence magnitude is much better. Perhaps the poor resolution of the FAM can lead to erroneous coherence magnitudes.

    For the question, what is PFa and how is it used to calculate the threshold for the coherence?

    Thank you.

    • When you use the FAM to compute the coherence for small N^\prime, what is the relation between the parameters you use for the FAM and the parameters you use for the PSD estimation using either the TSM or FSM? And, crucially, what is the input?

      In general, low N^\prime in the FAM or SSCA will cause distortion over frequency for any cycle frequency because small N^\prime means large (coarse) spectral resolution. So the underlying theoretical feature (slice of the f-\alpha plane) is effectively convolved with some pulse-like function with approximate width 1/N^\prime. That tends to make the values of the spectral correlation function estimate smaller than implied by theory, therefore decreasing the numerator of the coherence. But the PSD estimate is also subject to that distortion, and it appears in the denominator. So, yeah, when N^\prime is small and especially when the processed block length is also small, you can get errors in the coherence. Happens to me too!

      In terms of thresholding the coherence function that is output by the FAM or SSCA, the probability of false alarm (PFA) is the desired probability that a particular point estimate of the coherence (that is, \hat{N}_x^\alpha(f)) has a magnitude that exceeds the threshold even when the corresponding \alpha is not a cycle frequency for the processed data. Take a look at The Literature [R64] to find an applicable formula involving the processing block length, the spectral resolution, and the desired PFA).

  16. MS says:

    I used a QPSK signal with a RRC pulse. I tried to make the spectral resolution of the FAM result and the PSD the same. For the FAM, I used N’ = 16. For the FSM, I had 8000 samples and a window length of 501, which gives a spectral resolution of 0.0626. Then I realized that I zero-padded the signal before doing the PSD estimate, so the spectral resolution is half that. So the lobe of the FAM estimate is wider than the lobe of the PSD estimate. This leads to the error in the coherence magnitude. This brings up another question, is there a guideline on choosing N’?

    Thank you for answering my question and for the reference.

    • I don’t think zero-padding affects spectral resolution, just frequency sampling of the PSD. The main lobe of your QPSK signal should be the same width in Hz for all zero-padding choices. The number of frequency samples in the PSD will increase by the zero-padding factor, but their separation decreases. So if you are plotting things and/or thinking in terms of samples, you’ll run into trouble. Try to think and compute in terms of Hz (I prefer normalized Hz, but physical Hz works too, you just have to carry around the sampling rate when you are doing calculations). For example, here are three FSM PSD estimates for rectangular-pulse BPSK with bit rate 1/10 and carrier offset frequency of 0.1:

      FSM PSDs with zero padding

      You can see the effect of zero padding is essentially interpolation. This also makes sense in terms of the natural units of the PSD, which are Watts/Hz. It doesn’t matter how many frequency samples are contained in some frequency interval, what matters is that the sum of the PSD values in that interval multiplied by the frequency separation of the samples (which just approximates the integral of the continuous-frequency PSD over that interval) is a constant no matter how finely you sample in frequency. Here is the TSM with zero-padding:

      TSM PSDs with zero padding

      Here each short TSM block is zero padded prior to combining.

      Regarding N^\prime, I rarely use anything less than 32 nor more than 256. The smaller N^\prime is, the larger the effective spectral resolution \Delta f is, and this helps keep the variance of the SCF estimate low, albeit at the expense of distorting the more narrow spectral features of the data under study.

      Agree?

      • MS says:

        I do agree with your statement. It’s not that the zero-padding affects the spectral resolution. What I meant was that the smoothing window in effect gets narrower in frequency due to the zero-padding. So if I had 8000 samples and a window length of 800 samples, the window length is 1/10 in normalized frequency. If I zero-pad to 16000 samples and the window length is still 800, the window length is 1/20 in normalized frequency. Is that right?

        Thanks.

        • Yes, I agree with that. Here is how I avoid that issue in practice: I always specify the width of the smoothing window as a percentage of the sampling rate. Then I use the length of the processed data block together with that specified spectral-resolution percentage, to compute the number of frequency points that span the window. What do you think?

          • MS says:

            It makes sense. That would avoid mentally recalculating the number of points I need for the window for different lengths of the data block. Thanks, Chad.

Leave a Reply