I'm a software engineer that has been given the task of calculating the SNR of a communications signal that is represented by an array of complex numbers. I'm not quite sure how to proceed.

Here's what I have as input data:

An array complex numbers of length $N$. This is the representation of the signal for which I need to calculate the SNR. Within this array, there is a "marker signal" of length $M$ (where $M < N$) that is of known shape (let's say it's a single cycle of a sin function). For sake of scale, let's say $N = 1000$ and $M = 100$.

After doing some research on SNR, I've clearly discovered that I'm in over my head; however, I've attempted to formulate an approach...for which I need expert critique. So here it is:

It seems to calculate SNR, I need to know what the signal is without the noise and separately the noise itself, i.e. I need to get a array of complex numbers that represent the signal without noise, and an array of complex numbers that represent the corresponding noise, such that if I add these two arrays together, I get the original signal.

The only way I know to separate the original signal array into the two parts described above is to know the shape of underlying signal. In this case, I do know that for the "marker signal" portion of the array. Thus my approach would be, assuming that an SNR calculation for the "marker signal" of length $M$ would provide a reasonable estimate for the entire sample of length $N$.

  1. Create an array of length $M$ from the "marker signal" portion of the original length $N$ array. I can do this because I know where the marker is suppose to be in the $N$ array. Let's call it $O$.
  2. Create an array of length $M$ that matches the known "marker signal" shape, i.e. a noiseless marker. Let's call it $S$.
  3. Generate an $M$-length noise array by simply subtracting $S$ from $O$. Let's call this $E$. It should hold an estimate of the noise that overlaid the "marker" portion of the original signal.
  4. Separately calculate the RMS of $S$ and the RMS of $E$
  5. Finally, calculate SNR as

$$\text{SNR} = 20\text{log}_{10}\bigg(\frac{S_{RMS}}{E_{RMS}}\bigg) $$

My specific questions are:

a) In general, is this approach correct for an SNR estimate? If not, do you have an advice on how to appropriately handle this situation?

b) when separating the noise from the raw signal, I'm a little concerned about the amplitude of my reference marker signal not being the same as the underlying signal in the raw data. It seems like some sort of normalization should be done, but I'm not sure how I would do that. For example, in the image below, the orange signal is the raw "marker signal" and the blue is the reference marker signal. As you can see, they have the same shape but different magnitudes, so simply subtracting the reference from the raw would give me something other than just the noise.

enter image description here



I'm providing a few more details of my situation in response to @Engineer.

I didn't mention in my original post that I am locating the reference marker within the raw signal by performing a correlation. So, the process is:

  1. capture a block of incoming samples. The number of samples is selected such that I'm sure that I'll have at least one marker within the block.

  2. slide a window across the block of samples, the width of which is the same as the marker signal, and calculate the correlation between the samples within the window and the samples from the reference marker signal using the following equation (I actually used a normalized form of the equation because I was worried about the possible amplitude mis-match):

enter image description here

  1. the result of the equation above is a complex number, so use the magnitude of this complex value as the actual correlation value. If I plot this for all window positions within the block of data, I get a plot similar that that below. NOTE: this plot is shows ideal conditions, with real data it is obviously much noisier than this.

enter image description here

With all that said, and trying to connect that with your response using my small mind, I have the following questions:

  1. Is $R_{xy}$ in your response the same as the peak correlation value that I'm calculating? If not, is it because I'm using a normalized form of this correlation calculation?

  2. To calculate $P_x$ and $P_y$, do I simply use the RMS equation?

  3. If I understand 1 and 2 above correctly, I would calculate SNR as:

enter image description here

Thanks again for taking the time to respond.

  • $\begingroup$ Your approach seems sound in principle. You are correct that both the reference and the noisy reference signals must have the same amplitude. $\endgroup$ – MBaz Jan 22 at 21:36
  • $\begingroup$ @MBaz - thanks for the feedback. $\endgroup$ – BryanG Jan 25 at 17:15

The method of subtracting the clean signal from the received signal is a good method and will work as long as the scaling is matched up. As an alternative, you can also try the cross-correlation method which takes care the of the amplitude estimate. This previous answer gives the basic idea, How to calculate time domain SNR using known sequence.

If $x(t)$ is the marker/reference signal, then the received signal is:


where $A$ is some attenuation factor, $\tau$ is some time delay, and $w(t)$ is the noise. The noise power is $\sigma_w^2=\mathbb{E}\big[|w(t)|^2\big]$, or equivalently by manipulating the above equation:

\begin{align} \sigma_w^2&=\mathbb{E}\big[|y(t)-Ax(t-\tau)|^2 \big] \\ &=\mathbb{E}\big[|y(t)|^2 \big]-2A\mathbb{E}\big[y(t)x^*(t-\tau) \big]+A^2 \mathbb{E}\big[|x(t-\tau)|^2 \big] \\ &= P_y - 2AR_{xy}(\tau)+A^2P_x \end{align}

where the last step assumes that $x(t)$ and $y(t)$ are jointly WSS. Another way to interpret the equation above is that if we choose the right $A$ and $\tau$, then that difference is zero except for the noise. This is like an optimization problem where we want to choose $A$ and $\tau$ to minimize the noise power. Seems weird to say that since you don't have control over the noise power, but the idea is that if you don't choose the $A$ and $\tau$ to minimize $\sigma_w^2$ then you'll be attributing some of the signal's power to the noise through the mismatch.

The variable $\tau$ only appears once and clearly you should choose the $\tau$ that maximizes the cross-correlation:

$$\hat{\tau}=\text{argmax}_{\tau} R_{xy}(\tau)$$

From the noise power equation you can take the derivative with respect to $A$, set equal to zero and solve to find that $A$ should be chosen to be:

$$ \hat{A} = \frac{R_{xy}(\hat{\tau})}{P_x} $$

Once you have $\hat{A}$, you have the estimate of the received signal power, $\hat{P}_{RX}=\hat{A^2}P_x$ (SNR numerator). Then plug $\hat{A}$ into the equation to find the noise power (SNR denominator):

\begin{align} \hat{\sigma}_w^2 &= P_y-2\hat{A}R_{xy}(\hat{\tau})+\hat{A^2}P_x \\ &= P_y - \frac{R^2_{xy}(\hat{\tau})}{P_x} \end{align}

Putting numerator over the denominator gives:

$$ \hat{\text{SNR}} = \frac{\hat{P}_{RX}}{\hat{\sigma}_w^2} $$


The definition of the cross correlation being used is not normalized in any way. If you want to normalize, you should be dividing by the length of the marker/reference signal $M$ (there will only be $M$ non-zero values anyways). When I say the power of a signal, I'm talking about summing up all of the magnitude squared values. Again, you can divide by $M$ if you want to as long as you're consistent there will be a factor of $\frac{1}{M}$ floating around that gets cancelled out everywhere so that is why I say "if you want to". So either divide the cross-correlation by $M$ and compute the powers as $\frac{1}{M} \sum |.|^2$, or don't divide by anything and compute the powers as $\sum |.|^2$.

  • $\begingroup$ please see edits in my original post $\endgroup$ – BryanG Jan 25 at 18:45
  • $\begingroup$ @BryanG thanks, I have added some clarification that hopefully helps $\endgroup$ – Engineer Jan 25 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.