% single_layer.m
% Explain the LMSE algorithm using a fully connected neural
% network with only one layer, which is the output layer. 
% The weights and biases are updated for each input sample

% David Pan, UAH 

clear all;
close all;

alpha = 0.1;  % learning rate

% Linearly separable example
% Input data pattern
X = [1 -1 -1 1; 1 -1 1 -1];
% Response
R = [1  0  1 0; 0  1 0  1];

% Linearly non-separable example
% Input data pattern
%X = [1 -1 -1 1; 1 -1 1 -1];
% Response
%R = [1  1  0 0; 0 0  1  1];

rng('default');
Std = 0.02;

% Initial weights and biases
W2 = Std*randn(2,2);
b2 = Std*randn(2,1);

max_iter = 100;
mse = zeros(1, max_iter);

epoch = 0;
while (epoch <= max_iter)
    for i = 1: 4
        epoch = epoch + 1;
        A1 = X(:,i);
        A2 = W2*A1 + b2;
       
        D2 = A2 - R(:,i);
        mse(epoch) = 0.5*norm(D2)^2;
        
        % Update the weights and biases
        W2 = W2 - alpha*D2*A1';
        b2 = b2 - alpha*D2;    
    end
        
end
mse(epoch)
plot(mse); grid

figure; hold on;
% Visualize the classifer performance
for x1 = -1.5:0.05:1.5
    for x2 = -1.5:0.05:1.5
        X_test = [x1; x2];
        A1 = X_test;
        A2 = W2*A1 + b2;
      
        if (A2(1)>=0.5)
            plot(x1, x2, 'r.');
        else
            plot(x1, x2, 'b.');
        end
    end
end
        
plot(X(1,1),X(2,1),'ro','MarkerSize',12, 'MarkerFaceColor','r');
plot(X(1,2),X(2,2),'bo','MarkerSize',12, 'MarkerFaceColor','b');
plot(X(1,3),X(2,3),'ro','MarkerSize',12, 'MarkerFaceColor','r');
plot(X(1,4),X(2,4),'bo','MarkerSize',12, 'MarkerFaceColor','b');

