function [X,index,selection,notfound] = select(X,descript,selection)
% select  Return ACF, XSF, FFRF, IFRF submatrices for a selection of variables.
%
% Syntax for arrays returned from model functions
% ================================================
%
%     X = select(X,selection)
%
% Input arguments
% ================
%
% * `X` [ numeric ] - Array returned by one of the functions `acf`, `xsf`,
% `ffrf`, or `ifrf`.
%
% * `selection` [ cell | cellstr | char ] - Selection of variables for
% which the corresponding submatrices will be returned.
%
% Output arugments
% =================
%
% * `X` [ numeric ] - Subblock of the original array `X` corresponding to
% the selection of variables.
%
% Description
% ============
%
% Example
% ========
%
% We first compute the autocovariance and autocorrelation fuctions for all
% variables of the model object `m` using the [`acf`](model/acf) function.
% This step gives us a potentially large matricex `C` and `R`. We only want
% to examine the ACF matrices for a subset of variables, namely `X`, `Y`,
% and the first lag of `Z`. We call the `select` function and get a 3-by-3
% submatrix `C0`.
%
%     [C,R] = acf(m);
%     C0 = select(C,{'X','Y','Z','Z{-1}'});

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

% Parse required input arguments.
P = inputParser();
P.addRequired('X',@isnumeric);
P.addRequired('descript',@(x) iscellstr(x) ...
    || (iscell(x) && numel(x) == 2 && iscellstr(x{1}) && iscellstr(x{2})));
P.addRequired('selection',@(x) ischar(x) || iscellstr(x) ...
    || (iscell(x) && numel(x) == 2 && iscellstr(x{1}) && iscellstr(x{2})));
P.parse(X,descript,selection);

%**************************************************************************

% Replace log(xxx) with xxx.
removelogfunc = @(x) regexprep(x,'log\((.*?)\)','$1');

if iscellstr(descript)
    descript = {descript,descript};
end
descript{1} = removelogfunc(descript{1});
descript{2} = removelogfunc(descript{2});

% Find names in char list.
if ischar(selection)
    selection = removelogfunc(selection);
    selection = regexp(selection,'\w+','match');
end
oneselection = false;
if iscellstr(selection)
    oneselection = true;
    selection = {selection,selection};
end
selection{1} = removelogfunc(selection{1});
selection{2} = removelogfunc(selection{2});

if isnumeric(X)
    index = cell(1,2);
    notfound = cell(1,2);
    for i = 1 : 2
        for j = 1 : length(selection{i})
            k = strcmp(descript{i},selection{i}{j});
            if any(k)
                index{i}(end+1) = find(k,1);
            else
                notfound{i}{end+1} = selection{i}{j}; %#ok<*AGROW>
            end
        end
    end
    if oneselection
        notfound = intersect(notfound{1:2});
    else
        notfound = union(notfound{1:2});
    end
    if isempty(index{1})
        index{1} = 1 : size(X,1);
    end
    if isempty(index{2})
        index{2} = 1 : size(X,2);
    end
    subsref = cell(1,ndims(X));
    subsref(1:2) = index;
    subsref(3:end) = {':'};
    X = X(subsref{:});
elseif isstruct(X)
    [index,notfound] = strfun.findnames(descriptor,selection);
    index(isnan(index)) = [];
    list = fieldnames(X);
    for i = 1 : length(list)
        if istseries(X.(list{i}))
            X.(list{i}) = X.(list{i}){:,index};
        end
    end
end

if ~isempty(notfound)
    utils.error('select', ...
        'Name ''%s'' not found in the description of rows or columns.', ...
        notfound{:});
end

end