classdef plan < userdataobj
    % plan  Simulation plans.
    %
    % Simulation plans complement the use of the
    % [`model/simulate`](model/simulate) or
    % [`model/jforecast`](model/jforecast) functions.
    %
    % You need to use a simulation plan object to set up the following types of
    % more complex simulations or forecasts (or a combination of these):
    %
    % # simulations or forecasts with some of the model variables temporarily
    % exogenised;
    %
    % # simulations with some of the non-linear equations solved in an exact
    % non-linear mode;
    %
    % # forecasts conditioned upon some variables;
    %
    % The plan object is passed to the [`model/simulate`](model/simulate) or
    % [`model/jforecast`](model/jforecast) functions through the `'plan='`
    % option.
    %
    % Plan methods:
    %
    % Constructor
    % ============
    %
    % * [`plan`](plan/plan) - Create new simulation plan.
    %
    % Getting information about simulation plans
    % ===========================================
    %
    % * [`detail`](plan/detail) - Display details of a simulation plan.
    % * [`get`](plan/get) - Query plan object properties.
    % * [`nnzcond`](plan/nnzcond) - Number of conditioning data points.
    % * [`nnzendog`](plan/nnzendog) - Number of endogenised data points.
    % * [`nnzexog`](plan/nnzexog) - Number of exogenised data points.
    % * [`nnznonlin`](plan/nnznonlin) - Number of non-linearised data points.
    %
    % Setting up simulation plans
    % ============================
    %
    % * [`condition`](plan/condition) - Condition forecast upon the specified variables at the specified dates.
    % * [`endogenise`](plan/endogenise) - Endogenise shocks or re-endogenise variables at the specified dates.
    % * [`exogenise`](plan/exogenise) - Exogenise variables or re-exogenise shocks at the specified dates.
    % * [`nonlinearise`](plan/nonlinearise) - Select equations for simulation in an exact non-linear mode.
    %
    % Referencing plan objects
    % ==========================
    %
    % * [`subsref`](plan/subsref) - Subscripted reference for plan objects.
    %
    % Getting on-line help on simulation plans
    % =========================================
    %
    %     help plan
    %     help plan/function_name
    %
    
    % -IRIS Toolbox.
    % -Copyright (c) 2007-2012 Jaromir Benes.
    
    properties
        startdate = NaN;
        enddate = NaN;
        xlist = {};
        nlist = {};
        qlist = {};
        clist = {};
        xanchors = []; % Exogenise.
        nanchorsreal = []; % Endogenise real.
        nanchorsimag = []; % Endogenise imag.
        canchors = []; % Condition.
        qanchors = []; % Non-linearise.
    end
    
    methods
        
        function this = plan(varargin)
            % plan  Create new simulation plan.
            %
            % Syntax
            % =======
            %
            %     p = plan(m,range)
            %
            % Input arguments
            % ================
            %
            % * `m` [ model ] - Model object that will be simulated subject to this
            % simulation plan.
            %
            % * `range` [ numeric ] - Simulation range; this range must exactly
            % correspond to the range on which the model will be simulated.
            %
            % Output arguments
            % =================
            %
            % * `p` [ plan ] - New simulation plan.
            %
            % Description
            % ============
            %
            % You need to use a simulation plan object to set up the following types of
            % more complex simulations or forecats:
            %
            % # simulations or forecasts with some of the model variables temporarily exogenised;
            %
            % # simulations with some of the non-linear equations solved exactly.
            %
            % # forecasts conditioned upon some variables;
            %
            % The plan object is passed to the [simulate](model/simulate) or
            % [jforecast](model/jforecast) functions through the option `'plan='`.
            %
            % Example
            % ========
            %
            
            % -IRIS Toolbox.
            % -Copyright (c) 2007-2012 Jaromir Benes.
            
            if length(varargin) > 1
                % Range.
                this.startdate = varargin{2}(1);
                this.enddate = varargin{2}(end);
                nper = round(this.enddate - this.startdate + 1);
                % Exogenising.
                this.xlist = myget(varargin{1},'canbeexogenised');
                this.xanchors = false(length(this.xlist),nper);
                % Endogenising.
                this.nlist = myget(varargin{1},'canbeendogenised');
                this.nanchorsreal = false(length(this.nlist),nper);
                this.nanchorsimag = false(length(this.nlist),nper);
                % Non-linearising.
                this.qlist = myget(varargin{1},'canbenonlinearised');
                this.qanchors = false(length(this.qlist),nper);
                % Conditioning.
                this.clist = this.xlist;
                this.canchors = this.xanchors;
            end
            
        end
        
        varargout = condition(varargin)
        varargout = detail(varargin)
        varargout = exogenise(varargin)
        varargout = endogenise(varargin)
        varargout = isempty(varargin)
        varargout = nnzcond(varargin)
        varargout = nnzendog(varargin)
        varargout = nnzexog(varargin)
        varargout = nnznonlin(varargin)
        varargout = nonlinearise(varargin)
        varargout = subsref(varargin)
        
        varargout = get(varargin)
        varargout = set(varargin)
        
    end
    
    methods (Hidden)
        
        varargout = mydateindex(varargin)
        varargout = mysimulate(varargin)
        
        function disp(this)
            fprintf('\tplan object: 1-by-1\n');
            nx = nnzexog(this);
            [nn,nnreal,nnimag] = nnzendog(this); %#ok<ASGLU>
            nc = nnzcond(this);
            nq = nnznonlin(this);
            fprintf('\trange: %s to %s\n', ...
                dat2char(this.startdate),dat2char(this.enddate));
            fprintf('\texogenised data points: %g\n',nx);
            fprintf('\tendogenised data points [real imag]: %g %g\n', ...
                nnreal,nnimag);
            fprintf('\tconditioning data points: %g\n',nc);
            fprintf('\tnon-linearised data points: %g\n',nq);
            disp@userdataobj(this);
            disp(' ');
        end
        
        % Aliasing.
        function varargout = exogenize(this,varargin)
            [varargout{1:nargout}] = exogenise(this,varargin{:});
        end
        
        function varargout = endogenize(this,varargin)
            [varargout{1:nargout}] = endogenise(this,varargin{:});
        end
        
        function varargout = nonlinearize(this,varargin)
            [varargout{1:nargout}] = nonlinearise(this,varargin{:});
        end
        
    end
    
end