%% Hyperbel Example 2d Eingangsraum HILOMOT
%
% Schritt fuer Schritt Training durchgehen
% FRAGEN?

clear; clear all; close all; clc;

% Define Process and 'measured' training data
inputDimension  = 2;
exampleFunction = 'hyperbel';
pointsPerAxis   = 31;
uAxis           = linspace(0,1,pointsPerAxis)';
U               = makeBenchInputND(inputDimension,uAxis);
yUndisturbed    = benchFunktionND(U,exampleFunction);
noiseLevel      = 0.0;

% Define validation data
deltaU          = (uAxis(2)-uAxis(1))/2;    % 'Zwischengitterstellen' + andere Rauschauspraegung
% deltaU          = uAxis(2)-uAxis(1);        % Gleiche Stellen, andere Rauschauspraegung
uAxisVali       = deltaU:deltaU*2:max(uAxis)-deltaU;
Uvali           = makeBenchInputND(inputDimension,uAxisVali');
yUndisturbedVali = benchFunktionND(Uvali,exampleFunction);

% Only necessary for two dimensional inputs
u1g             = reshape(U(:,1),pointsPerAxis,pointsPerAxis);
u2g             = reshape(U(:,2),pointsPerAxis,pointsPerAxis);
yUndisturbedG   = reshape(yUndisturbed,pointsPerAxis,pointsPerAxis);

% Add noise to training data
rng(42,'twister');
yMeasured       = yUndisturbed + noiseLevel*range(yUndisturbed)*randn(size(yUndisturbed,1),1);

% Add noise to validation data
rng(24,'twister');
yMeasuredVali   = yUndisturbedVali + noiseLevel*range(yUndisturbed)*randn(size(yUndisturbedVali,1),1);

% Create LOLIMOT model
lmn             = hilomot;

% Pass training data
lmn.input       = U;
lmn.output      = yMeasured;

% Pass validation data
lmn.validationInput = Uvali;
lmn.validationOutput = yMeasuredVali;

% Some options for the training
lmn.smoothness  = 1;
lmn.maxNumberOfLM = 15;
lmn.minError    = 0.00;
lmn.maxValidationDeterioration = inf;
lmn.maxPenaltyDeterioration = inf;

% Start the LOLIMOT training algorithm
lmn             = lmn.train;

% Plot options
scrsize         = get(0,'ScreenSize');
width           = 1024;
height          = 768;
pos             = [(scrsize(3)-width)/2 (scrsize(4)-height)/2 width height];
linewidth       = 2;
fontname        = 'Arial';
fontsize        = 14;

% Predefinition of figure and axes
figure('Position',pos);
ah              = cell(4,3);

% Visualization of 3 iterations
for ii=1:3
    
    % Set model complexity
    lmn.leafModels = lmn.history.leafModelIter{1,ii};
    
    % Definition of axes
    ah{1,ii} = subplot(4,3,ii);
    grid('on');
    ah{2,ii} = subplot(4,3,ii+3);
    grid('on');
    ah{3,ii} = subplot(4,3,ii+3*2);
    grid('on');
    ah{4,ii} = subplot(4,3,ii+3*3);
    grid('on');
    ht = title(ah{1,ii},[num2str(ii),'. Iteration']);
    
    
    % Plot splitting function
    visualizeSplittingFunction(lmn,ii,[1 2],ah{1,ii});
    
    % Plot validity function
    options.plotAxis = ah{2,ii};
    options.resolution = pointsPerAxis;
    options.plotMethod = 'surf';
    lmn.plotPartition([1 2], [], options)
    % not implemented yet.
    
    % Plot local linear models seperately
    visualizeSeperateLocalModels(lmn,[],ah{3,ii});
    
    % Plot output of the whole local model network
    yDach = lmn.calculateModelOutput(lmn.input);
    yDachG = reshape(yDach,pointsPerAxis,pointsPerAxis);
    surf(ah{4,ii},u1g,u2g,yDachG)
    
    set([ah{1,ii},ah{3,ii}],'View',get(ah{2,ii},'View'));
    
end