% lolimotDemo4 Demo 4. Dynamic process of second order with 1 input and 1 output

% LoLiMoT - Nonlinear System Identification Toolbox
% Torsten Fischer, 20-October-2011
% Institute of Mechanics & Automatic Control, University of Siegen, Germany
% Copyright (c) 2012 by Prof. Dr.-Ing. Oliver Nelles


% Training
lolimotObject = lolimot;                                   % initialize lolimot object

load hammersteinT.mat                                      % Data for training

% The training data was created with the input signal stored in inputSequence1.mat
% which contains steps and an amplitude-modulated pseudo random binary signal covering
% the complete operating range.
% The process to be modeled has the following dynamics:
% y(k) = 0.1044*atan(u(k-1)) + 0.0883*atan(u(k-2)) + 1.4138*y(k-1) - 0.6065*y(k-2);

lolimotObject.input = data(:,1);
lolimotObject.output = data(:,2);
clear data

lolimotObject.xInputDelay = cell(1,1);
lolimotObject.xOutputDelay = cell(1,1);
lolimotObject.zInputDelay = cell(1,1);
lolimotObject.zOutputDelay = cell(1,1);
lolimotObject.xInputDelay{1} = [1 2];                                % Second order dynamic system
lolimotObject.xOutputDelay{1} = [1 2];                               % Second order dynamic system
lolimotObject.zInputDelay{1} = [1 2];                                % Second order dynamic system
lolimotObject.zOutputDelay{1} = [1 2];                               % Second order dynamic system

% Try also the following cases:
% - Premise input space is only of first order
% lolimotObject.xInputDelay{1} = [1 2];
% lolimotObject.xOutputDelay{1} = [1 2];
% lolimotObject.zInputDelay{1} = [1];
% lolimotObject.zOutputDelay{1} = [1];
% - Premise input space does only contain the physical inputs (this reflects the Hammerstein structure)
% lolimotObject.xInputDelay{1} = [1 2];
% lolimotObject.xOutputDelay{1} = [1 2];
% lolimotObject.zInputDelay{1} = [1 2];
% lolimotObject.zOutputDelay{1} = [];
% - Local finite impulse response (FIR) models (no feedback is involved which requires high feedforward order)
% lolimotObject.xInputDelay{1} = [1:30];
% lolimotObject.xOutputDelay{1} = [];
% lolimotObject.zInputDelay{1} = [1 2];
% lolimotObject.zOutputDelay{1} = [];


lolimotObject.maxNumberOfLM = 10;                          % Termination criterion for maximal number of LLMs
lolimotObject.minError = 0.02;                              % Termination criterion for minimal error
lolimotObject.kStepPrediction = inf;                        % Simulation not one-step-ahead prediction
lolimotObject.history.displayMode = true;                   % display information

% Train net
lolimotObject = lolimotObject.train;

% Find best performance/complexity trade-off
[~, idxBest] = min(lolimotObject.history.penaltyLossFunction);
lolimotObject.leafModels = lolimotObject.history.leafModelIter{idxBest};

% Generalization
load hammersteinG.mat                                      % Data for generalization

% The generalization data was generated with the input signal stored in inputSequence2.mat.
uG = data(:,1);
yG = data(:,2);
clear data

% Simulate net
yGModel = calculateModelOutput(lolimotObject, uG, yG);
JG = calcGlobalLossFunction(lolimotObject ,yG, yGModel);

figure
lolimotObject.plotModel
% figure
% lolimotObject.plotMSFValue
% figure
% lolimotObject.plotPartition