% Solve an Input-Output Fitting problem with a Neural Network
% Script generated by Neural Fitting app
% Created By @Nastaran
%
% This script assumes these variables are defined:
%
%   x - input data.
%   y - target data.
clc;
clear;
close all;

x=linspace(0,2*pi,40);
y=sin(x);

x = x;
t = y;

% Choose a Training Function
% For a list of all training functions type: help nntrain
% 'trainlm' is usually fastest.
% 'trainbr' takes longer but may be better for challenging problems.
% 'trainscg' uses less memory. Suitable in low memory situations.
%trainFcn = 'trainlm';  % Levenberg-Marquardt backpropagation.

% Create a Fitting Network
hiddenLayerSize = [3 4];
TF={'logsig','tansig','purelin'};
net = newff(x,t,hiddenLayerSize,TF);

net.trainFcn = 'trainlm';

% Choose Input and Output Pre/Post-Processing Functions
% For a list of all processing functions type: help nnprocess
net.input.processFcns = {'removeconstantrows','mapminmax'};
net.output.processFcns = {'removeconstantrows','mapminmax'};

% Setup Division of Data for Training, Validation, Testing
% For a list of all data division functions type: help nndivide
net.divideFcn = 'dividerand';  % Divide data randomly
net.divideMode = 'sample';  % Divide up every sample
%'time' if dynamic Network
%'sampletime' to divide targets by both sample and time step
%'all' to dive up targets by every scaler value
%'none' not divide up data at all
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;

% Choose a Performance Function
% For a list of all performance functions type: help nnperformance
net.performFcn = 'mse';  % Mean Squared Error

% Choose Plot Functions
% For a list of all plot functions type: help nnplot
net.plotFcns = {'plotperform','plottrainstate','ploterrhist', ...
   'plotregression', 'plotfit'};

%changing trainParam
net.trainParam.showWindow=true; 
net.trainParam.showCommandLine=false;
net.trainParam.show=10;
net.trainParam.epochs=100;
net.trainParam.goal=1e-3;


% Train the Network
[net,tr] = train(net,x,t);

% Test the Network
y = net(x);
e = gsubtract(t,y);
%performance = perform(net,t,y)

% Recalculate Training, Validation and Test Performance
%training
trainIndx=find(~isnan(tr.trainMask{1}));
trainInputs = x(:,trainIndx);
trainTargets = t(:,trainIndx);
trainOutputs = y(:,trainIndx);
trainErrors=trainTargets-trainOutputs;

%Validation
valIndx=find(~isnan(tr.valMask{1}));
valInputs = x(:,valIndx);
valTargets = t(:,valIndx);
valOutputs = y(:,valIndx);
valErrors=valTargets-valOutputs;

%testing
testIndx=find(~isnan(tr.testMask{1}));
testInputs = x(:,testIndx);
testTargets = t(:,testIndx);
testOutputs = y(:,testIndx);
testErrors=testTargets-testOutputs;

%trainPerformance = perform(net,trainTargets,y);
%valPerformance = perform(net,valTargets,y);
%testPerformance = perform(net,testTargets,y);

% View the Network
%view(net)

% Plots
% Uncomment these lines to enable various plots.
%figure, plotperform(tr);
%figure, plottrainstate(tr);
figure, ploterrhist(trainErrors,'Train Err',valErrors,'Validation Err',testErrors,'Test error');
figure, histfit(trainErrors,10);
figure, plotregression(t,y);
%figure, plotfit(net,x,t)

% Deployment
% Change the (false) values to (true) to enable the following code blocks.
% See the help for each generation function for more information.
if (false)
    % Generate MATLAB function for neural network for application
    % deployment in MATLAB scripts or with MATLAB Compiler and Builder
    % tools, or simply to examine the calculations your trained neural
    % network performs.
    genFunction(net,'myNeuralNetworkFunction');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a matrix-only MATLAB function for neural network code
    % generation with MATLAB Coder tools.
    genFunction(net,'myNeuralNetworkFunction','MatrixOnly','yes');
    y = myNeuralNetworkFunction(x);
end
if (false)
    % Generate a Simulink diagram for simulation or deployment with.
    % Simulink Coder tools.
    gensim(net);
end
