% T-61.3030 Principles of Neural Computing
%
% Matlab demo
%
% 2007-04-13

%% Generate data
Ndat=100;
x=[0:8/(Ndat-1):8];
a=0.1;
y=sin(x)./(x+a);
t=y+0.1*randn(size(y));

figure
plot(x,y,'-b',x,t,'k.');
legend('y','t')

%% Divide data to a training set and testing set
rind=randperm(Ndat);
x_train=x(rind(1:Ndat/2));
t_train=t(rind(1:Ndat/2));
x_test=x(rind(Ndat/2+1:Ndat));
t_test=t(rind(Ndat/2+1:Ndat));

figure
plot(x_train,t_train,'bo',x_test,t_test,'ro');
legend('Training data','Test data')

%% Construct a new MLP (fead forward) network

% net = newff(PR,[S1 S2...SNl],{TF1 TF2...TFNl},BTF,BLF,PF)
% PR - R x 2 matrix of min and max values for R input elements.
% Si - Size of ith layer, for Nl layers.
% TFi - Transfer function of ith layer, default = 'tansig'.
% BTF - Backpropagation network training function, default = 'traingdx'.
% BLF - Backpropagation weight/bias learning function, default = 'learngdm'.
% PF - Performance function, default = 'mse'.

%number of hidden neurons N
N=8;

net=newff([min(x_train),max(x_train)],[N 1],{'tansig' 'purelin'},'traingdm','learngd','mse');

%% Initialize weights to a small value
% Hidden layer (input) weights
net.IW{1,1}
net.IW{1,1}=0.001*randn([N 1]);
net.IW{1,1}

% Output layer weights
net.LW{2,1}
net.LW{2,1}=0.001*randn([1 N]);
net.LW{2,1}

% Biases
net.b{1,1}=0.001*randn([N 1]);
net.b{2,1}=0.001*randn;

%% Train network

%train(NET,P,T,Pi,Ai,VV,TV) takes,
%     net - Neural Network.
%     P - Network inputs.
%     T - Network targets, default = zeros.
%     Pi - Initial input delay conditions, default = zeros.
%     Ai - Initial layer delay conditions, default = zeros.
%     VV - Structure of validation vectors, default = [].
%     TV - Structure of test vectors, default = [].

net.trainParam.epochs = 100000;
net.trainParam.goal = 0.01;

[net,tr,Y,E]=train(net,x_train,t_train)
[xtr, tr_ind]=sort(x_train);
xts=sort(x_test);

%simulate the output of test set
Ytest=sim(net,xts);

%% Plot the results for training set and test set
figure
plot(x,y,'-k',xts,Ytest,'-g',x_train,t_train,'bo',x_test,t_test,'ro');
legend('y','ytest','Training data','Testing data')
