%% Hyperbel Example
%
% Schritt fuer Schritt Training durchgehen
% FRAGEN?

clear; clear all; close all; clc;

%% Define Process and 'measured' training data
pointsPerAxis   = 41;
uAxis           = linspace(0,1,pointsPerAxis)';
U               = makeBenchInputND(1,uAxis);
testFunction    = 'hyperbelGauss'; % 'parabola', 'hyperbelGauss'
yUndisturbed    = benchFunktionND(U,testFunction);
noiseLevel      = 0.03;

% 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(1,uAxisVali');
yUndisturbedVali = benchFunktionND(Uvali,testFunction);

% 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             = lolimot;

% 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 = 5;
lmn.minError    = 0.00;
lmn.maxValidationDeterioration = inf;
lmn.xRegressorDegree = 1;

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

%% Visualize undisturbed process and measured training as well as validation
% data

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

figure('Position',pos);
ah = axes;
hold(ah,'on');
set(ah,'FontSize',fontsize,'FontName',fontname,'YLim',[0 1.05]);

plot(ah,U,yUndisturbed,'LineStyle','--','LineWidth',linewidth,...
    'Color',[0.4 0.4 0.4]);
hTrainingMarker = plot(ah,U,yMeasured,'LineStyle','none','Marker','x','Color',[1 0 0],...
    'LineWidth',linewidth);
% hValidationMarker = plot(ah,Uvali,yMeasuredVali,'LineStyle','none','Marker','o','Color',[0 0.8 0],...
%     'LineWidth',linewidth);


pause

% delete([hTrainingMarker,hValidationMarker])
% delete(hTrainingMarker);
options.plotAxis = ah;


% Step by step
for ii=1:size(lmn.history.leafModelIter,2)
    
    % Set the current leaf models to the ones of the corresponding
    % iteration
    lmn.leafModels = lmn.history.leafModelIter{1,ii};
    
    % Plot validity functions
    hValidities = lmn.plotPartition(1,[],options);
    
    % Plot splitting functions
    hSplits = visualizeSplittingFunction(lmn,ii,1,ah);
    
    % Plot local models
    hLMs = visualizeSeperateLocalModels(lmn,[],ah);
    
    if ii==1
        hl=legend({'Prozess','Trainingsdaten','Normierte Basisfunktionen','Basisfunktionen','Lokale Modelle'});
        set(hl,'Location','West','FontSize',fontsize,'FontName',fontname);
    end
    
    pause
    
    if ii~=size(lmn.history.leafModelIter,2)
        delete([hValidities',hSplits{:},hLMs{:}]);
    end
    
end

pause

figure('Position',pos);
ah2 = axes;
hold(ah2,'on');
plot(ah2,U,yUndisturbed,'LineStyle','--','LineWidth',linewidth,...
    'Color',[0.4 0.4 0.4]);
plot(ah2,lmn.input,lmn.outputModel,'LineStyle','-','LineWidth',linewidth,...
    'Color',[0 0 0]);
hTrainingMarker = plot(ah2,U,yMeasured,'LineStyle','none','Marker','x','Color',[1 0 0],...
    'LineWidth',linewidth);
set(ah2,'FontSize',fontsize,'FontName',fontname,'YLim',[0 1.05]);
hl=legend(ah2,{'Undisturbed Process','Model','Training data'});
set(hl,'Location','NorthWest','FontSize',fontsize,'FontName',fontname);