function [InitStatus,theta,thetaPositions,ModelParameters,thetaDist,PriorDist,ParameterNames,thetaIndex,UniformBounds,LowerBound] = InitializeDSGEModelSimulation(DSGEModel,CurrINI)
% InitializeDSGEModelSimulation: Checks if the prior file has valid data, if the measurement equation file is correctly
%                                specified, and if the additional parameters files are correctly specified.
%
% USAGE:
%
%       [InitStatus,theta,thetaPositions,ModelParameters,thetaDist,PriorDist,ParameterNames,thetaIndex,UniformBounds,LowerBound] = InitializeDSGEModelSimulation(DSGEModel,CurrINI)
%
% REQUIRED INPUT: DSGEModel (structure) whose fields contain all required information
%                           about the model, such as input files, variable and sample
%                           data. Actual observations are not stored in this file.
%
%                 CurrINI (structure), with initialization information.
%
% REQUIRED OUTPUT: InitStatus (boolean), takes the value 1 if all the input files are correctly specified.
%
%                  theta (vector), with initial values of the parameters to be estimated.
%
%                  thetaPositions (structure) where thetaPositions(i).parameter is a string vector giving the name
%                           of the model parameter in position i of theta. The field "distribution" has a string
%                           vector giving the assumed prior distribution of the parameter.
%
%                  ModelParameters (structure) whose fields have names given by the parameter names in the
%                           DSGE model.
%
% OPTIONAL OUTPUT: thetaDist (vector) with integers 1 if gamma, 2 if beta, 3 if normal, 4 if invgamma, 5 if
%                           truncnormal, and 6 if uniform.
%
%                  PriorDist (structure) with fields "beta", "gamma", "normal", "invgamma", "truncnormal", and "uniform" where
%                           the values are matrices with the parameter values for the distributions. In the case of
%                           the normal, beta, and gamma these parameter values are the mean and the standard deviation.
%                           For the invgamma it is the s and q parameters, where q is a positive integer (degrees of
%                           freedom). Finally, for the left truncated normal there's a third parameter, the lower bound.
%
%                  ParameterNames (structure) with fields "calibrated", "beta", "gamma", "normal", "invgamma", "truncnormal",
%                           "uniform", "all" and "estimated". Each field returns a string matrix with the parameter names.
%
%                  thetaIndex (vector) with integers where 1=gamma, invgamma, truncnormal 2=beta, 3=uniform, and 0=normal.
%                           This is used to determine the type of transformation that may need to be performed for the
%                           theta parameters.
%
%                  UniformBounds (matrix) with the same number of rows as parameters and 2 columns. The columns are 0 1 except
%                           for the uniform and the beta distribution, where they represent the upper and lower bounds.
%
%                  LowerBound (vector) with lower bound values for the theta vector.
%
%
%                       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: August 16, 2006.
%                        This version: March 9, 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:
%
% * 17-08-2006: Added the 2 new inputs for the measurement equation file. These inputs include string matrices with the
%               names of the observed variables and the exogenous variables.
%
% * 24-08-2006: Removed the output "InitialValues" from the call to "VerifyPriorData".
%
% * 25-08-2006: Added the output UniformBounds to the call to "VerifyPriorData".
%
% * 28-08-2006: Made "thetaDist", "PriorDist", and "ParameterNames" optional output arguments.
%
% * 14-09-2006: Added the new inputs for the measurement equation function call.
%
% * 15-09-2006: Fixed bug with PriorDist call.
%
% * 17-10-2006: Added a try, catch call for the file "DSGEModel.AIMDataFile". This is needed if matlab can't
%               read the mat-file, e.g., because it was create with a later version of matlab.
%
% * 02-11-2007: Added the optional output arguments "thetaIndex", "UniformBounds", and "LowerBound".
%
% * 13-11-2007: Updated the documentation.
%
% * 23-05-2008: Updated the documentation.
%
% * 03-07-2008: Made sure that the measurement equation receives only the active state variable names.
%
% * 22-07-2008: Took the lower bound for the gamma distribution into account.
%
% * 23-07-2008: Took the upper and lower bounds of the beta distribution into account.
%
% * 23-10-2008: Made sure that all parameter names are read by the function.
%
% * 18-12-2008: Updated the documentation.
%
% * 19-12-2008: The function now copies parameter m-files and the measurement equations before it checks the prior.
%
% * 09-02-2009: Changed the input "length(DSGEModel.StateVariablePositions)" to "size(F,1)" when calling the
%               measurement equation function. This required that the function called additional functions
%               so that the dimension of F could be retrieved.
%
% * 13-02-2009: The mcode values 7 and 8 are now properly mentioned when encountered.
%
% * 09-03-2009: Added quotation marks around paths for the dos copy commands.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

