function [obj] = estimateFirstLM(obj)
% ESTIMATEFIRSTLM calculates a global model to initialize the LOLIMOT
% object. This is nessassary, because the splitting procedure needs a model
% and its validity area to operate.
%
%
% [obj] = estimateFirstLM(obj)
%
%
% INPUT/OUTPUT:
%   obj:  object    LOLIMOT object containing all relevant net and data set
%                   information and variables.
%
%
% LoLiMoT - Nonlinear System Identification Toolbox
% Torsten Fischer, 08-December-2011
% Institute of Mechanics & Automatic Control, University of Siegen, Germany
% Copyright (c) 2012 by Prof. Dr.-Ing. Oliver Nelles


% Define some variables
obj.numberOfInputs = size(obj.input,2);
obj.numberOfOutputs = size(obj.output,2);
zLowerBound = min(obj.zRegressor);
zUpperBound = max(obj.zRegressor);

% Corners of the first local model are identical to the boundaries of the z regressor space
lowerLeftCorner = zLowerBound;
upperRightCorner = zUpperBound;

% Initialize the local model object and calculating its gaussian
obj.localModels = gaussianOrthoLocalModel(lowerLeftCorner,upperRightCorner,obj.smoothness);

% First leaf model
obj.leafModels = true;

% Add boundaries to the local model object
obj.localModels.zLowerBound = zLowerBound;
obj.localModels.zUpperBound = zUpperBound;

% Calculate Gaussians
obj.MSFValue{1} = calculateMSF(obj.localModels,obj.zRegressor);

% Validities of the leaf local model (Here: all equal to 1)
validityFunctionValue = obj.calculateVFV(obj.MSFValue(1));

% Check for sufficient amount of data samples
if obj.pointsPerLMFactor * size(obj.xRegressor,2) - sum(validityFunctionValue{1}) > eps
    obj.idxAllowedLM = false;
    warning('lolimot:estimateFirstModel','the first local model has not enough valid point to estimate its parameters properly.')
else
    obj.idxAllowedLM = true;
end

% Estimate parameters of the first LM
obj.localModels.parameter = estimateParametersLocal(obj, obj.xRegressor, obj.output, validityFunctionValue{1}, [], obj.dataWeighting);

% Calculate model output
obj.outputModel = calculateModelOutput(obj);

% Calculate the local loss function value for one leaf models
obj.localModels.localLossFunctionValue = calcLocalLossFunction(obj, obj.unscaledOutput, obj.outputModel , cell2mat(validityFunctionValue), obj.dataWeighting, obj.outputWeighting);

end