function [c_train, c_test, obj] = perf_regression(d_train, ...
    l_train, d_test, cls)

% [c_train, c_test, obj] = perf_classification(d_train, ...
%     l_train, d_test, cls)
% 
% The functions performs regression (the training and testing of selected)
% algorithm. The function returns predicted classes for both training and
% testing set of data. The classifier is determined by optional structure
% 'classifier' that holds the information about the algorithm used.
% 
% INPUT DATA:
% d_train   - input training matrix [columns: features; rows: observations]
% d_test    - input testing matrix  [columns: features; rows: observations]
%             NOTE: size(d_train, 2) must be equal to size(d_test, 2)
% l_train   - column vector with labels of the training observations 
%             NOTE: size(l_train, 1) must be equal to size(d_train, 1)
% cls       - structure with the setting for selected classifier
%             NOTE: .alg field is mandatory (determines the classifier)
%                   possible classifiers: 
%                   - Classification and Regression trees ('cart')
%
% OUTPUT DATA:
% c_train   - the classified training class (predicted labels)
% c_test    - the classified testing class (predicted labels)
% obj       - trained model object
%
% CLASSIFIER OPTIONAL DATA:
%   1) Classification and Regression trees classifier
%      - no options so FAR (TODO)
%
%
% --
% ing. Zoltán Galáž
% xgalaz00@stud.feec.vutbr.cz       
% 
% Department of Telecommunications
% Faculty of Electrical Engineering and Communication
% Brno University of Technology

%% Paths and variables
if (~isfield(cls, 'alg'))
    error(['The input structure ''cls'' must contain field ''alg'' '   ...
           'that determines the selected regression algorithm.']);
end

%% Lower the algorithm specification (for consistency)
cls.alg = lower(cls.alg);

%% Check the regression algorithm
cls.alg = check_regression_alg(cls.alg);

if (isempty(cls.alg))
    cls.alg = 'cart';
    disp(' ');
    disp('Improper classifier selected. Set to default: Cart');
end

%% Train and classify selected classifier
if (strcmp(cls.alg, 'classificationandregressiontrees')             || ...
    strcmp(cls.alg, 'classification and regression trees')          || ...
    strcmp(cls.alg, 'regressiontrees')                              || ...
    strcmp(cls.alg, 'regression trees')                             || ...
    strcmp(cls.alg, 'cart algorithm')                               || ...
    strcmp(cls.alg, 'cart'))
    
    % Classification and Regression Trees algorithm
    cls = check_regression_sett(cls);
    [c_train, c_test, obj] = perf_cart(d_train, l_train, d_test, cls);
else        
    error(['Classifier ' cls.alg ' is not supported.']);
end