You are on page 1of 6

function [iter,error]=lms(inp,h,N,L,plot_flag)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Least mean squares (LMS) algorithms are a class of adaptive filter used to
%mimic a desired filter by finding the filter coefficients that relate to %
%producing the least mean squares of the error signal (difference between %
%the desired and the actual signal)
%
%
%
% The weights update Formula for every Iteration is
%
% Wt new=Wt old + mu * error *input
%
%
%
%For Example:
%
%inp=wavread('BlueFunk-bass1.wav');
%
%inp=inp-(min(inp)); % required for audio signals
%
%h=[1 -4 6 -5 2]; % Known System papametes for a low Pass filter h,
%
%Iter=lms(inp,h,100,5,1);
%
%
%
%Author:Santhana Raj.A
%
%https://sites.google.com/site/santhanarajarunachalam/
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Initialaisation
W=zeros(N,L);
E=zeros(N,L);
iter=0;
for i=1:N
x=inp((i-1)*L+1:(i-1)*L+L); % select L no of inputs as ith Set
X(:,i)=x;
d= h'.*x;
y=d+randn(L,1)*0.1;

%Actual Output
%Output with noise

w=W(i,:);
mu=0.5;

% weights for this Iteration


% Learning Factor - in LMS algo

e = d - w'.*x;
wt_up=mu*(e.*x)';
W(i+1,:)=w+wt_up;

% Calculate error
% find the weight Update
% Set the new Weights

% Saving Iteration Values