InitStatus = 0;
%
% Copy files to the tmp directory and load data from DSGEModel.AIMDataFile
%
[stat,msg] = dos(['copy /Y "' GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m" "' pwd '\tmp"']);
[stat,msg] = dos(['copy /Y "' DSGEModel.MeasurementEquationFile '" "' pwd '\tmp"']);
if FileExist(DSGEModel.UpdateParameterFile)==1;
   [stat,msg] = dos(['copy /Y "' DSGEModel.UpdateParameterFile '" "' pwd '\tmp"']);
end;
if FileExist(DSGEModel.InitializeParameterFile)==1;
   [stat,msg] = dos(['copy /Y "' DSGEModel.InitializeParameterFile '" "' pwd '\tmp"']);
end;
%
[status,theta,thetaIndexOpt,thetaDistOpt,LowerBoundOpt,ModelParameters,thetaPositions,PriorDistOpt,ParameterNamesOpt,UniformBoundsOpt] = VerifyPriorData(DSGEModel,CurrINI);
if (status==0);
   return;
end;
OriginalModelParameters = ModelParameters;
if isempty(PriorDistOpt.beta)==0;
   [a,b] = MomentToParamStdbetaPDF((PriorDistOpt.beta(:,1)-PriorDistOpt.beta(:,3))./(PriorDistOpt.beta(:,4)-PriorDistOpt.beta(:,3)),PriorDistOpt.beta(:,2)./(PriorDistOpt.beta(:,4)-PriorDistOpt.beta(:,3)));
   PriorDistOpt.beta_ab = [a b];
else;
   PriorDistOpt.beta_ab = [];
end;
%
if isempty(PriorDistOpt.gamma)==0;
%   GammaLB = LowerBoundOpt(thetaDistOpt==1);
   [a,b] = MomentToParamGammaPDF(PriorDistOpt.gamma(:,1)-PriorDistOpt.gamma(:,3),PriorDistOpt.gamma(:,2));
   PriorDistOpt.gamma_ab = [a b];
else;
   PriorDistOpt.gamma_ab = [];
end;
if nargout>4;
   thetaDist = thetaDistOpt;
   PriorDist = PriorDistOpt;
   ParameterNames = ParameterNamesOpt;
   if nargout>7;
      thetaIndex = thetaIndexOpt;
      UniformBounds = UniformBoundsOpt;
      LowerBound = LowerBoundOpt;
   end;
end;
%
% NOTE: if all parameters are calibrated then theta is empty
%
ErrorStr = '';
ErrorFile = '';
try;
   AIMData = load(DSGEModel.AIMDataFile);
catch;
   ErrorStr = ['Unable to load the file "' DSGEModel.AIMDataFile '". Message caught is: ' lasterr];
   ErrorFile = DSGEModel.AIMDataFile;
end;
%
% The structure AIMData contains fields such as neq, nlead and nlag
%
if isempty(ErrorStr)==1;
   firstUpdatePos = 0;
   lastUpdatePos = 0;
   firstInitializePos = 0;
   lastInitializePos = 0;
   if DSGEModel.RunInitializeFirst==1;
      %
      % check if the file with additional parameters that only needs to be updated is OK
      %
      %
      % we need to run the file DSGEModel.InitializeParameterFile first
      %
      try;
         firstInitializePos = length(fieldnames(ModelParameters))+1;
         eval(['ModelParameters = ' GetName(DSGEModel.InitializeParameterFile) '(ModelParameters);']);
         lastInitializePos = length(fieldnames(ModelParameters));
      catch;
         ErrorStr = ['Error found in "' GetName(DSGEModel.InitializeParameterFile) '.m". Message caught is: ' lasterr];
         ErrorFile = DSGEModel.InitializeParameterFile;
      end;
      if (FileExist(DSGEModel.UpdateParameterFile)==1)&(isempty(ErrorStr)==1);
         try;
            firstUpdatePos = length(fieldnames(ModelParameters))+1;
            eval(['ModelParameters = ' GetName(DSGEModel.UpdateParameterFile) '(ModelParameters);']);
            lastUpdatePos = length(fieldnames(ModelParameters));
         catch;
            ErrorStr = ['Error found in "' GetName(DSGEModel.UpdateParameterFile) '.m". Message caught is: ' lasterr];
            ErrorFile = DSGEModel.UpdateParameterFile;
         end;
      end;
   else;
      if FileExist(DSGEModel.UpdateParameterFile)==1;
         try;
            firstUpdatePos = length(fieldnames(ModelParameters))+1;
            eval(['ModelParameters = ' GetName(DSGEModel.UpdateParameterFile) '(ModelParameters);']);
            lastUpdatePos = length(fieldnames(ModelParameters));
         catch;
            ErrorStr = ['Error found in "' GetName(DSGEModel.UpdateParameterFile) '.m". Message caught is: ' lasterr];
            ErrorFile = DSGEModel.UpdateParameterFile;
         end;
      end;
      if (FileExist(DSGEModel.InitializeParameterFile)==1)&(isempty(ErrorStr)==1);
         try;
            firstInitializePos = length(fieldnames(ModelParameters))+1;
            eval(['ModelParameters = ' GetName(DSGEModel.InitializeParameterFile) '(ModelParameters);']);
            lastInitializePos = length(fieldnames(ModelParameters));
         catch;
            ErrorStr = ['Error found in "' GetName(DSGEModel.InitializeParameterFile) '.m". Message caught is: ' lasterr];
            ErrorFile = DSGEModel.InitializeParameterFile;
         end;
      end;
   end;
   %
   % update the parameter names
   %
   if nargout>4;
      ParameterNames = ReadAdditionalParameterNames(ParameterNames,ModelParameters,OriginalModelParameters,[firstUpdatePos lastUpdatePos firstInitializePos lastInitializePos]);
   end;
end;
%
% check if the model can be solved
%
if isempty(ErrorStr)==1;
   try;
      [mcode,MaxAbsError,BMatrix,SMatrix] = AiMSolver(ModelParameters,AIMData.neq,AIMData.nlag,AIMData.nlead,DSGEModel.AIMTolerance);
   catch;
      ErrorStr = ['Error found in "compute_aim_matrices.m". Message caught is: ' lasterr];
      ErrorFile = [GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m'];
   end;
end;
%
if (isempty(ErrorStr)==1)&(mcode==1);
   try;
      [F,B0] = AiMtoStateSpace(BMatrix,SMatrix,DSGEModel.StateVariablePositions,DSGEModel.StateShockPositions);
   catch;
      ErrorStr = ['Error found when using the output from "compute_aim_matrices.m". Message caught is: ' lasterr];
      ErrorFile = [GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m'];
   end;
elseif (isempty(ErrorStr)==1)&(mcode~=1);
   if mcode==2;
      mcodeStr = 'Roots are not correctly computed by real_schur.'
   elseif mcode==3;
      mcodeStr = 'Too many big roots.';
   elseif mcode==35;
      mcodeStr = 'Too many big roots, and q(:,right) is singular.';
   elseif mcode==4;
      mcodeStr = 'Too few big roots.';
   elseif mcode==45;
      mcodeStr = 'Too few big roots, and q(:,right) is singular.';
   elseif mcode==5;
      mcodeStr = 'q(:,right) is singular.';
   elseif mcode==61;
      mcodeStr = 'Too many exact shiftrights.';
   elseif mcode==62;
      mcodeStr = 'Too many numeric shiftrights.';
   elseif mcode==7;
      mcodeStr = 'Infinite or NaN values detected.';
   elseif mcode==8;
      mcodeStr = 'The function "compute_aim_matrices" returns complex numbers.';
   else;
      mcodeStr = 'Return code not properly specified.';
   end;
   ErrorStr = ['The DSGE model doesn''t have a unique covergent solution. AiM returns the status: ' mcodeStr];
   ErrorFile = [GetPath(DSGEModel.AIMDataFile) 'compute_aim_matrices.m'];
end;
%
% check the measurement equation file for internal validity
%
if isempty(ErrorStr)==1;
   try;
      eval(['[A,H,R] = ' GetName(DSGEModel.MeasurementEquationFile) '(ModelParameters,AIMData.endog(DSGEModel.StateVariablePositions,:),DSGEModel.VariableNames,DSGEModel.XVariableNames,DSGEModel.n,size(F,1),DSGEModel.k);']);
   catch;
      ErrorStr = ['Error found in "' GetName(DSGEModel.MeasurementEquationFile) '.m". Message caught is: ' lasterr];
      ErrorFile = DSGEModel.MeasurementEquationFile;
   end;
end;
%
% If any error messages were caught, display about dialog and return
%
if isempty(ErrorStr)==0;
   About(ErrorStr,'error',['Error - ' GetFilename(ErrorFile)],120,500,CurrINI);
   return;
end;
%
% Initialization went fine
%
InitStatus = 1;

%
% end of InitializeDSGEModelSimulation.m
%
