Signal averaging

Signal averaging is a signal processing technique applied in the time domain, intended to increase the strength of a signal relative to noise that is obscuring it. By averaging a set of replicate measurements, the signal-to-noise ratio (SNR) will be increased, ideally in proportion to the square root of the number of measurements.

Deriving the SNR for averaged signals

Assumed that

  • Signal is uncorrelated to noise, and noise is uncorrelated : .
  • Signal power is constant in the replicate measurements.
  • Noise is random, with a mean of zero and constant variance in the replicate measurements: and .
  • We (canonically) define Signal-to-Noise ratio as .

Noise power for sampled signals

Assuming we sample the noise, we get a per-sample variance of

.

Averaging a random variable leads to the following variance:

.

Since noise variance is constant :

,

demonstrating that averaging realizations of the same, uncorrelated noise reduces noise power by a factor of , and reduces noise level by a factor of .

Signal power for sampled signals

Considering vectors of signal samples of length :

,

the power of such a vector simply is

.

Again, averaging the vectors , yields the following averaged vector

.

In the case where , we see that reaches a maximum of

.

In this case, the ratio of signal to noise also reaches a maximum,

.

This is the oversampling case, where the observed signal is correlated (because oversampling implies that the signal observations are strongly correlated).

Time-locked signals

Averaging is applied to enhance a time-locked signal component in noisy measurements; time-locking implies that the signal is observation-periodic, so we end up in the maximum case above.

Averaging odd and even trials

A specific way of obtaining replicates is to average all the odd and even trials in separate buffers. This has the advantage of allowing for comparison of even and odd results from interleaved trials. An average of odd and even averages generates the completed averaged result, while the difference between the odd and even averages, divided by two, constitutes an estimate of the noise.

Algorithmic implementation

The following is a MATLAB simulation of the averaging process:

N=1000;   % signal length
even=zeros(N,1);  % even buffer
odd=even;         % odd buffer
actual_noise=even;% keep track of noise level
x=sin(linspace(0,4*pi,N))'; % tracked signal
for ii=1:256 % number of replicates
    n = randn(N,1); % random noise
    actual_noise = actual_noise+n;
    
    if (mod(ii,2))
        even = even+n+x;
    else
        odd=odd+n+x;
    end
end

even_avg = even/(ii/2); %even buffer average 
odd_avg = odd/(ii/2);   % odd buffer average
act_avg = actual_noise/ii; %actual noise level

db(rms(act_avg))
db(rms((even_avg-odd_avg)/2))
plot((odd_avg+even_avg)); 
hold on; 
plot((even_avg-odd_avg)/2)

The averaging process above, and in general, results in an estimate of the signal. When compared with the raw trace, the averaged noise component is reduced with every averaged trial. When averaging real signals, the underlying component may not always be as clear, resulting in repeated averages in a search for consistent components in two or three replicates. It is unlikely that two or more consistent results will be produced by chance alone.

Correlated noise

Signal averaging typically relies heavily on the assumption that the noise component of a signal is random, having zero mean, and being unrelated to the signal. However, there are instances in which the noise is not uncorrelated. A common example of correlated noise is quantization noise (e.g. the noise created when converting from an analog to a digital signal).

gollark: ```perl# lyricly, utterly: ''=~('('.'?'.'{'.('`'|'['^'-').('`').('`'|',').'"'.('`'|'&').('`'|'/').('['^')').'('.'\\'.'$'.('`'|')').'='.('^'^('`'|'.')).';'.'\\'.'$'.('`'|')').'<'.'\\'$'.^'(').';'.'\\'.'$'.('`'|')').'+'.'+'.)'.\\'.'{'.('`'|'&').('`'|'/').('['^')').'('.'\\'.'$'.('`'|'*').'='.('^'^('`'|'.')).';'.'\\'.'$'.(|'*').'<'.\'.'$'.('['^'(').';'.'\\'.'$'.('`'|'*').'+'.'+'.')'.'\\'.'{'.('`'|'-').('^'"').'\\'.'$'.('['/').';'.'\\'.'$'.('['^'/').'+'.'='.'\\'.'$'.('`'|'!').'['.'\\'.'$'.('`'|')').']'.'['.'\\'.'$'.'_'.']'..'\\'.'$'.(''|'"').'[\'.'$'.'_'.']'.'['.'\\'.'$'.('`'|'*').']'.('`'|'&').('`'|'/')['^')').'('.('^'^('`'|'.')).'.'.'.'.'\\'.'$'.('(').')'.';'.('['^'+').('['^')').('`'|')').('`'|'.').('['^'/').'\\'.'$'.('['^'/').'.'."'".('{'^'[')."'".';'.'\\'.'}'.('['^'+')['^')').('`'|')').('`'|'.').('['^'/').'\\'.'"'.'\\'.'\\'.('`'|'.').'\\'.'"'.';'\'.'}'.'"'.'}'.')')```
gollark: I assume it also extracts extra code from one of the "insult" lines.
gollark: This is pythonoforms from my entry.
gollark: It doesn't even bother to add newlines!
gollark: ```pythonclass Entry(ℝ): def __init__(self, Matrix=globals()): M_ = collections.defaultdict(__import__("functools").lru_cache((lambda _: lambda: -0)(lambda: lambda: 0))) M_[0] = [*map(lambda dabmal: random.randint(0, len(Row)), range(10))] for self in repr(aes256): for i in range(ℤ(math.gamma(0.5)), ℤ(math.gamma(7))): print(" #"[i in M_[0]], end="") M_[1] = {*lookup[10:]} for M_[3] in [ marshal for t in [*(y for y in (x for x in map(lambda p: range(p - 1, p + 2), M_[0])))] for marshal in t ]: M_[4] = (((M_[3] - 1) in M_[0]) << 2) + ((M_[3] in M_[0]) << 1) + ((M_[3] + 1) in M_[0]) if (0o156&(1<<M_[4]))>>M_[4]: M_[1].add(M_[3]) M_[0] = M_[1] pass passpass```Sheer elegance.

References

    This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.