dynare.m 9.62 KB
Newer Older
michel's avatar
michel committed
1
function dynare(fname, varargin)
2
3
%       This command runs dynare with specified model file in argument
%       Filename.
4
%       The name of model file begins with an alphabetic character,
5
6
7
%       and has a filename extension of .mod or .dyn.
%       When extension is omitted, a model file with .mod extension
%       is processed.
assia's avatar
assia committed
8
9
10
11
%
% INPUTS
%   fname:      file name
%   varargin:   list of arguments following fname
12
%
assia's avatar
assia committed
13
14
% OUTPUTS
%   none
15
%
assia's avatar
assia committed
16
17
% SPECIAL REQUIREMENTS
%   none
18

19
% Copyright (C) 2001-2019 Dynare Team
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
%
% 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/>.
sebastien's avatar
sebastien committed
35

36
if ~nargin || strcmpi(fname,'help')
37
    skipline()
38
    disp(['This is Dynare version ' dynare_version() '.'])
39
    skipline()
40
    disp('USAGE: dynare FILENAME[.mod,.dyn] [OPTIONS]')
41
    skipline()
42
    disp('The dynare command executes instruction included in FILENAME.mod.')
43
    disp('See the reference manual for the available options.')
44
    skipline()
45
46
47
    return
end

48
49
50
51
% Set default local options
change_path_flag = true;

% Filter out some options.
52
preprocessoroutput = true;
53
if nargin>1
54
55
    id = ismember(varargin, 'nopathchange');
    if any(id)
56
        change_path_flag = false;
57
        varargin(id) = [];
58
    end
59
    preprocessoroutput = ~ismember('nopreprocessoroutput', varargin);
60
61
62
63
64
65
end

% Check matlab path
check_matlab_path(change_path_flag);

% Detect if MEX files are present; if not, use alternative M-files
66
dynareroot = dynare_config();
67

68
warning_config()
sebastien's avatar
v4:    
sebastien committed
69

70
if isoctave
71
72
73
    % The supported_octave_version.m file is not in git nor in the source
    % package, it is manually added in binary packages distributed on dynare.org
    if exist('supported_octave_version', 'file') && ~strcmp(supported_octave_version, version)
74
75
        skipline()
        warning(['This version of Octave is not supported. Consider installing ' ...
76
77
78
                 'version %s of Octave\n' ...
                 'from www.octave.org, otherwise m files will be used instead ' ...
                 'of precompiled mex files and some\nfeatures, like solution ' ...
79
80
                 'of models approximated at third order, will not be available.'], supported_octave_version())
        skipline()
81
    elseif octave_ver_less_than('4.4') % Should match the test in mex/build/octave/configure.ac
82
        skipline()
83
        warning(['This version of Dynare has only been tested on Octave 4.4 and above. Dynare may fail to run or give unexpected result. Consider upgrading your version of Octave.'])
84
        skipline()
85
86
    end
else
87
    if matlab_ver_less_than('7.9') % Should match the test in mex/build/matlab/configure.ac
88
                                   % and in m4/ax_mexopts.m4
89
        skipline()
90
        warning('This version of Dynare has only been tested on MATLAB 7.9 (R2009b) and above. Since your MATLAB version is older than that, Dynare may fail to run, or give unexpected results. Consider upgrading your MATLAB installation, or switch to Octave.');
91
        skipline()
92
    end
sebastien's avatar
v4:    
sebastien committed
93
94
95
end

% disable output paging (it is on by default on Octave)
96
97
98
more off

% sets default format for save() command
99
if isoctave
100
    save_default_options('-mat')
101
102
end

sebastien's avatar
sebastien committed
103
if nargin < 1
104
    error('Dynare: you must provide the name of the .mod file in argument')
michel's avatar
michel committed
105
end
sebastien's avatar
sebastien committed
106

sebastien's avatar
sebastien committed
107
if ~ischar(fname)
108
    error('Dynare: argument of dynare must be a text string')
sebastien's avatar
sebastien committed
109
end
sebastien's avatar
sebastien committed
110

