# Adaptive filter with two inputs

I have general theoretical questions:

• Is it true that an adaptive filter with two inputs (one normal and one delayed by the single time increment) can completely get rid of any single frequency noise?
• Is it then true that a three-input adaptive filter can (completely) get rid of a noise consisting of two harmonics, etc.?

Maybe there is a theorem for this, any pointers would be appreciated.

• Consider a delay line of length T seconds; A sine wave of frequency 1/T will have gone 360° after it has gone through the delay line. If the output of the delay line was subtracted from the signal (of same magnitude) prior to the delay, it would completely cancel that particular frequency. Similarly, all the following frequencies would also have delayed 360° in this delay line: 2/T, 3/T, 4/T... etc and therefore would also cancel. Such a filter is known as a "comb filter" as it combs out specific frequency components. There's more details to this, let me know if this is on the right path. Jun 19 '16 at 3:07
• Thanks for your reply. My question was actually about any frequency, not only of the form k/T. Basically, I was going through the book Neural Network Design (hagan.okstate.edu/nnd.html) and on pages 323-326 he s Jun 19 '16 at 3:21
• I see--- I think that is an area that is a bit beyond me, but sounds interesting! I'll be watching, hopefully someone can answer. Jun 19 '16 at 3:26
• Thanks for your reply. In my question I was actually asking about arbitrary frequency, not only of the form k/T. Basically, I was going over the book Neural Network Design (hagan.okstate.edu/nnd.html) and on pages 323-326 they explicitly solve/design an adaptive filter for a phase shifted single frequency noise (frequency is 1/3T) . It is kind of counterintuitive that a linear combination can filter out a harmonic function, but apparently it works. Sorry for the double post. Jun 19 '16 at 3:31
• Yes that would be due to what I described; a frequency of 1/(3T) can be cancelled by delaying by 1/(3T) and subtracting---isn't that a linear combination filtering out a specific frequency? Jun 19 '16 at 3:43

I've had a look at the problem in the book you've cited (Figure 10.7, Adaptive Filter for Noise Cancellation). As Dan has stated, a linear combination can filter out a specific frequency, but it depends on the specific noise frequency, the sample rate, and the length of the adaptive filter delay-line (i.e. the number taps or weights used in the adaptive filter).

In general, however, a given adaptive filter arrangement used for noise cancellation (i.e. sample rate, length of delay-line, adaptive algorithm) will dictate what specific frequencies of the noise will be attenuated.

• Hmmm, so you don't think arbitrary (single) frequency noise can be filtered out by a two-input filter with a given sample rate (which would mean the answer to my original question is no)? In the book, I didn't see anything special about their configuration for sample rate/noise frequency, but they do filter out the noise completely with the filter sin(wt)/sqrt(3)+2*sin(w(t-1))/sqrt(3) Jun 22 '16 at 3:11
• I have written a short Matlab script-file to demonstrate the idea. I will post it later today or tomorrow. Jun 30 '16 at 13:18

In general case, to fully filter out a noise consisting of $N$ (arbitrary) harmonics, one needs an adaptive filter with length (number of taps) of at least $2N$.

Here is a script-file that simulates the problem:

function [] = noise_cancellation()

%% Signals

close all; clear all; clc; set(0, 'DefaultFigureWindowStyle', 'normal');

fs=180; signal_length=40e3;
rng('default');  h_eeg = @(signal_length) -0.2 + (0.4).*rand(1, signal_length);

f=60;
h_noise_source = @(indices, f, fs) 1.2 .* sin(2.*pi.*f./fs.*indices);
h_noise_contaminate = @(indices, f, fs) 0.12 .* sin(2.*pi.*f./fs.*indices + pi/2);

eeg_signal = h_eeg(signal_length);
noise_signal = h_noise_source(1:signal_length, f, fs);

tapNumber=2; stepSize=0.0005;

desired=eeg_signal_contaminated;  reference=noise_signal;

[ tapWeights, error ] = LMS_MRW( stepSize, tapNumber, reference, desired );

sqrt( mean(eeg_signal(500:end).^2) );
sqrt( mean(error(500:end).^2) );

figure;
plot(1:length(reference), error, 'r'); hold on; plot(eeg_signal, 'b');
grid on; xlim([1 numel(error)]);
title('Filtered Noisy EEG Signal and Clean EEG Signal');
xlabel('Index'); ylabel('Amplitude (unitless)'); legend('Filtered Noisy EEG Signal', 'Clean EEG Signal');

h = tapWeights(:, end);

figure;
plot(tapWeights'); grid on; xlim([1 numel(error)]);
title('Filter Tap-weight Convergence Curves');
xlabel('Index'); ylabel('Tap-weights (unitless)'); legend(['Tap 1 -> ' num2str(h(1))], ['Tap 2 -> ' num2str(h(2))]);

figure; spectrogram(eeg_signal, 128, 100, 256, fs); caxis([-122 -21]); colorbar; title('EEG Signal (desired)');
figure; spectrogram(eeg_signal_contaminated, 128, 100, 256, fs); caxis([-122 -21]); colorbar; title('Noise Contaminated EEG Signal (reference)');
figure; spectrogram(error, 128, 64, 256, fs); caxis([-122 -21]); colorbar; title('Recovered (target)');

end

function [tapWeights, error] = LMS_MRW(stepSize, tapNumber, reference, desired)

tapWeights = zeros(tapNumber, length(desired));
inputVector = zeros(tapNumber, 1);

for updateIndex = 1:1:length(reference)

inputVector(1) = reference(updateIndex);

filterOutput = inputVector'*tapWeights(:, updateIndex);

error(updateIndex) = desired(updateIndex) - filterOutput;

tapWeights(:, updateIndex + 1) = tapWeights(:, updateIndex) + stepSize*inputVector*error(updateIndex);

for inputVectorIndex = length(inputVector):-1:2
inputVector(inputVectorIndex) = inputVector(inputVectorIndex - 1);
end;

end;

end;


The adaptive algorithm used is the LMS with a step-size of 0.0005. The step-size is noticeably smaller and perhaps an extreme value compared to the value of 0.01 stated in the example. However, by using such a small step-size, we can readily see the convergence of the tap-weights and the gradual reduction of the 60 Hz noise in the discrete-time domain.  The reduction of the 60 Hz noise can also be seen by examining the signals using spectrograms. Here are three spectrograms for the EEG signal prior to degradation by the 60 Hz noise, the contaminated EEG signal, and finally the recovered EEG signal with the 60 Hz noise removed by the adaptive filter.   In the third figure, you can readily see the 60 Hz noise being gradually removed by the adaptive filter.

Finally, if you followed the computation of the autocorrelation matrix, R, and the cross-correlation vector, h, you could compute the tap-weight vector, x. The simulation gives values x(1) = -0.0571 and x(2) = - 0.1158, which are close to the theoretical values of -0.0578 and -0.1156, respectively.

If you set the "desired" variable to "noise_added" and "reference" to "noise_signal", the EEG signal is not included, you can remove the 60 Hz tone entirely, as shown by the red curve in the time-domain plot. See the plot below. Again you can see the 60 Hz noise being attenuated. The step-size was kept at 0.0005.

When the EEG signal is present, however, the 60 Hz noise is reduced, but not entirely eliminated. The third spectrogram shown above is based on a step-size of 0.0005, so the error due to the 60 Hz noise appears to be eliminated after the tap-weights of the filter have converged. However, if the step-size is made larger, say to 0.05, the error is readily seen in the spectrogram. 