% patternnet_demo.m
% Use the Matlab function to classify the XOR pattern data. 
% The activation function of each neuron is a sigmoid function
% 
% David Pan, UAH 

clear all;
close all;

% Linearly separable example (requiring a small number of epochs)
% 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 (with XOR pattern)
% Input data pattern
X = [1 -1 -1 1; 1 -1 1 -1];
% Repeat X for training, validation and testing
X_repeat = repmat(X, 1, 3);
% Response
R = [1  1  0 0; 0 0  1  1];
R_repeat = repmat(R, 1, 3);

rng('default');
% net = feedforwardnet(2);
net = patternnet(2);

% Gradient descent backpropagation
net.trainFcn = 'traingd';

net.performFcn = 'mse';

net.layers{1}.transferFcn = 'logsig';
% The default output layer uses softmax transfer function
%net.layers{2}.transferFcn = 'softmax';


% Maximum number of epochs to train
net.trainParam.epochs = 1000000;

% Learning rate (default = 0.01)
net.trainParam.lr  = 0.5;

% Separates targets into three sets: 
% training, validation, and testing, 
% according to indices provided

net.divideFcn = 'divideind';
net.divideParam.trainInd = 1:4;
net.divideParam.valInd = 5:8;
net.divideParam.testInd= 9:12;

% Train the network
net = train(net, X_repeat, R_repeat);

% Verify the output using the weights and biases learned by net
final_output = zeros(2, 4);

for i = 1: 4
    A1 = X(:,i);
    W2 = cell2mat(net.IW);
    b2 = net.b{1};
    Z2 = W2*A1 + b2;
    
    % Hidden layer uses sigmoid transfer function
    %A2 = 1./(1+exp(-Z2));
    A2 = logsig(Z2);

    W3 = cell2mat(net.LW(2));
    b3 = net.b{2};
    
    Z3 = W3*A2 + b3;

    % The output layer uses softmax transfer function
    A3 = softmax(Z3);
  
    final_output(:,i) = A3;
end

final_output

% Compared to the desired response
R

% Scatter plot of the classified regions

figure;
hold on;
for x1 = -1.5:0.05:1.5
    for x2 = -1.5:0.05:1.5
        X_test = [x1; x2];
        y = sim(net, X_test);
        
        if (y(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),'ro','MarkerSize',12, 'MarkerFaceColor','r');
plot(X(1,3),X(2,3),'bo','MarkerSize',12, 'MarkerFaceColor','b');
plot(X(1,4),X(2,4),'bo','MarkerSize',12, 'MarkerFaceColor','b');


   