Stéphane Adjemian's avatar
Stéphane Adjemian committed
111
% Testing if filename has more than one period (not allowed).
112
dot_location=strfind(fname,'.');
113
if length(dot_location)>1
114
    error('Dynare: Periods in filenames are only allowed for .mod or .dyn extensions')
115
116
117
end

if dot_location==length(fname)
118
    error('Dynare: Periods in filenames are only allowed for .mod or .dyn extensions')
119
120
end

Stéphane Adjemian's avatar
Stéphane Adjemian committed
121
% Add dyn or mod extension to the file name if not already provided.
122
if isempty(dot_location)
123
    fnamelength = length(fname);
124
125
126
127
128
129
    fname1 = [fname '.dyn'];
    d = dir(fname1);
    if length(d) == 0
        fname1 = [fname '.mod'];
    end
    fname = fname1;
michel's avatar
michel committed
130
else
Stéphane Adjemian's avatar
Stéphane Adjemian committed
131
    % Check provided file extension.
132
    if ~strcmpi(fname(dot_location+1:end), 'mod') && ~strcmpi(fname(dot_location+1:end), 'dyn')
133
        error('Dynare: argument must be a filename with .mod or .dyn extensions')
134
    end
135
    fnamelength = length(fname) - 4;
136
end
137

138
if fnamelength + length('.set_auxiliary_variables') > namelengthmax()
139
    error('Dynare: the name of your .mod file is too long, please shorten it')
140
141
end

142
143
144
145
146
147
148
149
% Workaround for a strange bug with Octave: if there is any call to exist(fname)
% before the call to the preprocessor, then Octave will use the old copy of
% the .m instead of the newly generated one. Deleting the .m beforehand
% fixes the problem.
if isoctave && length(dir([fname(1:(end-4)) '.m'])) > 0
    delete([fname(1:(end-4)) '.m'])
end

150
if ~isempty(strfind(fname,filesep))
151
    fprintf('\nIt seems you are trying to call a .mod file not located in the "Current Folder". This is not possible (the %s symbol is not allowed in the name of the .mod file).\n', filesep)
Houtan Bastani's avatar
Houtan Bastani committed
152
    [pathtomodfile,basename] = fileparts(fname);
153
154
155
156
157
    if exist(pathtomodfile,'dir')
        filesindirectory = dir(pathtomodfile);
        filesindirectory = struct2cell(filesindirectory);
        filesindirectory = filesindirectory(1,:);
        if ~isempty(strmatch([basename '.mod'],filesindirectory)) || ~isempty(strmatch([basename '.dyn'],filesindirectory))
158
            fprintf('Please set your "Current Folder" to the folder where the .mod file is located using the following command:\n')
159
160
161
162
163
            fprintf('\n  >> cd %s\n\n',pathtomodfile)
        else
            fprintf('The file %s[.mod,.dyn] could not be located!\n\n',basename)
        end
    end
164
    error(['Dynare: can''t open ' fname, '.'])
165
166
167
end

if ~exist(fname,'file') || isequal(fname,'dir')
168
169
    fprintf('\nThe file %s could not be located in the "Current Folder". Check whether you typed in the correct filename\n',fname)
    fprintf('and whether the file is really located in the "Current Folder".\n')
170
171
    try
        list_of_mod_files = ls('*.mod');
172
        fprintf('\nCurrent folder is %s, and contains the following .mod files:\n\n',pwd)
173
174
        disp(list_of_mod_files)
    catch
175
        fprintf('\nCurrent folder is %s, and does not contain any .mod files.\n\n',pwd)
176
    end
177
    error(['Dynare: can''t open ' fname])
178
end
179

180
if ~isvarname(fname(1:end-4))
181
    error('Dynare: argument of dynare must conform to MATLAB''s convention for naming functions, i.e. start with a letter and not contain special characters. Please rename your .mod file.')
182
183
end

184
% pre-dynare-preprocessor-hook
185
186
if exist(fname(1:end-4),'dir') && exist([fname(1:end-4) filesep 'hooks'],'dir') && exist([fname(1:end-4) filesep 'hooks/priorprocessing.m'],'file')
    run([fname(1:end-4) filesep 'hooks/priorprocessing'])
