%% Different noise level
function differentNoiseLevel(pointsPerAxis)
% clear; clear all; close all; clc;

%% Define Process and 'measured' training data
% pointsPerAxis   = 51; % 51, 301
uAxis           = linspace(0,1,pointsPerAxis)';
% uAxis           = rand(pointsPerAxis,1);
U               = uAxis;
yUndisturbed    = benchFunktionND(U,'hyperbelGauss');
noiseLevel      = [0 0.05 0.1];
noiseLevel      = [0.05 0.1 0.2];

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

% Predefine cell array, that will contain the local model networks for
% different noise levels
lmn             = cell(size(noiseLevel,2),1);

%% Plot options
scrsize         = get(0,'ScreenSize');
width           = 500;
height          = 400;
pos             = [(scrsize(3)-width)/2 (scrsize(4)-height)/2 width height];
linewidth       = 2;
fontname        = 'Times';
fontsize        = 14;
colors          = {[0 0 1],[0 0.8 0],[1 0 0]};

figure('Position',pos);
ahLeft = axes;
figure('Position',pos+[width 0 0 0]);
ahRight = axes;
hold(ahLeft,'on');
hold(ahRight,'on');
grid(ahLeft,'on');
grid(ahRight,'on');
% options.plotAxis = ah;

%% Training und Visualisierung
for ii=1:size(noiseLevel,2)
    
    % Add noise to training data
    rng(24,'twister');
    yMeasured       = yUndisturbed + noiseLevel(ii)*randn(size(yUndisturbed,1),1);
    
    % Add noise to validation data
    yMeasuredVali   = yUndisturbedVali + 0*noiseLevel(ii)*randn(size(yUndisturbedVali,1),1);
    
    % Create LOLIMOT model
    lmn{ii,1}             = lolimot;
    lmn{ii,1}.xRegressorDegree = 1;
    lmn{ii,1}.lossFunctionGlobal = 'RMSE';
    
    % Pass training data
    lmn{ii,1}.input       = U;
    lmn{ii,1}.output      = yMeasured;
    
    % Pass validation data
    lmn{ii,1}.validationInput = Uvali;
    lmn{ii,1}.validationOutput = yMeasuredVali;
    
    % Pass test data
    lmn{ii,1}.testInput = Uvali;
    lmn{ii,1}.testOutput = yMeasuredVali;
    
    % Some options for the training
    lmn{ii,1}.smoothness  = 1.0;
    lmn{ii,1}.maxNumberOfLM = 15;
    lmn{ii,1}.minError    = 0.00;
    lmn{ii,1}.maxValidationDeterioration = inf;
    lmn{ii,1}.maxPenaltyDeterioration = inf;
    
    % Start the LOLIMOT training algorithm
    lmn{ii,1}             = lmn{ii,1}.train;
    
    % Global loss function (training data)
    plot(ahLeft,lmn{ii,1}.history.globalLossFunction,...
        'LineWidth',linewidth,'Color',colors{ii});
    
    % Global loss function (validation data)
    plot(ahRight,lmn{ii,1}.history.validationDataLossFunction,...
        'LineWidth',linewidth,'Color',colors{ii});

end

hlLeft = legend(ahLeft,{['\sigma_n = ',num2str(noiseLevel(1))],...
    ['\sigma_n = ',num2str(noiseLevel(2))],['\sigma_n = ',num2str(noiseLevel(3))]});
hlRight = legend(ahRight,{['\sigma_n = ',num2str(noiseLevel(1))],...
    ['\sigma_n = ',num2str(noiseLevel(2))],['\sigma_n = ',num2str(noiseLevel(3))]});
hxLeft = xlabel(ahLeft,'Model Complexity');
hyLeft = ylabel(ahLeft,'Loss Function Value');
htLeft = title(ahLeft,'Training Data');
hxRight = xlabel(ahRight,'Model Complexity');
hyRight = ylabel(ahRight,'Loss Function Value');
htRight = title(ahRight,'Validation Data (Noise Free)');

set([hlLeft,hlRight,ahLeft,ahRight,hxLeft,hyLeft,htLeft,hxRight,hyRight,htRight],...
    'FontSize',fontsize,'FontName',fontname);
set([hlLeft,hlRight],'Location','best');

set([ahLeft,ahRight],'YScale','log');
% set([ahLeft,ahRight],'YLim',[0.003 1]);


