Commit 502e3e1d authored by sebastien's avatar sebastien
Browse files

Beautified MATLAB code (Unix newline convention + Emacs indentation), except: AIM, swz, particle

git-svn-id: https://www.dynare.org/svn/dynare/trunk@3250 ac1d8469-bf42-47a9-8791-bf33cf982152
parent e6f1a53e
function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% function [dr,aimcode]=dynAIMsolver1(jacobia_,M_,dr)
% Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson
% and derives the solution for gy=dr.hgx and gu=dr.hgu from the AIM outputs
% AIM System is given as a sum:
% i.e. for i=-$...+& SUM(Hi*xt+i)= *zt, t = 0, . . . ,?
% and its input as single array of matrices: [H-$... Hi ... H+&]
% and its solution as xt=SUM( Bi*xt+i) + @**zt for i=-$...-1
% with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1)
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'=
%
% INPUTS
% jacobia_ [matrix] 1st order derivative of the model
% dr [matlab structure] Decision rules for stochastic simulations.
% M_ [matlab structure] Definition of the model.
%
% OUTPUTS
% dr [matlab structure] Decision rules for stochastic simulations.
% aimcode [integer] 1: the model defines variables uniquely
% aimcode is resolved in AIMerr as
% (c==1) e='Aim: unique solution.';
% (c==2) e='Aim: roots not correctly computed by real_schur.';
% (c==3) e='Aim: too many big roots.';
% (c==35) e='Aim: too many big roots, and q(:,right) is singular.';
% (c==4) e='Aim: too few big roots.';
% (c==45) e='Aim: too few big roots, and q(:,right) is singular.';
% (c==5) e='Aim: q(:,right) is singular.';
% (c==61) e='Aim: too many exact shiftrights.';
% (c==62) e='Aim: too many numeric shiftrights.';
% else e='Aimerr: return code not properly specified';
%
% SPECIAL REQUIREMENTS
% Dynare use:
% 1) the lognormal block in DR1 is being invoked for some models and changing
% values of ghx and ghy. We need to return the AIM output
% values before that block and run the block with the current returned values
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
% (it does not depend on mjdgges output).
%
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
% results to the Dynare solutiion then when if plain jacobia_ is passed,
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
%
% GP July 2008
% Copyright (C) 2008 Dynare Team
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>.
aimcode=-1;
neq= size(jacobia_,1); % no of equations
lags=M_.maximum_endo_lag; % no of lags and leads
leads=M_.maximum_endo_lead;
klen=(leads+lags+1); % total lenght
theAIM_H=zeros(neq, neq*klen); % alloc space
lli=M_.lead_lag_incidence';
% "sparse" the compact jacobia into AIM H aray of matrices
% without exogenous shoc
theAIM_H(:,find(lli(:)))=jacobia_(:,nonzeros(lli(:)));
condn = 1.e-10;%SPAmalg uses this in zero tests
uprbnd = 1 + 1.e-6;%allow unit roots
% forward only models - AIM must have at least 1 lead and 1 lag.
if lags ==0
theAIM_H =[zeros(neq) theAIM_H];
lags=1;
klen=(leads+lags+1);
end
% backward looking only models
if leads ==0
theAIM_H =[theAIM_H zeros(neq)];
leads=1;
klen=(leads+lags+1);
end
%disp('gensysToAMA:running ama');
try % try to run AIM
[bb,rts,ia,nexact,nnumeric,lgroots,aimcode] =...
SPAmalg(theAIM_H,neq, lags,leads,condn,uprbnd);
catch
err = lasterror;
disp(['Dynare AIM Solver error:' sprintf('%s; ID:%s',err.message, err.identifier)]);
rethrow(lasterror);
end
if aimcode==1 %if OK
col_order=[];
for i =1:lags
col_order=[((i-1)*neq)+dr.order_var' col_order];
end
bb_ord= bb(dr.order_var,col_order); % derive ordered gy
% variables are present in the state space at the lag at which they
% appear and at all smaller lags. The are ordered from smaller to
% higher lag (reversed order of M_.lead_lag_incidence rows for lagged
% variables)
i_lagged_vars = flipud(cumsum(M_.lead_lag_incidence(1:M_.maximum_lag,dr.order_var),1))';
dr.ghx= bb_ord(:,find(i_lagged_vars(:))); % get columns reported in
% Dynare solution
if M_.exo_nbr % if there are exogenous shocks then derive gu for the shocks:
% get H0 and H+1=HM
% theH0= theAIM_H (:,M_.maximum_endo_lag*neq+1: (M_.maximum_endo_lag+1)*neq);
%theH0= theAIM_H (:,lags*neq+1: (lags+1)*neq);
% theHP= theAIM_H (:,(M_.maximum_endo_lag+1)*neq+1: (M_.maximum_endo_lag+2)*neq);
%theHP= theAIM_H (:,(lags+1)*neq+1: (lags+2)*neq);
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
%? = inv(H0 + H1B1)
%phi= (theH0+theHP*sparse(bb(:,(lags-1)*neq+1:end)))\eye( neq);
%AIM_ghu=phi*theAIM_Psi;
%dr.ghu =AIM_ghu(dr.order_var,:); % order gu
% Using AIM SPObstruct
scof = SPObstruct(theAIM_H,bb,neq,lags,leads);
scof1= scof(:,(lags)*neq+1:end);
scof1= scof1(:,dr.order_var);
dr.ghu =scof1\theAIM_Psi;
else
dr.ghu = [];
end
else
err=SPAimerr(aimcode);
%warning('Error in AIM: aimcode=%d, erro=%s', aimcode, err);;
disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
if aimcode < 1 || aimcode > 5 % too big exception, use mjdgges
error('Error in AIM: aimcode=%d ; %s', aimcode, err);
end
% if aimcode > 5
% disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
% aimcode=5;
% end
end
function [dr,aimcode,rts]=dynAIMsolver1(jacobia_,M_,dr)
% function [dr,aimcode]=dynAIMsolver1(jacobia_,M_,dr)
% Maps Dynare jacobia to AIM 1st order model solver designed and developed by Gary ANderson
% and derives the solution for gy=dr.hgx and gu=dr.hgu from the AIM outputs
% AIM System is given as a sum:
% i.e. for i=-$...+& SUM(Hi*xt+i)= *zt, t = 0, . . . ,?
% and its input as single array of matrices: [H-$... Hi ... H+&]
% and its solution as xt=SUM( Bi*xt+i) + @**zt for i=-$...-1
% with the output in form bb=[B-$... Bi ... B-1] and @=inv(Ho+H1*B-1)
% Dynare jacobian = [fy'-$... fy'i ... fy'+& fu']
% where [fy'-$... fy'i ... fy'+&]=[H-$... Hi ... H+&] and fu'=
%
% INPUTS
% jacobia_ [matrix] 1st order derivative of the model
% dr [matlab structure] Decision rules for stochastic simulations.
% M_ [matlab structure] Definition of the model.
%
% OUTPUTS
% dr [matlab structure] Decision rules for stochastic simulations.
% aimcode [integer] 1: the model defines variables uniquely
% aimcode is resolved in AIMerr as
% (c==1) e='Aim: unique solution.';
% (c==2) e='Aim: roots not correctly computed by real_schur.';
% (c==3) e='Aim: too many big roots.';
% (c==35) e='Aim: too many big roots, and q(:,right) is singular.';
% (c==4) e='Aim: too few big roots.';
% (c==45) e='Aim: too few big roots, and q(:,right) is singular.';
% (c==5) e='Aim: q(:,right) is singular.';
% (c==61) e='Aim: too many exact shiftrights.';
% (c==62) e='Aim: too many numeric shiftrights.';
% else e='Aimerr: return code not properly specified';
%
% SPECIAL REQUIREMENTS
% Dynare use:
% 1) the lognormal block in DR1 is being invoked for some models and changing
% values of ghx and ghy. We need to return the AIM output
% values before that block and run the block with the current returned values
% of gy (i.e. dr.ghx) and gu (dr.ghu) if it is needed even when the AIM is used
% (it does not depend on mjdgges output).
%
% 2) passing in aa={Q'|1}*jacobia_ can produce ~ one order closer
% results to the Dynare solutiion then when if plain jacobia_ is passed,
% i.e. diff < e-14 for aa and diff < *e-13 for jacobia_ if Q' is used.
%
% GP July 2008
% Copyright (C) 2008 Dynare Team
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>.
aimcode=-1;
neq= size(jacobia_,1); % no of equations
lags=M_.maximum_endo_lag; % no of lags and leads
leads=M_.maximum_endo_lead;
klen=(leads+lags+1); % total lenght
theAIM_H=zeros(neq, neq*klen); % alloc space
lli=M_.lead_lag_incidence';
% "sparse" the compact jacobia into AIM H aray of matrices
% without exogenous shoc
theAIM_H(:,find(lli(:)))=jacobia_(:,nonzeros(lli(:)));
condn = 1.e-10;%SPAmalg uses this in zero tests
uprbnd = 1 + 1.e-6;%allow unit roots
% forward only models - AIM must have at least 1 lead and 1 lag.
if lags ==0
theAIM_H =[zeros(neq) theAIM_H];
lags=1;
klen=(leads+lags+1);
end
% backward looking only models
if leads ==0
theAIM_H =[theAIM_H zeros(neq)];
leads=1;
klen=(leads+lags+1);
end
%disp('gensysToAMA:running ama');
try % try to run AIM
[bb,rts,ia,nexact,nnumeric,lgroots,aimcode] =...
SPAmalg(theAIM_H,neq, lags,leads,condn,uprbnd);
catch
err = lasterror;
disp(['Dynare AIM Solver error:' sprintf('%s; ID:%s',err.message, err.identifier)]);
rethrow(lasterror);
end
if aimcode==1 %if OK
col_order=[];
for i =1:lags
col_order=[((i-1)*neq)+dr.order_var' col_order];
end
bb_ord= bb(dr.order_var,col_order); % derive ordered gy
% variables are present in the state space at the lag at which they
% appear and at all smaller lags. The are ordered from smaller to
% higher lag (reversed order of M_.lead_lag_incidence rows for lagged
% variables)
i_lagged_vars = flipud(cumsum(M_.lead_lag_incidence(1:M_.maximum_lag,dr.order_var),1))';
dr.ghx= bb_ord(:,find(i_lagged_vars(:))); % get columns reported in
% Dynare solution
if M_.exo_nbr % if there are exogenous shocks then derive gu for the shocks:
% get H0 and H+1=HM
% theH0= theAIM_H (:,M_.maximum_endo_lag*neq+1: (M_.maximum_endo_lag+1)*neq);
%theH0= theAIM_H (:,lags*neq+1: (lags+1)*neq);
% theHP= theAIM_H (:,(M_.maximum_endo_lag+1)*neq+1: (M_.maximum_endo_lag+2)*neq);
%theHP= theAIM_H (:,(lags+1)*neq+1: (lags+2)*neq);
theAIM_Psi= - jacobia_(:, size(nonzeros(lli(:)))+1:end);%
%? = inv(H0 + H1B1)
%phi= (theH0+theHP*sparse(bb(:,(lags-1)*neq+1:end)))\eye( neq);
%AIM_ghu=phi*theAIM_Psi;
%dr.ghu =AIM_ghu(dr.order_var,:); % order gu
% Using AIM SPObstruct
scof = SPObstruct(theAIM_H,bb,neq,lags,leads);
scof1= scof(:,(lags)*neq+1:end);
scof1= scof1(:,dr.order_var);
dr.ghu =scof1\theAIM_Psi;
else
dr.ghu = [];
end
else
err=SPAimerr(aimcode);
%warning('Error in AIM: aimcode=%d, erro=%s', aimcode, err);;
disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
if aimcode < 1 || aimcode > 5 % too big exception, use mjdgges
error('Error in AIM: aimcode=%d ; %s', aimcode, err);
end
% if aimcode > 5
% disp(['Error in AIM: aimcode=' sprintf('%d : %s',aimcode, err)]);
% aimcode=5;
% end
end
function [ErrorCode] = AnalyseComputationalEnviroment(DataInput)
% Input/Output description:
%
% DataInput is the strcture option_.parallel, with the follow fields:
%
% Local Define the computation place: 1 is on local machine, 0 remote
% PcName Intuitive: contain the computer name.
% NumCPU Intuitive: contain the CPU number.
% user Intuitive: contain the use name for the PcName.
% passwd Intuitive: contain the password for the user name in PcName.
% RemoteDrive Drive used for Local/Remote computation (data exchange, etc) must be contain 'RemoteFolder'.
% RemoteFolder Folder in RemoteDrive used for Local/Remote computation.
%
% This information is typed by the user using the *.mod file,
% the goal of this function is to check if it correct.
%
%
% The variable ErrorCode is initialized at 0. If there are non problems with
% Local, PcName connections,... in general with parallel software execution,
% the ErrorCode is unchanged, in the others cases 1, 2 , ... The values
% table is below.
%
%
% Table for ErrorCode Values.
%
% ErrorCode -> 0 Initial Value -> No Error Detected!!!
% ErrorCode -> > 1 When an error happens. The value 1, 2, 3... are
% used to specify the kind of error.
%
% Value 1: The variable 'Local' has a bad value!
%
% Value 2: The variable 'NumCPU' has a bad value. Parallel Dynare
% require an input data like [s:d] with s<=d, in this case we
% have s>d!
% 2.1 The user asks to use more CPU of those available.
% 2.2 There are CPU not used!
%
% Value 3: The remote computer is unreachable!!!
%
% Value 4: The user name and/or password is/are incorrect on the
% remote computer!
%
% Value 5: It is impossible write/read file on remote computer.
%
% Then at the point call of this function it is possible react in a best way, in accord
% with the ErrorCode.
% Copyright (C) 2009 Dynare Team
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>.
ErrorCode=0;
% The function is composed by two main blocks, determined by the 'Local'
% variable.
if ((DataInput.Local == 0) |(DataInput.Local == 1))
% Continue it is Ok!
else
ErrorCode=1;
return
end
%%%%%%%%%% Local Machine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% In this case we need to check only the variable 'NumCPU'.
% We run the parallel code on local computer, so the others fields are automatically
% fixed by Dynare. Then the user can also fill them with wrong values.
if (DataInput.Local == 1)
yn=isempty(DataInput.NumCPU);
if yn==1
ErrorCode=2;
return
end
% We look for the information on local computer hardware.
si=[];
de=[];
[si de]=system(['psinfo \\']);
RealNumCPU=-1;
RealNumCPU=GiveCPUnumber(de);
% Trasforming the input data provided in a form [n1:n2] in a single numerical
% value.
DataInput.NumCPU=length(DataInput.NumCPU);
if DataInput.NumCPU == RealNumCPU
% It is Ok!
end
if DataInput.NumCPU > RealNumCPU
ErrorCode=2.1;
end
if DataInput.NumCPU < RealNumCPU
ErrorCode=2.2;
end
end
%%%%%%%%%% Remote Machine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% In this case we need more sophisticated check.
if (DataInput.Local == 0)
si=[];
de=[];
[si de]=system(['ping ', DataInput.PcName]);
if si==1
% It is impossiblie to be connected to the
% remote computer.
ErrorCode=3;
return;
end
% -> IL CODICE SEGUENTE E' DA CONTROLLARE E VERIFICARE!
% The Local Machine can be connetted with Remote Computer.
% Now we verify if user name and password are correct and if remote
% drive and remote folder exist on the remote computer and it is
% possible to exchange data with them.
si=[];
de=[];
[si de]=system(['psinfo \\', DataInput.PcName, ' -u ',DataInput.user, ' -p ',DataInput.passwd ]);
if si<0
% It is possible to be connected to the remote computer but it is not usable because the user
% name and/or password is/are incorrect.
ErrorCodeComputer=4;
return;
else
% Username and Password are correct!
end
% Now we verify if it possible to exchange data with the remote
% computer:
fid = fopen('Tracing.txt','w+');
fclose (fid);
% ATTENZIONE: verificare perche sembra funzionare anche se il RemoteFolder non
% esiste.
Status=movefile('Tracing.txt', ['\\',DataInput.PcName,'\',DataInput.RemoteDrive,'$\',DataInput.RemoteFolder]);
if Status==1
% Remote Drive/Folder exist on Remote computer and
% it is possible to exchange data with him.
else
% Move file error!
ErrorCodeComputer=5;
return;
end
% At this point we can to analyze the remote computer hardware.
RealNumCPU=-1;
RealNumCPU=GiveCPUnumber(de);
% Trasforming the input data provided in a form [n1:n2] in a single numerical
% value.
DataInput.NumCPU=length(DataInput.NumCPU);
if DataInput.NumCPU == RealNumCPU
% It is Ok!
end
if DataInput.NumCPU > RealNumCPU
ErrorCode=2.1;
end
if DataInput.NumCPU < RealNumCPU
ErrorCode=2.2;
end
end
function [ErrorCode] = AnalyseComputationalEnviroment(DataInput)
% Input/Output description:
%
% DataInput is the strcture option_.parallel, with the follow fields:
%
% Local Define the computation place: 1 is on local machine, 0 remote
% PcName Intuitive: contain the computer name.
% NumCPU Intuitive: contain the CPU number.
% user Intuitive: contain the use name for the PcName.
% passwd Intuitive: contain the password for the user name in PcName.
% RemoteDrive Drive used for Local/Remote computation (data exchange, etc) must be contain 'RemoteFolder'.
% RemoteFolder Folder in RemoteDrive used for Local/Remote computation.
%
% This information is typed by the user using the *.mod file,
% the goal of this function is to check if it correct.
%
%
% The variable ErrorCode is initialized at 0. If there are non problems with
% Local, PcName connections,... in general with parallel software execution,
% the ErrorCode is unchanged, in the others cases 1, 2 , ... The values
% table is below.
%
%
% Table for ErrorCode Values.
%
% ErrorCode -> 0 Initial Value -> No Error Detected!!!
% ErrorCode -> > 1 When an error happens. The value 1, 2, 3... are
% used to specify the kind of error.
%
% Value 1: The variable 'Local' has a bad value!
%
% Value 2: The variable 'NumCPU' has a bad value. Parallel Dynare
% require an input data like [s:d] with s<=d, in this case we
% have s>d!
% 2.1 The user asks to use more CPU of those available.
% 2.2 There are CPU not used!
%
% Value 3: The remote computer is unreachable!!!
%
% Value 4: The user name and/or password is/are incorrect on the
% remote computer!
%
% Value 5: It is impossible write/read file on remote computer.
%
% Then at the point call of this function it is possible react in a best way, in accord
% with the ErrorCode.
% Copyright (C) 2009 Dynare Team
%
% This file is part of Dynare.
%
% Dynare 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.
%
% Dynare 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 Dynare. If not, see <http://www.gnu.org/licenses/>.
ErrorCode=0;
% The function is composed by two main blocks, determined by the 'Local'
% variable.
if ((DataInput.Local == 0) |(DataInput.Local == 1))
% Continue it is Ok!
else
ErrorCode=1;
return
end
%%%%%%%%%% Local Machine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% In this case we need to check only the variable 'NumCPU'.