function [W,LIST] = ifrf(THIS,FREQ,varargin)
% ifrf  Frequency response function to shocks.
%
% Syntax
% =======
%
%     [W,LIST] = ifrf(M,FREQ,...)
%
% Input arguments
% ================
%
% * `M` [ model ] - Model object for which the frequency response function
% will be computed.
%
% * `FREQ` [ numeric ] - Vector of frequencies for which the response
% function will be computed.
%
% Output arguments
% =================
%
% * `W` [ numeric ] - Array with frequency responses of transition
% variables (in rows) to shocks (in columns).
%
% * `LIST` [ cell ] - List of transition variables in rows of the `W`
% matrix, and list of shocks in columns of the `W` matrix.
%
% Options
% ========
%
% * `'output='` [ *'namedmat'* | numeric ] - Output matrix `W` will be
% either a namedmat object or a plain numeric array; if the option
% `'select='` is used, `'output='` is always `'namedmat'`.
%
% * `'select='` [ char | cellstr | *`Inf`* ] - Return the frequency response
% function only for selected variables and/or selected shocks.
%
% Description
% ============
%
% Example
% ========
%

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

% Parse input arguments.
P = inputParser();
P.addRequired('m',@ismodel);
P.addRequired('freq',@isnumeric);
P.parse(THIS,FREQ);

% Parse options.
opt = passvalopt('model.ifrf',varargin{:});

isselect = iscellstr(opt.select);
isnamedmat = strcmpi(opt.output,'namedmat') || isselect;

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

FREQ = FREQ(:)';
nfreq = length(FREQ);
ny = length(THIS.solutionid{1});
nx = length(THIS.solutionid{2});
ne = length(THIS.solutionid{3});
nalt = size(THIS.Assign,3);
W = zeros(ny+nx,ne,nfreq,nalt);

if ne > 0
    [flag,index] = isnan(THIS,'solution');
    for ialt = find(~index)
        [T,R,K,Z,H,D,Za,Omega] = mysspace(THIS,ialt,false);
        % Call Freq Domain package.
        W(:,:,:,ialt) = timedom.ifrf(T,R,K,Z,H,D,Za,Omega,FREQ);
    end
end

% Report solutions not available.
if flag
    utils.warning('model', ...
        '#Solution_not_available', ...
        sprintf(' #%g',find(index)));
end

LIST = { ...
    [THIS.solutionvector{1:2}], ...
    THIS.solutionvector{3}, ...
    };
    
if isnamedmat
    W = namedmat(W{1},LIST{1},LIST{2});
end

% Select variables.
if isselect
    W = select(W,opt.select);
end

end