E(i,:)=e;
if (mean(E(i,:))<=0.1 && iter==0) || (i==N && iter==0)
iter=i;
end
Y(i,:)=y;
end
yd = W(N+1,:)'.*x; % Caluculate Output from Identified System for an input
error=mean(E(i,:));
if plot_flag==1
subplot(121),plot([1:L],y),xlabel('Samples'), ylabel('System Output'),title('Actual
System'),
subplot(122),plot([1:L],yd),xlabel('Samples'), ylabel('System Output'),title
('Identified System');

figure();plot([1:N],mean(E,2)'),xlabel('No of Iterations'), ylabel('Mean


error'),title('Learning Curve');
end
end

function [w_out mse_out ref_out] = LMS(FIR_A,FIR_B,L,wave)


% [w mse ref res iter] = LMS(FIR_A,FIR_B,L,wave)
% LMS filter to solve the system identification problem represented below:
%
%
------------------%
------- FILTER A -----out_A----- FILTER X ---out-%
|
------------------|
% in |
|
% ----|
|+
%
|
---------- ----%
------- FILTER B -----out_B-------------------- SUM ---error--%
-------------%
% FILTER_X is unknown and to be derived. This problem is called "filter matching"
% and is encountered when one needs to augment a certain filter (A)
% in order to match the behavior of a reference filter (B).
%
% Parameters have the following significance:
%
FIR_A: impulse response (taps) of FILTER_A as a column vector
%
FIR_B: impulse response of FILTER_B as a column vector
%
L:
number of weights in the unknown filter
%
wave:
reference waveform. Available options:
%
('square', 'triangle', 'noise', 'chirp', 'multiburst')
%
% The outputs have the following significance:
%
w_out:
weights of the unknown filter
%
mse_out:
evolution of the mse with iterations
%
ref_out:
input (reference) signal
%------------------------------------------------------------------------% constants
mu = 10^-5;

% learning rate

% parameters for the reference signal


n_samples = 20000;
% number of samples in the reference signal
periods = 10;
% number of periods in the input square signal
signal_amplitude = 10; % amplitude of the reference signal
lead_border = 500;
% skipped samples at the beginning
lag_border = 500;
% skipped samples in the end
samples_per_period = int32(n_samples / periods);

% parameters specific to the square wave


duty_cycle = 0.7;
% duty-cycle for the square wave input
% parameters specific to the triangular wave
skewness = 0.7;
% skewness of the triangular wave
% parameters specific to the periodic chirp signal
T0 = samples_per_period / 4;
% initial period in samples
Tf = samples_per_period / 40; % final period in samples
% parameters specific to the multiburst signal
flat_line = samples_per_period / 5; % samples spent on flat region that separates the
bursts
% preliminary steps
fir_A = double(FIR_A);
fir_B = double(FIR_B);
[len_Ay len_Ax] = size(fir_A);
[len_By len_Bx] = size(fir_B);
len_A = max(len_Ax,len_Ay);
len_B = max(len_Bx,len_By);
if len_Ax > len_Ay
fir_A = fir_A';
end
if len_Bx > len_By
fir_B = fir_B';
end
max_len = max(len_A, len_B);
% normalize filters
fir_A = double(fir_A)/double(sum(fir_A));
fir_B = double(fir_B)/double(sum(fir_B));
% generate the input reference signal.
in = zeros(n_samples,1);
% avoid division by zero in the triangular wave case
if skewness == 1
skewness = 1.0-1.0/samples_per_period;
end
if strcmp(wave,'square')
samples_per_high = int32(samples_per_period * duty_cycle);
for i=1:n_samples
local_idx = mod(i,samples_per_period);
if local_idx < samples_per_high
in(i)= signal_amplitude;
end
end
elseif strcmp(wave,'triangle')
samples_per_ascending_front = samples_per_period * skewness;
for i=1:n_samples
local_idx = mod(i,samples_per_period);
if local_idx < samples_per_ascending_front
in(i)= signal_amplitude * double(local_idx) / ...
double(samples_per_ascending_front);
else
in(i) = double(signal_amplitude) * double(samples_per_period - local_idx)/
...

double(samples_per_period - samples_per_ascending_front);
end
end
elseif strcmp(wave,'noise')
in = signal_amplitude * randn(n_samples,1);
elseif strcmp (wave, 'chirp')
for i=1:n_samples
local_idx = mod(i,samples_per_period);
T = T0 - double(local_idx) * double(T0 - Tf)/double(samples_per_period);
in(i) = double(signal_amplitude) * sin(2 * pi / double(T) * double(local_idx));
end
else
display('Unknown waveform option');
end
% generate signals; This step can be replaced with canned convolution
% but one must be careful about misalignment when filters have unequal lengths
out_A = zeros(n_samples,1);
out_B = zeros(n_samples,1);
for i=1:n_samples
s = 0;
for j=1:len_A
signal_idx = min(n_samples,max(1,i+j-1-int32(len_A/2)));
kernel_idx = j;
s = s + in(signal_idx) * fir_A(kernel_idx);
end
out_A(i,1)=s;
end
for i=1:n_samples
s = 0;
for j=1:len_B
signal_idx = min(n_samples,max(1,i+j-1-int32(len_B/2)));
kernel_idx = j;
s = s + in(signal_idx) * fir_B(kernel_idx);
end
out_B(i,1)=s;
end
% make sure we leave enough samples near the borders
lead_border = max( lead_border, L);
lag_border = max(lag_border, L);
% initialize iterations
w = zeros(L,1);
mse = zeros(n_samples,1);
iter = 0;
% main iteration of the LMS algo
for k=lead_border:n_samples - lag_border
iter = iter + 1;
y = 0;
for i=1:L
y = y + out_A(k+i) * w(i);
end
error = out_B(k+int32(L/2+1)) - y;
mse(k) = error * error;
lr = 2 * mu * error;
% weight update
for i=1:L

w(i) = w(i) + lr * out_A(k+i);


end
end
w_out = w;
ref_out = in;
mse_out = mse;

clc;
clear all;
close all;
x = randn(1,1000);
% Input to the filter
b = fir1(31,0.5);
% FIR system to be identified
n = 0.1*randn(1,1000); % Observation noise signal
d = filter(b,1,x)+n; % Desired signal
mu = 0.008;
% LMS step size.
ha = adaptfilt.lms(32,mu);
[y,e] = filter(ha,x,d);
subplot(2,1,1); plot(1:1000,[e.^2]);
title('System Identification of an FIR Filter');
legend('Error');
xlabel('Time Index'); ylabel('Signal Value');
subplot(2,1,2); stem([b.',ha.coefficients.']);
legend('Actual','Estimated');
xlabel('Coefficient #'); ylabel('Coefficient Value');

grid on;

clc
clear all
close all
%%%Training using LMS - Algorithm
n = input('enter number of filter co-efficents:'); %%%Order of the filter, Second order
filter means Three coefficents..
x = rand(1,10000) - 0.5; %%%input samples
S = var(x); %signal Power
SNR = 30; %SNR = input('enter SNR');
Noise_amp = sqrt(S/(10^(SNR/10)));
Noise_sample = Noise_amp*rand(1,length(x));
h = rand(1,n) %%% Known filter coefficents
h1 = toeplitz([x(1) zeros(1,n-1)],x); %% toeplitz matrix to enable dealy inputs
h2 = rand(1,n); %%% unknown filter initial values

for i = 1 : length(x)
d(i) = sum(h1(:,i).*h')+Noise_sample(i);
y(i) = sum(h1(:,i).*h2');
h2 = h2 + 2*0.005*(d(i) - y(i))*h1(:,i)';
end
h2
%%testing
a1= rand(1,10) - 0.5;
h11 = toeplitz([a1(1) zeros(1,n-1)],a1);
for j = 1:10
d1(j) = sum(h11(:,j).*h');
y1(j) = sum(h11(:,j).*h2');
end
plot(d1)
hold on
plot(y1,'*r')

You might also like