187
188
end

189
if ispc
190
    arch = getenv('PROCESSOR_ARCHITECTURE');
191
else
192
    [~, arch] = system('uname -m');
193
194
195
end

if isempty(strfind(arch, '64'))
196
    arch_ext = '32';
197
198
199
    if preprocessoroutput
        disp('Using 32-bit preprocessor');
    end
200
else
201
    arch_ext = '64';
202
203
204
    if preprocessoroutput
        disp('Using 64-bit preprocessor');
    end
205
206
end

Houtan Bastani's avatar
Houtan Bastani committed
207
command = ['"' dynareroot 'preprocessor' arch_ext filesep 'dynare_m" ' fname] ;
208
command = [ command ' mexext=' mexext ' "matlabroot=' matlabroot '"'];
Houtan Bastani's avatar
Houtan Bastani committed
209
210
211
if ~isempty(varargin)
    dynare_varargin = strjoin(varargin);
    command = [command ' ' dynare_varargin];
michel's avatar
michel committed
212
end
213

214
if preprocessoroutput
215
    fprintf(['Starting Dynare (version ' dynare_version() ').\n']);
216
    fprintf('Calling Dynare with arguments: ');
217
218
    if isempty(varargin)
        disp('none')
219
    else
Houtan Bastani's avatar
Houtan Bastani committed
220
        disp(dynare_varargin);
221
    end
222
end
223

224
225
226
% Under Windows, make sure the MEX file is unloaded (in the use_dll case),
% otherwise the preprocessor can't recompile it
if isoctave
227
    clear([fname(1:end-4) '.static'], [fname(1:end-4) '.dynamic'])
228
else
229
    clear(['+' fname(1:end-4) '/static'], ['+' fname(1:end-4) '/dynamic'])
230
231
end

michel's avatar
michel committed
232
[status, result] = system(command);
233
234
235
if status ~= 0 || preprocessoroutput
    disp(result)
end
236
if ismember('onlymacro', varargin)
237
    if preprocessoroutput
Sébastien Villemot's avatar
Sébastien Villemot committed
238
        disp('Preprocessor stopped after macroprocessing step because of ''onlymacro'' option.');
239
    end
240
    return
241
end
242

243
if ismember('onlyjson', varargin)
244
    if preprocessoroutput
Sébastien Villemot's avatar
Sébastien Villemot committed
245
        disp('Preprocessor stopped after preprocessing step because of ''onlyjson'' option.');
246
    end
247
248
249
    return;
end

250
% post-dynare-prerocessor-hook
251
252
if exist(fname(1:end-4),'dir') && exist([fname(1:end-4) filesep 'hooks'],'dir') && exist([fname(1:end-4) filesep 'hooks/postprocessing.m'],'file')
    run([fname(1:end-4) filesep 'hooks/postprocessing'])
253
254
end

255
% Save preprocessor result in logfile (if `no_log' option not present)
256
257
258
fid = fopen(fname, 'r');
firstline = fgetl(fid);
fclose(fid);
Houtan Bastani's avatar
Houtan Bastani committed
259
260
if ~ismember('nolog', varargin) ...
        && isempty(regexp(firstline, '//\s*--\+\s*options:(|.*\s|.*,)nolog(|\s.*|,.*)\+--'))
261
    logname = [fname(1:end-4) '.log'];
Houtan Bastani's avatar
Houtan Bastani committed
262
    fid = fopen(logname, 'w');
263
    fprintf(fid, '%s', result);
264
265
266
    fclose(fid);
end

michel's avatar
michel committed
267
if status
268
    % Should not use "error(result)" since message will be truncated if too long
269
    error('Dynare: preprocessing failed')
michel's avatar
michel committed
270
271
272
end

if ~ isempty(find(abs(fname) == 46))
273
    fname = fname(:,1:find(abs(fname) == 46)-1) ;
michel's avatar
michel committed
274
end
275
276
277
278
279

% We need to clear the driver (and only the driver, because the "clear all"
% within the driver will clean the rest)
clear(['+' fname '/driver'])

280
evalin('base',[fname '.driver']) ;