function [A,H,R,F,B0,status] = SolveDSGEModel(DSGEModel,theta,thetaPositions,ModelParameters,AIMData)
% SolveDSGEModel: Solves the DSGE model for a given value of the parameters and writes the solution
%                 as a state-space respresentation.
%
% USAGE:
%
%       [A,H,R,F,B0,status] = SolveDSGEModel(DSGEModel,theta,thetaPositions,ModelParameters,AIMData)
%
% REQUIRED INPUT:  DSGEModel (structure) with fields containing all the information about a DSGE Model for YADA.
%
%                  theta (vector) with the original parameters.
%
%                  thetaPositions (structure) with fields parameter and distribution. This function
%                                 needs the former field to know which parameter name corresponds to
%                                 position i in theta.
%
%                  ModelParameters (structure) whose fields have names given by the parameter names in the
%                                 DSGE model.
%
%                  AIMData (structure) with data collected by AIM about the model.
%
% REQUIRED OUTPUT: A (kxn) matrix with coefficients on the exogenous variables in the measurement equation.
%
%                  H (rxnxT) matrix with cofficients on the state variables in the measurement equation.
%
%                  R (nxn) matrix with the covariances of the measurement errors.
%
%                  F (rxr) transition matrix for the state variables.
%
%                  B0 (rxq) matrix with coefficients on the economic shocks in the state equation.
%
% OPTIONAL OUTPUT: status (integer) Indicates whether the solution of the model is unique or not.
%                                 mcode is 1 when unique, 0 if not computed, and various other values when
%                                 there are problems with the solution. Specifically:
%
%                                      mcode = 2:      Roots not correctly computed by real_schur
%                                      mcode = 3:      Too many big roots
%                                      mcode = 35:     Too many big roots, and q(:,right) is singular
%                                      mcode = 4:      Too few big roots
%                                      mcode = 45:     Too few big roots, and q(:,right) is singular
%                                      mcode = 5:      q(:,right) is singular
%                                      mcode = 61:     Too many exact shiftrights
%                                      mcode = 62:     Too many numeric shiftrights.
%                                      mcode = 7:      The a matrix has infinite or NaN values. Eigenvalues
%                                                      cannot be calculated.
%                                      mcode = 8:      The function "compute_aim_matrices" returns complex
%                                                      numbers.
%                                      else            Return code not properly specified
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2009 European Central Bank.
%
%                       First version: February 22, 2007.
%                        This version: February 13, 2009.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LICENSE INFORMATION:
%
%      YADA is free software: you can redistribute it and/or modify
%      it under the terms of the GNU General Public License as published by
%      the Free Software Foundation, either version 3 of the License, or
%      (at your option) any later version.
%
%      This program is distributed in the hope that it will be useful,
%      but WITHOUT ANY WARRANTY; without even the implied warranty of
%      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%      GNU General Public License for more details.
%
%      You should have received a copy of the GNU General Public License
%      along with this program.  If not, see <http://www.gnu.org/licenses/>.
%
%      YADA is released under the GNU General Public License, Version 3,
%      29 June 2007 <http://www.gnu.org/licenses/>. The current release of
%      the program was last modified by the ECB on the "This version" date
%      above.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CHANGELOG:
%
% * 02-05-2007: Added the optional output "status".
%
% * 13-11-2007: Updated the documentation.
%
% * 16-05-2008: Took the "DSGEModel.AIMTolerance" input for AiMSolver into account.
%
% * 23-05-2008: Updated the documentation.
%
% * 27-05-2008: The mcode value 7 is now supported.
%
% * 03-07-2008: Made sure that the measurement equation receives only the active state variable names.
%
% * 09-07-2008: Updated the documentation.
%
% * 22-01-2009: Updated the documentation.
%
% * 09-02-2009: Changed the input "length(DSGEModel.StateVariablePositions)" to "size(F,1)" when calling the
%               measurement equation function.
%
% * 13-02-2009: The mcode values 7 and 8 are now properly mentioned when encountered.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

if nargout==6;
   status = 1;
end;
%
% Make sure that the ModelParameter structure takes the correct values.
% This is not necessary to do when initial values are given to the function.
% In that case, more substantial checking is required!
%
ModelParameters = ThetaToModelParameters(ModelParameters,theta,thetaPositions);
%
% Update any parameteters that need updating
%
if FileExist(DSGEModel.UpdateParameterFile)==1;
   eval(['ModelParameters = ' GetName(DSGEModel.UpdateParameterFile) '(ModelParameters);']);
end;
%
% Solve the model
%
if nargout==5;
   [mcode,MaxAbsError,BMatrix,SMatrix] = AiMSolver(ModelParameters,AIMData.neq,AIMData.nlag,AIMData.nlead,DSGEModel.AIMTolerance);
else;
   try;
      [mcode,MaxAbsError,BMatrix,SMatrix] = AiMSolver(ModelParameters,AIMData.neq,AIMData.nlag,AIMData.nlead,DSGEModel.AIMTolerance);
   catch;
      if exist('mcode')>0;
         status = mcode;
      else;
         status = 0;
      end;
      F = [];
      B0 = [];
      A = [];
      H = [];
      R = [];
      return;
   end;
end;
if (mcode~=1)&(nargout==6);
   status = mcode;
   F = [];
   B0 = [];
   A = [];
   H = [];
   R = [];
   return;
end;
%
% Convert to the state equation matrices
%
[F,B0] = AiMtoStateSpace(BMatrix,SMatrix,DSGEModel.StateVariablePositions,DSGEModel.StateShockPositions);
%
% obtain the measurement equation matrices
%
eval(['[A,H,R] = ' GetName(DSGEModel.MeasurementEquationFile) '(ModelParameters,AIMData.endog(DSGEModel.StateVariablePositions,:),DSGEModel.VariableNames,DSGEModel.XVariableNames,DSGEModel.n,size(F,1),DSGEModel.k);']);

%
% end of SolveDSGEModel.m
%
