Code covered by the BSD License

# Automatic Solution and Log Linearisation of DSGE Models

### Tom Holden (view profile)

06 Jun 2011 (Updated )

Code to analytically log linearise DSGE models in Matlab. Requires the symbolic toolbox.

LogLin.m
```function result = LogLin( VarEndoNames, VarExoNames, Parameters, Equations, SolveMode, EvalMode, EvalString, Digits )
% ------------------------------------------------------------
% PURPOSE:	Performs log-linearisation.
% ------------------------------------------------------------
% SYNTAX:	result = LogLin( VarEndoNames, VarExoNames, Parameters, Equations, SolveMode, EvalMode, EvalString, Digits );
% ------------------------------------------------------------
% EXAMPLE:	result = LogLin( { 'R', 'A' }, { 'EPSILON' }, { 'beta', 'rho' }, { 'beta * R * A / A(+1) = 1', 'A = A(-1) ^ rho * exp( EPSILON )' }, 2, 2 )
% ------------------------------------------------------------
% OUTPUT:	result:		a cell array of log-linearised equations, with __d appended to variable names that are deviations from steady state.
% ------------------------------------------------------------
% INPUT:	VarEndoNames:	a cell array of endogenous variable names
%			VarExoNames:	a cell array of exogenous variable names
%			Parameters:		a cell array of parameter names
%			Equations:		a cell array of equations, in Dynare notation
%			SolveMode:		specifies how the steady state is found
%				SolveMode = 1	---> the steady state is found analytically
%				SolveMode = 2	---> the steady state is found analytically, allowing all algebraic manipulations
%				SolveMode = 3	---> the steady state is found analytically, assuming real values
%				SolveMode = 4	---> the steady state is found numerically
%			EvalMode:		specifies any processing of the found equations
%				EvalMode = 0	---> no additional processing
%				EvalMode = 1	---> simplification
%				EvalMode = 2	---> simplification, allowing all algebraic manipulations
%				EvalMode = 3	---> numeric evaluation, to Digits precision
%			EvalString:		string of comma delimited equations, useful for	specifying parameters or your own computed steady state values (e.g. 'beta=0.99,rho=1/2', or 'A=1')
%        	Digits:		(optional) the number of digits of accuracy for numerical compuations
% ------------------------------------------------------------
% Copyright  2011 Tom Holden ( http://www.tholden.org/ )
% ------------------------------------------------------------
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     * Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%     * Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
% ------------------------------------------------------------

if nargin < 6
error( 'Insufficient arguments provided to LogLin.' );
end

nl = sprintf( '\n' );

ProcessedEquations = cell( size( Equations ) );
SteadyEquations = cell( size( Equations ) );
TempVarNames = [ VarEndoNames VarExoNames ];

Comma = '';

for VarEndoName = VarEndoNames
Comma = ', ';
end
for VarExoName = VarExoNames
end

AllLagsAndLeads = cell( 1, 0 );
SteadyStateEquationsTmp = cell( 1, 0 );

for i = 1:length( Equations )
SFEquation = [ ' ' Equations{i} ' ' ];
for Parameter = Parameters
SFEquation = regexprep( SFEquation, [ '(?<=\W)' Parameter{1} '(?=\W)' ], [ '__' Parameter{1} '__' ] );
end
SFEquation = regexprep( SFEquation, '(?<=\W)log(?=\W)', 'ln' );
SFEquation = regexprep( SFEquation, '\s', '' );
SFEquation = regexprep( SFEquation, '=(.*)', '-(\$1)' );
LagsAndLeads = unique( cellfun( @cellstr, regexp( SFEquation, '\w\(([+-]?\d+)\)', 'tokens' ) ) );
ProcessedEquation = SFEquation;
ReplaceString = [ '__' repmat( 'f', 1, NLagOrLead ) ];
else
ReplaceString = [ '__' repmat( 'b', 1, -NLagOrLead ) ];
else
ReplaceString = '';
end
end
ProcessedEquation = regexprep( ProcessedEquation, [ '(\w+)\(' TLagOrLead '\)' ], [ '\$1' ReplaceString ] );
TempVarNames = unique( [ TempVarNames cellfun( @cellstr, regexp( ProcessedEquation, [ '(\w+' ReplaceString ')' ], 'tokens' ) ) ] );

for VarEndoName = VarEndoNames
SteadyStateEquationsTmp = [ SteadyStateEquationsTmp [ VarEndoName{1} ReplaceString '__s := ' VarEndoName{1} '__s;' ] ];
end
for VarExoName = VarExoNames
SteadyStateEquationsTmp = [ SteadyStateEquationsTmp [ VarExoName{1} ReplaceString '__s := 0;' ] ];
end
end
ProcessedEquations{i} = ProcessedEquation;
end

end

TempVarNamesList = '';
EvalLoc = '';
Comma = '';

for TempVarName = TempVarNames
TempVarNamesList = [ TempVarNamesList ' ' TempVarName{1} ];
EvalLoc = [ EvalLoc Comma TempVarName{1} ' = ' TempVarName{1} '__s' ];
Comma = ', ';
end

if nargin >= 7
NewEvalString = [ ' ' EvalString ' ' ];
for Parameter = Parameters
NewEvalString = regexprep( NewEvalString, [ '(?<=\W)' Parameter{1} '(?=\W)' ], [ '__' Parameter{1} '__' ] );
end
for VarEndoName = VarEndoNames
NewEvalString = regexprep( NewEvalString, [ '(?<=\W)' VarEndoName{1} '(?=\W)' ], [ VarEndoName{1} '__s' ] );
end
NewEvalString = regexprep( NewEvalString, '(?<=\W)log(?=\W)', 'ln' );
NewEvalString = regexprep( NewEvalString, '\s', '' );
MuPADStringPrefix = [ SteadyStateEquations 'EvalLoc := { ' EvalLoc Comma NewEvalString ' };' nl ];
else
MuPADStringPrefix = [ SteadyStateEquations 'EvalLoc := { ' EvalLoc ' };' nl ];
end

switch EvalMode
case 1
Prefix = 'simplify( ';
Suffix = ' )';
case 2
Prefix = 'simplify( ';
Suffix = ', IgnoreAnalyticConstraints )';
case 3
Prefix = 'float( ';
Suffix = ' )';
otherwise
Prefix = '';
Suffix = '';
end

if nargin >= 8
MuPADStringPrefix = [ MuPADStringPrefix 'DIGITS := ' int2str( Digits ) ';' nl ];
end

Comma = '';

for i = 1:length( Equations )
MuPADString = [ MuPADString 'eq__' int2str( i ) ' := ' Prefix 'evalAt( evalAt( ' ProcessedEquations{i} ' , EvalLoc ), EvalLocSteadyState )' Suffix ]; %#ok<*AGROW>
for TempVarName = TempVarNames
MuPADString = [ MuPADString ' + ' Prefix 'evalAt( evalAt( ' TempVarName{1} ' * diff( ' ProcessedEquations{i} ' , ' TempVarName{1} ' ), EvalLoc ), EvalLocSteadyState ) * ' lower( TempVarName{1} ) '__d' Suffix ];
end
Comma = ', ';
end

if SolveMode > 0
if SolveMode == 4
end
Comma = '';
for i = 1:length( Equations )
Comma = ', ';
end
switch SolveMode
case 2
SolveOption = ', IgnoreAnalyticConstraints';
case 3
SolveOption = ', Real';
otherwise
SolveOption = '';
end
MuPADStringPrefix = [ MuPADStringPrefix ' }, EvalLoc ), { ' SteadyStateVars ' } ' SolveOption ' );' nl ];
else
end
eqs = evalin( symengine, MuPADString );
result = cell( size( eqs ) );
for i = 1:length( eqs )
ResEq = char( eqs( i ) );
ReplaceString = [ '__' repmat( 'f', 1, NLagOrLead ) ];
else
ReplaceString = [ '__' repmat( 'b', 1, -NLagOrLead ) ];
else
ReplaceString = '';
end
end
ResEq = regexprep( ResEq, [ '(\w+)' ReplaceString '__d' ], [ '\$1__d(' LagOrLead{1} ')' ] );
end
for Parameter = Parameters
ResEq = regexprep( ResEq, [ '__' Parameter{1} '__' ], Parameter{1} );
end
ResEq = regexprep( ResEq, '(?<=\W)ln(?=\W)', 'log' );
result{i} = ResEq;
end
```