diff --git a/doc/dynare.texi b/doc/dynare.texi index f107bbf98..2bc260882 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -241,13 +241,19 @@ Stochastic solution and simulation Sensitivity and identification analysis +* Performing sensitivity analysis:: +* Performing identification analysis:: +* IRF/Moment calibration:: +* Types of analysis and output files:: + +Types of analysis and output files * Sampling:: * Stability Mapping:: +* IRF/Moment restrictions:: * Reduced Form Mapping:: * RMSE:: * Screening Analysis:: * Identification Analysis:: -* Performing Sensitivity and Identification Analysis:: Macro-processing language @@ -845,6 +851,14 @@ Allows Dynare to issue a warning and continue processing when @item there are more endogenous variables than equations @item an undeclared symbol is assigned in @code{initval} or @code{endval} @end enumerate + +@item fast +Only useful with model option @code{use_dll}. Don't recompile the MEX +files when running again the same model file and the lists of variables +and the equations haven't changed. We use a 32 bit checksum, stored in +@code{/checksum}. There is a very small probability that +the preprocessor misses a change in the model. In case of doubt, re-run +without the @code{fast} option. @end table @outputhead @@ -2331,7 +2345,7 @@ jump from t=200 to t=201. @end deffn @deffn Block histval ; - +@anchor{histval} @descriptionhead @customhead{In a deterministic perfect foresight context} @@ -2371,6 +2385,11 @@ affect the starting point for impulse response functions). As for the case of perfect foresight simulations, all not explicitly specified variables are set to 0. Moreover, as only states enter the recursive policy functions, all values specified for control variables will be ignored. +For @ref{Ramsey} policy, it also specifies the values of the endogenous states at +which the objective function of the planner is computed. Note that the initial values +of the Lagrange multipliers associated with the planner's problem cannot be set +(@pxref{planner_objective_value}). + @examplehead @example @@ -4660,6 +4679,11 @@ a @uref{http://www.java.com/download,Java Runtime Environment}). Note that the base name (ie without extension) of the datafile has to be different from the base name of the model file. +@item dirname = @var{FILENAME} +Directory in which to store @code{estimation} output. To pass a +subdirectory of a directory, you must quote the argument. Default: +@code{} + @item xls_sheet = @var{NAME} @anchor{xls_sheet} The name of the sheet with the data in an Excel file @@ -4848,10 +4872,11 @@ compute the smoothed value of the variables of a model with calibrated parameter @item 1 Uses @code{fmincon} optimization routine (available under MATLAB if -the optimization toolbox is installed; not available under Octave) +the Optimization Toolbox is installed; not available under Octave) @item 2 -Value no longer used +Uses the continuous simulated annealing global optimization algorithm +described in @cite{Corana et al. (1987)} and @cite{Goffe et al. (1994)}. @item 3 Uses @code{fminunc} optimization routine (available under MATLAB if @@ -4885,12 +4910,21 @@ routine (generally more efficient than the MATLAB or Octave implementation available with @code{mode_compute=7}) @item 9 -Uses the CMA-ES (Covariance Matrix Adaptation Evolution Strategy) algorithm, an evolutionary algorithm for difficult non-linear non-convex optimization +Uses the CMA-ES (Covariance Matrix Adaptation Evolution Strategy) algorithm of +@cite{Hansen and Kern (2004)}, an evolutionary algorithm for difficult non-linear non-convex optimization @item 10 Uses the simpsa algorithm, based on the combination of the non-linear simplex and simulated annealing algorithms and proposed by @cite{Cardoso, Salcedo and Feyo de Azevedo (1996)}. +@item 101 +Uses the SolveOpt algorithm for local nonlinear optimization problems proposed by +@cite{Kuntsevich and Kappel (1997)}. + +@item 102 +Uses @code{simulannealbnd} optimization routine (available under MATLAB if +the Global Optimization Toolbox is installed; not available under Octave) + @item @var{FUNCTION_NAME} It is also possible to give a @var{FUNCTION_NAME} to this option, instead of an @var{INTEGER}. In that case, Dynare takes the return @@ -4961,13 +4995,54 @@ A list of @var{NAME} and @var{VALUE} pairs. Can be used to set options for the o @table @code @item 1, 3, 7 -Available options are given in the documentation of the MATLAB optimization toolbox or in Octave's documentation. +Available options are given in the documentation of the MATLAB Optimization Toolbox or in Octave's documentation. + +@item 2 +Available options are: + +@table @code + +@item 'initial_step_length' +Initial step length. Default: @code{1} + +@item 'initial_temperature' +Initial temperature. Default: @code{15} + +@item 'MaxIter' +Maximum number of function evaluations. Default: @code{100000} + +@item 'neps' +Number of final function values used to decide upon termination. Default: @code{10} + +@item 'ns' +Number of cycles. Default: @code{10} + +@item 'nt' +Number of iterations before temperature reduction. Default: @code{10} + +@item 'step_length_c' +Step length adjustment. Default: @code{0.1} + +@item 'TolFun' +Stopping criteria. Default: @code{1e-8} + +@item 'rt' +Temperature reduction factor. Default: @code{0.1} + +@item 'verbosity' +Controls verbosity of display during optimization, ranging from 0 (silent) to 3 +(each function evaluation). Default: @code{1} + +@end table @item 4 Available options are: @table @code +@item 'InitialInverseHessian' +Initial approximation for the inverse of the Hessian matrix of the posterior kernel (or likelihood). Obviously this approximation has to be a square, positive definite and symmetric matrix. Default: @code{'1e-4*eye(nx)'}, where @code{nx} is the number of parameters to be estimated. + @item 'MaxIter' Maximum number of iterations. Default: @code{1000} @@ -4980,9 +5055,6 @@ Size of the perturbation used to compute numerically the gradient of the objecti @item 'TolFun' Stopping criteria. Default: @code{1e-7} -@item 'InitialInverseHessian' -Initial approximation for the inverse of the Hessian matrix of the posterior kernel (or likelihood). Obviously this approximation has to be a square, positive definite and symmetric matrix. Default: @code{'1e-4*eye(nx)'}, where @code{nx} is the number of parameters to be estimated. - @end table @item 5 @@ -4990,15 +5062,15 @@ Available options are: @table @code -@item 'MaxIter' -Maximum number of iterations. Default: @code{1000} - @item 'Hessian' Triggers three types of Hessian computations. @code{0}: outer product gradient; @code{1} default DYNARE Hessian routine; @code{2} 'mixed' outer product gradient, where diagonal elements are obtained using second order derivation formula and outer product is used for correlation structure. Both @{0@} and @{2@} options require univariate filters, to ensure using maximum number of individual densities and a positive definite Hessian. Both @{0@} and @{2@} are quicker than default DYNARE numeric Hessian, but provide decent starting values for Metropolis for large models (option @{2@} being more accurate than @{0@}). Default: @code{1}. +@item 'MaxIter' +Maximum number of iterations. Default: @code{1000} + @item 'TolFun' Stopping criteria. Default: @code{1e-5} for numerical derivatives @code{1e-7} for analytic derivatives. @@ -5009,8 +5081,14 @@ Available options are: @table @code -@item 'NumberOfMh' -Number of MCMC run sequentially. Default: @code{3} +@item 'AcceptanceRateTarget' +A real number between zero and one. The scale parameter of the jumping distribution is adjusted so that the effective acceptance rate matches the value of option @code{'AcceptanceRateTarget'}. Default: @code{1.0/3.0} + +@item 'InitialCovarianceMatrix' +Initial covariance matrix of the jumping distribution. Default is @code{'previous'} if option @code{mode_file} is used, @code{'prior'} otherwise. + +@item 'nclimb' +Number of iterations in the last MCMC (climbing mode). @item 'ncov-mh' Number of iterations used for updating the covariance matrix of the jumping distribution. Default: @code{20000} @@ -5018,14 +5096,8 @@ Number of iterations used for updating the covariance matrix of the jumping dist @item 'nscale-mh' Maximum number of iterations used for adjusting the scale parameter of the jumping distribution. @code{200000} -@item 'nclimb' -Number of iterations in the last MCMC (climbing mode). - -@item 'InitialCovarianceMatrix' -Initial covariance matrix of the jumping distribution. Default is @code{'previous'} if option @code{mode_file} is used, @code{'prior'} otherwise. - -@item 'AcceptanceRateTarget' -A real number between zero and one. The scale parameter of the jumping distribution is adjusted so that the effective acceptance rate matches the value of option @code{'AcceptanceRateTarget'}. Default: @code{1.0/3.0} +@item 'NumberOfMh' +Number of MCMC run sequentially. Default: @code{3} @end table @@ -5034,6 +5106,9 @@ Available options are: @table @code +@item 'InitialSimplexSize' +Initial size of the simplex, expressed as percentage deviation from the provided initial guess in each direction. Default: @code{.05} + @item 'MaxIter' Maximum number of iterations. Default: @code{5000} @@ -5049,10 +5124,6 @@ Tolerance parameter (w.r.t the objective function). Default: @code{1e-4} @item 'TolX' Tolerance parameter (w.r.t the instruments). Default: @code{1e-4} -@item 'InitialSimplexSize' - -Initial size of the simplex, expressed as percentage deviation from the provided initial guess in each direction. Default: @code{.05} - @end table @item 9 @@ -5079,6 +5150,9 @@ Available options are: @table @code +@item 'EndTemperature' +Terminal condition w.r.t the temperature. When the temperature reaches @code{EndTemperature}, the temperature is set to zero and the algorithm falls back into a standard simplex algorithm. Default: @code{.1} + @item 'MaxIter' Maximum number of iterations. Default: @code{5000} @@ -5091,11 +5165,33 @@ Tolerance parameter (w.r.t the objective function). Default: @code{1e-4} @item 'TolX' Tolerance parameter (w.r.t the instruments). Default: @code{1e-4} -@item 'EndTemperature' -Terminal condition w.r.t the temperature. When the temperature reaches @code{EndTemperature}, the temperature is set to zero and the algorithm falls back into a standard simplex algorithm. Default: @code{.1} +@end table + +@item 101 +Available options are: + +@table @code + +@item 'LBGradientStep' +Lower bound for the stepsize used for the difference approximation of gradients. Default: @code{1e-11} + +@item 'MaxIter' +Maximum number of iterations. Default: @code{15000} + +@item 'SpaceDilation' +Coefficient of space dilation. Default: @code{2.5} + +@item 'TolFun' +Tolerance parameter (w.r.t the objective function). Default: @code{1e-6} + +@item 'TolX' +Tolerance parameter (w.r.t the instruments). Default: @code{1e-6} @end table +@item 102 +Available options are given in the documentation of the MATLAB Global Optimization Toolbox. + @end table @customhead{Example 1} @@ -6459,7 +6555,7 @@ new, expanded model. Alternatively, you can either solve for optimal policy under commitment with @code{ramsey_policy}, for optimal policy under discretion with @code{discretionary_policy} or for optimal simple rule with -@code{osr}. +@code{osr} (also implying commitment). @anchor{osr} @@ -6649,7 +6745,7 @@ at the optimum, stored in fields of the form @descriptionhead This command computes the First Order Conditions for maximizing the policy maker objective function subject to the -constraints provided by the equilibrium path of the economy. +constraints provided by the equilibrium path of the private economy. The planner objective must be declared with the @code{planner_objective} command. @@ -6679,6 +6775,7 @@ under optimal policy. Requires a @code{steady_state_model} block or a @end table @customhead{Steady state} +@anchor{Ramsey steady state} Dynare takes advantage of the fact that the Lagrange multipliers appear linearly in the equations of the steady state of the model under optimal @@ -6703,12 +6800,32 @@ instrument. @deffn Command ramsey_policy [@var{VARIABLE_NAME}@dots{}]; @deffnx Command ramsey_policy (@var{OPTIONS}@dots{}) [@var{VARIABLE_NAME}@dots{}]; +@anchor{ramsey_policy} @descriptionhead This command computes the first order approximation of the policy that -maximizes the policy maker objective function submitted to the -constraints provided by the equilibrium path of the economy. +maximizes the policy maker's objective function subject to the +constraints provided by the equilibrium path of the private economy and under +commitment to this optimal policy. Following @cite{Woodford (1999)}, the Ramsey +policy is computed using a timeless perspective. That is, the government forgoes +its first-period advantage and does not exploit the preset privates sector expectations +(which are the source of the well-known time inconsistency that requires the +assumption of commitment). Rather, it acts as if the initial multipliers had +been set to 0 in the distant past, giving them time to converge to their steady +state value. Consequently, the optimal decision rules are computed around this steady state +of the endogenous variables and the Lagrange multipliers. + +This first order approximation to the optimal policy conducted by Dynare is not to be +confused with a naive linear quadratic approach to optimal policy that can lead to +spurious welfare rankings (see @cite{Kim and Kim (2003)}). In the latter, the optimal policy +would be computed subject to the first order approximated FOCs of the +private economy. In contrast, Dynare first computes the FOCs of the Ramsey planner's problem +subject to the nonlinear constraints that are the FOCs of the private economy +and only then approximates these FOCs of planner's problem to first order. Thereby, the second +order terms that are required for a second-order correct welfare evaluation are +preserved. + The planner objective must be declared with the @code{planner_objective} command. @@ -6732,36 +6849,34 @@ under optimal policy. Requires a @code{steady_state_model} block or a @end table -Note that only first order approximation is available (@i{i.e.} -@code{order=1} must be specified). +Note that only a first order approximation of the optimal Ramsey policy is +available, leading to a second-order accurate welfare ranking +(@i{i.e.} @code{order=1} must be specified). @outputhead -This command generates all the output variables of @code{stoch_simul}. +This command generates all the output variables of @code{stoch_simul}. For specifying +the initial values for the endogenous state variables (except for the Lagrange +multipliers), @pxref{histval}. @vindex oo_.planner_objective_value +@anchor{planner_objective_value} + In addition, it stores the value of planner objective function under -Ramsey policy in @code{oo_.planner_objective_value}. +Ramsey policy in @code{oo_.planner_objective_value}, given the initial values +of the endogenous state variables. If not specified with @code{histval}, they are +taken to be at their steady state values. The result is a 1 by 2 +vector, where the first entry stores the value of the planner objective under +the timeless perspective to Ramsey policy, i.e. where the initial Lagrange +multipliers associated with the planner's problem are set to their steady state +values (@pxref{ramsey_policy}). +In contrast, the second entry stores the value of the planner objective with +initial Lagrange multipliers of the planner's problem set to 0, i.e. it is assumed +that the planner succumbs to the temptation to exploit the preset private expecatations +in the first period (but not in later periods due to commitment). @customhead{Steady state} - -Dynare takes advantage of the fact that the Lagrange multipliers appear -linearly in the equations of the steady state of the model under optimal -policy. Nevertheless, it is in general very difficult to compute the -steady state with simply a numerical guess in @code{initval} for the -endogenous variables. - -It greatly facilitates the computation, if the user provides an -analytical solution for the steady state (in @code{steady_state_model} -block or in a @code{@dots{}_steadystate.m} file). In this case, it is -necessary to provide a steady state solution CONDITIONAL on the value -of the instruments in the optimal policy problem and declared with -option @code{instruments}. Note that choosing the instruments is -partly a matter of interpretation and you can choose instruments that -are handy from a mathematical point of view but different from the -instruments you would refer to in the analysis of the paper. A typical -example is choosing inflation or nominal interest rate as an -instrument. +@xref{Ramsey steady state}. @end deffn @@ -6846,311 +6961,17 @@ With respect to the previous version of the toolbox, in order to work properly, the GSA toolbox no longer requires that the Dynare estimation environment is set up. -Sensitivity analysis results are saved locally in @code{/GSA}, -where @code{.mod} is the name of the DYNARE model file. @menu -* Sampling:: -* Stability Mapping:: -* Reduced Form Mapping:: -* RMSE:: -* Screening Analysis:: -* Identification Analysis:: -* Performing Sensitivity and Identification Analysis:: +* Performing sensitivity analysis:: +* Performing identification analysis:: +* IRF/Moment calibration:: +* Types of analysis and output files:: @end menu -@node Sampling -@subsection Sampling -The following binary files are produced: -@itemize -@item -@code{_prior.mat}: this file stores information about the analyses -performed sampling from the prior ranges, @i{i.e.} @code{pprior=1} and @code{ppost=0}; - -@item -@code{_mc.mat}: this file stores information about the analyses performed -sampling from multivariate normal, @i{i.e.} @code{pprior=0} and @code{ppost=0}; - -@item -@code{_post.mat}: this file stores information about analyses performed -using the Metropolis posterior sample, @i{i.e.} @code{ppost=1}. -@end itemize - -@node Stability Mapping -@subsection Stability Mapping - -Figure files produced are of the form @code{_prior_*.fig} and store results -for stability mapping from prior Monte-Carlo samples: -@itemize -@item -@code{_prior_stab_SA_*.fig}: plots of the Smirnov test analyses -confronting the cdf of the sample fulfilling Blanchard-Kahn conditions -with the cdf of the rest of the sample; - -@item -@code{_prior_stab_indet_SA_*.fig}: plots of the Smirnov test -analyses confronting the cdf of the sample producing indeterminacy -with the cdf of the original prior sample; - -@item -@code{_prior_stab_unst_SA_*.fig}: plots of the Smirnov test -analyses confronting the cdf of the sample producing unstable (explosive -roots) behavior with the cdf of the original prior sample; - -@item -@code{_prior_stable_corr_*.fig}: plots of bivariate projections -of the sample fulfilling Blanchard-Kahn conditions; - -@item -@code{_prior_indeterm_corr_*.fig}: plots of bivariate projections -of the sample producing indeterminacy; - -@item -@code{_prior_unstable_corr_*.fig}: plots of bivariate projections -of the sample producing instability; - -@item -@code{_prior_unacceptable_corr_*.fig}: plots of bivariate projections -of the sample producing unacceptable solutions, @i{i.e.} either -instability or indeterminacy or the solution could not be found (@i{e.g.} -the steady state solution could not be found by the solver). -@end itemize - -Similar conventions apply for @code{_mc_*.fig} files, obtained when -samples from multivariate normal are used. - -@node Reduced Form Mapping -@subsection Reduced Form Mapping - -The mapping of the reduced form solution forces the use of samples from -prior ranges or prior distributions, @i{i.e.}: @code{pprior=1} and @code{ppost=0}. It -uses 250 samples to optimize smoothing parameters and 1000 samples to compute the -fit. The rest of the sample is used for out-of-sample validation. One can also -load a previously estimated mapping with a new Monte-Carlo sample, to look at the -forecast for the new Monte-Carlo sample. - -The following synthetic figures are produced: -@itemize -@item -@code{_redform__vs_lags_*.fig}: shows bar charts -of the sensitivity indices for the ten most important parameters driving -the reduced form coefficients of the selected endogenous variables -(@code{namendo}) versus lagged endogenous variables (@code{namlagendo}); suffix -@code{log} indicates the results for log-transformed entries; - -@item -@code{_redform__vs_shocks_*.fig}: shows bar charts -of the sensitivity indices for the ten most important parameters driving -the reduced form coefficients of the selected endogenous variables -(@code{namendo}) versus exogenous variables (@code{namexo}); suffix @code{log} -indicates the results for log-transformed entries; - -@item -@code{_redform_GSA(_log).fig}: shows bar chart of all sensitivity -indices for each parameter: this allows one to notice parameters that -have a minor effect for any of the reduced form coefficients. -@end itemize - -Detailed results of the analyses are shown in the subfolder @code{/GSA/redform_stab}, -where the detailed results of the estimation of the single functional relationships -between parameters @math{\theta} and reduced form coefficient are stored in separate directories -named as: - -@itemize -@item -@code{_vs_}: for the entries of the transition matrix; - -@item -@code{_vs_}: for entries of the matrix of the shocks. -@end itemize -Moreover, analyses for log-transformed entries are denoted with the following -suffixes (@math{y} denotes the generic reduced form coefficient): -@itemize -@item -@code{log}: @math{y^* = \log(y)}; -@item -@code{minuslog}: @math{y^* = \log(-y)}; -@item -@code{logsquared}: @math{y^* = \log(y^2)} for symmetric fat tails; -@item -@code{logskew}: @math{y^* = \log(|y + \lambda|)} for asymmetric fat tails. -@end itemize -The optimal type of transformation is automatically selected without the -need of user intervention. - -@node RMSE -@subsection RMSE - -The RMSE analysis can be performed with different types of sampling options: -@enumerate -@item -When @code{pprior=1} and @code{ppost=0}, the toolbox analyzes the RMSEs for -the Monte-Carlo sample obtained by sampling parameters from their prior distributions -(or prior ranges): this analysis provides some hints about -what parameter drives the fit of which observed series, prior to the full -estimation; - -@item -When @code{pprior=0} and @code{ppost=0}, the toolbox analyzes the RMSEs for -a multivariate normal Monte-Carlo sample, with covariance matrix based on -the inverse Hessian at the optimum: this analysis is useful when maximum likelihood -estimation is done (@i{i.e.} no Bayesian estimation); - -@item -When @code{ppost=1} the toolbox analyzes the RMSEs for the posterior sample -obtained by Dynare's Metropolis procedure. -@end enumerate - -The use of cases 2 and 3 requires an estimation step beforehand. To -facilitate the sensitivity analysis after estimation, the @code{dynare_sensitivity} -command also allows you to indicate some options of the @code{estimation} -command. These are: -@itemize @bullet -@item @code{datafile} -@item @code{nobs} -@item @code{first_obs} -@item @code{prefilter} -@item @code{presample} -@item @code{nograph} -@item @code{nodisplay} -@item @code{graph_format} -@item @code{conf_sig} -@item @code{loglinear} -@item @code{mode_file} -@end itemize - -Binary files produced my RMSE analysis are: -@itemize -@item -@code{_prior_*.mat}: these files store the filtered and smoothed - variables for the prior Monte-Carlo sample, generated when doing RMSE analysis - (@code{pprior=1} and @code{ppost=0}); -@item -@code{_mc_*.mat}: these files store the filtered and smoothed variables - for the multivariate normal Monte-Carlo sample, generated when doing - RMSE analysis (@code{pprior=0} and @code{ppost=0}). -@end itemize - -Figure files @code{_rmse_*.fig} store results for the RMSE analysis. - -@itemize -@item -@code{_rmse_prior*.fig}: save results for the analysis using prior -Monte-Carlo samples; - -@item -@code{_rmse_mc*.fig}: save results for the analysis using multivariate -normal Monte-Carlo samples; - -@item -@code{_rmse_post*.fig}: save results for the analysis using Metropolis -posterior samples. -@end itemize - -The following types of figures are saved (we show prior sample to fix ideas, -but the same conventions are used for multivariate normal and posterior): - -@itemize -@item -@code{_rmse_prior_*.fig}: for each parameter, plots the cdfs -corresponding to the best 10% RMSEs of each observed series; - -@item -@code{_rmse_prior_dens_*.fig}: for each parameter, plots the -pdfs corresponding to the best 10% RMESs of each observed series; - -@item -@code{_rmse_prior__corr_*.fig}: for -each observed series plots the bi-dimensional projections of samples -with the best 10% RMSEs, when the correlation is significant; - -@item -@code{_rmse_prior_lnlik*.fig}: for each observed series, plots -in red the cdf of the log-likelihood corresponding to the best 10% -RMSEs, in green the cdf of the rest of the sample and in blue the -cdf of the full sample; this allows one to see the presence of some -idiosyncratic behavior; - -@item -@code{_rmse_prior_lnpost*.fig}: for each observed series, plots -in red the cdf of the log-posterior corresponding to the best 10% RMSEs, -in green the cdf of the rest of the sample and in blue the cdf of the full -sample; this allows one to see idiosyncratic behavior; - -@item -@code{_rmse_prior_lnprior*.fig}: for each observed series, plots -in red the cdf of the log-prior corresponding to the best 10% RMSEs, -in green the cdf of the rest of the sample and in blue the cdf of the full -sample; this allows one to see idiosyncratic behavior; - -@item -@code{_rmse_prior_lik_SA_*.fig}: when @code{lik_only=1}, this shows -the Smirnov tests for the filtering of the best 10% log-likelihood values; - -@item -@code{_rmse_prior_post_SA_*.fig}: when @code{lik_only=1}, this shows -the Smirnov test for the filtering of the best 10% log-posterior values. -@end itemize - -@node Screening Analysis -@subsection Screening Analysis - -Screening analysis does not require any additional options with respect to -those listed in @ref{Sampling Options}. The toolbox performs all the -analyses required and displays results. - -The results of the screening analysis with Morris sampling design are stored -in the subfolder @code{/GSA/SCREEN}. The data file @code{_prior} stores -all the information of the analysis (Morris sample, reduced form coefficients, -etc.). - -Screening analysis merely concerns reduced form coefficients. Similar -synthetic bar charts as for the reduced form analysis with Monte-Carlo samples are -saved: -@itemize -@item -@code{_redform__vs_lags_*.fig}: shows bar charts -of the elementary effect tests for the ten most important parameters -driving the reduced form coefficients of the selected endogenous variables -(@code{namendo}) versus lagged endogenous variables (@code{namlagendo}); - -@item -@code{_redform__vs_shocks_*.fig}: shows bar charts -of the elementary effect tests for the ten most important parameters -driving the reduced form coefficients of the selected endogenous variables -(@code{namendo}) versus exogenous variables (@code{namexo}); - -@item -@code{_redform_screen.fig}: shows bar chart of all elementary -effect tests for each parameter: this allows one to identify parameters that -have a minor effect for any of the reduced form coefficients. -@end itemize - -@node Identification Analysis -@subsection Identification Analysis - -Setting the option @code{identification=1}, an identification analysis based on -theoretical moments is performed. Sensitivity plots are provided that allow -to infer which parameters are most likely to be less identifiable. - -Prerequisite for properly running all the identification routines, is the keyword -@code{identification}; in the Dynare model file. This keyword triggers -the computation of analytic derivatives of the model with respect to estimated -parameters and shocks. This is required for option @code{morris=2}, -which implements @cite{Iskrev (2010)} identification analysis. - -For example, the placing @code{identification; dynare_sensitivity(identification=1, morris=2);} -in the Dynare model file trigger identification analysis using analytic derivatives -@cite{Iskrev (2010)}, jointly with the mapping of the acceptable region. - -The identification analysis with derivatives can also be triggered by the -commands @code{identification;} This does not do the mapping of -acceptable regions for the model and uses the standard random sampler of Dynare. -It completely offsets any use of the sensitivity analysis toolbox. - -@node Performing Sensitivity and Identification Analysis -@subsection Performing Sensitivity and Identification Analysis +@node Performing sensitivity analysis +@subsection Performing sensitivity analysis @deffn Command dynare_sensitivity ; @deffnx Command dynare_sensitivity (@var{OPTIONS}@dots{}); @@ -7383,6 +7204,80 @@ Maximum number of lags for moments in identification analysis. Default: @code{1} @end deffn +@node IRF/Moment calibration +@subsection IRF/Moment calibration + +IRF and moment calibration can be defined in @code{irf_calibration} and @code{moment_calibration} blocks: + +@deffn Block irf_calibration; +@deffnx Block irf_calibration(@var{OPTIONS}@dots{}); + +@descriptionhead + +This block allows defining IRF calibration criteria and is terminated by @code{end;}. +To set IRF sign restrictions, the following syntax is used +@example +@var{VARIABLE_NAME}(@var{INTEGER}),@var{EXOGENOUS_NAME}, -; +@var{VARIABLE_NAME}(@var{INTEGER}:@var{INTEGER}),@var{EXOGENOUS_NAME}, +; +@end example +To set IRF restrictions with specific intervals, the following syntax is used +@example +@var{VARIABLE_NAME}(@var{INTEGER}),@var{EXOGENOUS_NAME}, [@var{DOUBLE} @var{DOUBLE}]; +@var{VARIABLE_NAME}(@var{INTEGER}:@var{INTEGER}),@var{EXOGENOUS_NAME}, [@var{DOUBLE} @var{DOUBLE}]; +@end example + +When @code{(@var{INTEGER}:@var{INTEGER})} is used, the restriction is considered to be fulfilled by a logical OR. +A list of restrictions must always be fulfilled with logical AND. + +@examplehead + +@example +irf_calibration; +y(1:4), e_ys, [ -50 50]; //[first year response with logical OR] +@@#for ilag in 21:40 +R_obs(@@@{ilag@}), e_ys, [0 6]; //[response from 5th to 10th years with logical AND] +@@#endfor +end; +@end example + +@end deffn + +@deffn Block moment_calibration; +@deffnx Block moment_calibration(@var{OPTIONS}@dots{}); + +@descriptionhead + +This block allows defining moment calibration criteria. This block is terminated by @code{end;}, and contains lines of the +form: +@example +@var{VARIABLE_NAME1},@var{VARIABLE_NAME2}(+/-@var{INTEGER}), [@var{DOUBLE} @var{DOUBLE}]; +@var{VARIABLE_NAME1},@var{VARIABLE_NAME2}(+/-@var{INTEGER}), +/-; +@var{VARIABLE_NAME1},@var{VARIABLE_NAME2}(+/-(@var{INTEGER}:@var{INTEGER})), [@var{DOUBLE} @var{DOUBLE}]; +@var{VARIABLE_NAME1},@var{VARIABLE_NAME2}((-@var{INTEGER}:+@var{INTEGER})), [@var{DOUBLE} @var{DOUBLE}]; +@end example + +When @code{(@var{INTEGER}:@var{INTEGER})} is used, the restriction is considered to be fulfilled by a logical OR. +A list of restrictions must always be fulfilled with logical AND. + +@examplehead + +@example +moment_calibration; +y_obs,y_obs, [0.5 1.5]; //[unconditional variance] +y_obs,y_obs(-(1:4)), +; //[sign restriction for first year acf with logical OR] +@@#for ilag in -2:2 +y_obs,R_obs(@@@{ilag@}), -; //[-2:2 ccf with logical AND] +@@#endfor +@@#for ilag in -4:4 +y_obs,pie_obs(@@@{ilag@}), -; //[-4_4 ccf with logical AND] +@@#endfor +end; +@end example + +@end deffn +@node Performing identification analysis +@subsection Performing identification analysis + @deffn Command identification ; @deffnx Command identification (@var{OPTIONS}@dots{}); @@ -7463,6 +7358,404 @@ Specify the parameter set to use. Default: @code{prior_mean} @end deffn +@node Types of analysis and output files +@subsection Types of analysis and output files + +The sensitivity analysis toolbox includes several types of analyses. +Sensitivity analysis results are saved locally in @code{/gsa}, +where @code{.mod} is the name of the DYNARE model file. + +@menu +* Sampling:: +* Stability Mapping:: +* IRF/Moment restrictions:: +* Reduced Form Mapping:: +* RMSE:: +* Screening Analysis:: +* Identification Analysis:: +@end menu + +@node Sampling +@subsubsection Sampling + +The following binary files are produced: +@itemize +@item +@code{_prior.mat}: this file stores information about the analyses +performed sampling from the prior, @i{i.e.} @code{pprior=1} and @code{ppost=0}; + +@item +@code{_mc.mat}: this file stores information about the analyses performed +sampling from multivariate normal, @i{i.e.} @code{pprior=0} and @code{ppost=0}; + +@item +@code{_post.mat}: this file stores information about analyses performed +using the Metropolis posterior sample, @i{i.e.} @code{ppost=1}. +@end itemize + +@node Stability Mapping +@subsubsection Stability Mapping + +Figure files produced are of the form @code{_prior_*.fig} and store results +for stability mapping from prior Monte-Carlo samples: +@itemize +@item +@code{_prior_stable.fig}: plots of the Smirnov test and the correlation analyses +confronting the cdf of the sample fulfilling Blanchard-Kahn conditions (blue color) +with the cdf of the rest of the sample (red color), @i{i.e.} either +instability or indeterminacy or the solution could not be found (@i{e.g.} +the steady state solution could not be found by the solver); + +@item +@code{_prior_indeterm.fig}: plots of the Smirnov test and the correlation +analyses confronting the cdf of the sample producing indeterminacy (red color) +with the cdf of the rest of the sample (blue color); + +@item +@code{_prior_unstable.fig}: plots of the Smirnov test and the correlation +analyses confronting the cdf of the sample producing explosive roots (red color) +with the cdf of the rest of the sample (blue color); + +@item +@code{_prior_wrong.fig}: plots of the Smirnov test and the correlation +analyses confronting the cdf of the sample where the solution could not be found (@i{e.g.} +the steady state solution could not be found by the solver - red color) +with the cdf of the rest of the sample (blue color); + +@item +@code{_prior_calib.fig}: plots of the Smirnov test and the correlation +analyses splitting the sample fulfilling Blanchard-Kahn conditions, +by confronting the cdf of the sample where IRF/moment restrictions are matched (blue color) +with the cdf where IRF/moment restrictions are NOT matched (red color); + +@end itemize + +Similar conventions apply for @code{_mc_*.fig} files, obtained when +samples from multivariate normal are used. + +@node IRF/Moment restrictions +@subsubsection IRF/Moment restrictions + +The following binary files are produced: +@itemize +@item +@code{_prior_restrictions.mat}: this file stores information about the IRF/moment restriction analysis +performed sampling from the prior ranges, @i{i.e.} @code{pprior=1} and @code{ppost=0}; + +@item +@code{_mc_restrictions.mat}: this file stores information about the IRF/moment restriction analysis performed +sampling from multivariate normal, @i{i.e.} @code{pprior=0} and @code{ppost=0}; + +@item +@code{_post_restrictions.mat}: this file stores information about IRF/moment restriction analysis performed +using the Metropolis posterior sample, @i{i.e.} @code{ppost=1}. +@end itemize + +Figure files produced are of the form @code{_prior_irf_calib_*.fig} and @code{_prior_moment_calib_*.fig} and store results +for mapping restrictions from prior Monte-Carlo samples: +@itemize +@item +@code{_prior_irf_calib__vs__.fig}: plots of the Smirnov test and the correlation +analyses splitting the sample fulfilling Blanchard-Kahn conditions, +by confronting the cdf of the sample where the individual IRF restriction +@code{} vs. @code{} at period(s) @code{} is matched (blue color) +with the cdf where the IRF restriction is NOT matched (red color) + +@item +@code{_prior_irf_calib__vs__ALL.fig}: plots of the Smirnov test and the correlation +analyses splitting the sample fulfilling Blanchard-Kahn conditions, +by confronting the cdf of the sample where ALL the individual IRF restrictions for the same couple +@code{} vs. @code{} are matched (blue color) +with the cdf where the IRF restriction is NOT matched (red color) + +@item +@code{_prior_irf_restrictions.fig}: plots visual information on the IRF restrictions +compared to the actual Monte Carlo realization from prior sample. + +@item +@code{_prior_moment_calib__vs__.fig}: plots of the Smirnov test and the correlation +analyses splitting the sample fulfilling Blanchard-Kahn conditions, +by confronting the cdf of the sample where the individual acf/ccf moment restriction +@code{} vs. @code{} at lag(s) @code{} is matched (blue color) +with the cdf where the IRF restriction is NOT matched (red color) + +@item +@code{_prior_moment_calib__vs__ALL.fig}: plots of the Smirnov test and the correlation +analyses splitting the sample fulfilling Blanchard-Kahn conditions, +by confronting the cdf of the sample where ALL the individual acf/ccf moment restrictions for the same couple +@code{} vs. @code{} are matched (blue color) +with the cdf where the IRF restriction is NOT matched (red color) + +@item +@code{_prior_moment_restrictions.fig}: plots visual information on the moment restrictions +compared to the actual Monte Carlo realization from prior sample. + +@end itemize + +Similar conventions apply for @code{_mc_*.fig} and @code{_post_*.fig} files, obtained when +samples from multivariate normal or from posterior are used. + +@node Reduced Form Mapping +@subsubsection Reduced Form Mapping + +When the option @code{threshold_redform} is not set, or it is empty (the default), this analysis estimates a multivariate +smoothing spline ANOVA model (the 'mapping') for the selected entries in the transition matrix of the shock matrix of the reduce form first order solution of the model. +This mapping is done either with prior samples or with MC samples with @code{neighborhood_width}. +Unless @code{neighborhood_width} is set with MC samples, the mapping of the reduced form solution forces the use of samples from +prior ranges or prior distributions, @i{i.e.}: @code{pprior=1} and @code{ppost=0}. It +uses 250 samples to optimize smoothing parameters and 1000 samples to compute the +fit. The rest of the sample is used for out-of-sample validation. One can also +load a previously estimated mapping with a new Monte-Carlo sample, to look at the +forecast for the new Monte-Carlo sample. + +The following synthetic figures are produced: +@itemize +@item +@code{_redform__vs_lags_*.fig}: shows bar charts +of the sensitivity indices for the ten most important parameters driving +the reduced form coefficients of the selected endogenous variables +(@code{namendo}) versus lagged endogenous variables (@code{namlagendo}); suffix +@code{log} indicates the results for log-transformed entries; + +@item +@code{_redform__vs_shocks_*.fig}: shows bar charts +of the sensitivity indices for the ten most important parameters driving +the reduced form coefficients of the selected endogenous variables +(@code{namendo}) versus exogenous variables (@code{namexo}); suffix @code{log} +indicates the results for log-transformed entries; + +@item +@code{_redform_gsa(_log).fig}: shows bar chart of all sensitivity +indices for each parameter: this allows one to notice parameters that +have a minor effect for any of the reduced form coefficients. +@end itemize + +Detailed results of the analyses are shown in the subfolder @code{/gsa/redform_prior} for prior samples and in @code{/gsa/redform_mc} for MC samples with option @code{neighborhood_width}, +where the detailed results of the estimation of the single functional relationships +between parameters @math{\theta} and reduced form coefficient (denoted as @math{y} hereafter) are stored in separate directories +named as: + +@itemize +@item +@code{_vs_}: for the entries of the transition matrix; + +@item +@code{_vs_}: for entries of the matrix of the shocks. +@end itemize + +The following files are stored in each directory (we stick with prior sample but similar convetins are used for MC samples): +@itemize +@item +@code{_prior__vs_.fig}: histogram and CDF plot of the MC sample of the individual entry +of the shock matrix, in sample and out of sample fit of the ANOVA model; + +@item +@code{_prior__vs__map_SE.fig}: for entries of the shock matrix it shows graphs of the estimated first order ANOVA terms @math{y = f(\theta_i)} for each deep parameter @math{\theta_i}; + +@item +@code{_prior__vs_.fig}: histogram and CDF plot of the MC sample of the individual entry +of the transition matrix, in sample and out of sample fit of the ANOVA model; + +@item +@code{_prior__vs__map_SE.fig}: for entries of the transition matrix it shows graphs of the estimated first order ANOVA terms @math{y = f(\theta_i)} for each deep parameter @math{\theta_i}; + +@item +@code{_prior__vs__map.mat}, @code{__vs__map.mat}: these files store info in the estimation; + +@end itemize + +When option @code{logtrans_redform} is set, the ANOVA estimation is performed using a log-transformation of each @code{y}. +The ANOVA mapping is then transformed back onto the original scale, to allow comparability with the baseline estimation. +Graphs for this log-transformed case, are stored in the same folder in files denoted with the @code{_log} suffix. + +When the option @code{threshold_redform} is set, the analysis is performed via Monte Carlo filtering, by displaying parameters that drive the individual entry @code{y} inside the range specified in @code{threshold_redform}. If no entry is found (or all entries are in the range), the MCF algorithm ignores the range specified in @code{threshold_redform} and performs the analysis splitting the MC sample of @code{y} into deciles. Setting @code{threshold_redform=[-inf inf]} triggers this approach for all @code{y}'s. + +Results are stored in subdirectories of @code{/gsa/redform_prior} named +@itemize +@item +@code{_prior__vs__threshold}: for the entries of the transition matrix; + +@item +@code{_prior__vs__threshold}: for entries of the matrix of the shocks. +@end itemize + +The files saved are named +@itemize +@item +@code{_prior__vs__threshold.fig},@code{__vs__threshold.fig}: graphical outputs; +@item +@code{_prior__vs__threshold.mat},@code{__vs__threshold.mat}: info on the analysis; + +@end itemize + +@node RMSE +@subsubsection RMSE + +The RMSE analysis can be performed with different types of sampling options: +@enumerate +@item +When @code{pprior=1} and @code{ppost=0}, the toolbox analyzes the RMSEs for +the Monte-Carlo sample obtained by sampling parameters from their prior distributions +(or prior ranges): this analysis provides some hints about +what parameter drives the fit of which observed series, prior to the full +estimation; + +@item +When @code{pprior=0} and @code{ppost=0}, the toolbox analyzes the RMSEs for +a multivariate normal Monte-Carlo sample, with covariance matrix based on +the inverse Hessian at the optimum: this analysis is useful when maximum likelihood +estimation is done (@i{i.e.} no Bayesian estimation); + +@item +When @code{ppost=1} the toolbox analyzes the RMSEs for the posterior sample +obtained by Dynare's Metropolis procedure. +@end enumerate + +The use of cases 2 and 3 requires an estimation step beforehand. To +facilitate the sensitivity analysis after estimation, the @code{dynare_sensitivity} +command also allows you to indicate some options of the @code{estimation} +command. These are: +@itemize @bullet +@item @code{datafile} +@item @code{nobs} +@item @code{first_obs} +@item @code{prefilter} +@item @code{presample} +@item @code{nograph} +@item @code{nodisplay} +@item @code{graph_format} +@item @code{conf_sig} +@item @code{loglinear} +@item @code{mode_file} +@end itemize + +Binary files produced my RMSE analysis are: +@itemize +@item +@code{_prior_*.mat}: these files store the filtered and smoothed + variables for the prior Monte-Carlo sample, generated when doing RMSE analysis + (@code{pprior=1} and @code{ppost=0}); +@item +@code{_mc_*.mat}: these files store the filtered and smoothed variables + for the multivariate normal Monte-Carlo sample, generated when doing + RMSE analysis (@code{pprior=0} and @code{ppost=0}). +@end itemize + +Figure files @code{_rmse_*.fig} store results for the RMSE analysis. + +@itemize +@item +@code{_rmse_prior*.fig}: save results for the analysis using prior +Monte-Carlo samples; + +@item +@code{_rmse_mc*.fig}: save results for the analysis using multivariate +normal Monte-Carlo samples; + +@item +@code{_rmse_post*.fig}: save results for the analysis using Metropolis +posterior samples. +@end itemize + +The following types of figures are saved (we show prior sample to fix ideas, +but the same conventions are used for multivariate normal and posterior): + +@itemize +@item +@code{_rmse_prior_params_*.fig}: for each parameter, plots the cdfs +corresponding to the best 10% RMSEs of each observed series (only those cdfs below the significance threshold @code{alpha_rmse}); + +@item +@code{_rmse_prior__*.fig}: if a parameter significantly affects the fit of @code{var_obs}, all possible trade-off's with other observables for same parameter are plotted; + +@item +@code{_rmse_prior__map.fig}: plots the MCF analysis of parameters significantly driving the fit the observed series @code{var_obs}; + +@item +@code{_rmse_prior_lnlik*.fig}: for each observed series, plots +in BLUE the cdf of the log-likelihood corresponding to the best 10% +RMSEs, in RED the cdf of the rest of the sample and in BLACK the +cdf of the full sample; this allows one to see the presence of some +idiosyncratic behavior; + +@item +@code{_rmse_prior_lnpost*.fig}: for each observed series, plots +in BLUE the cdf of the log-posterior corresponding to the best 10% RMSEs, +in RED the cdf of the rest of the sample and in BLACK the cdf of the full +sample; this allows one to see idiosyncratic behavior; + +@item +@code{_rmse_prior_lnprior*.fig}: for each observed series, plots +in BLUE the cdf of the log-prior corresponding to the best 10% RMSEs, +in RED the cdf of the rest of the sample and in BLACK the cdf of the full +sample; this allows one to see idiosyncratic behavior; + +@item +@code{_rmse_prior_lik.fig}: when @code{lik_only=1}, this shows +the MCF tests for the filtering of the best 10% log-likelihood values; + +@item +@code{_rmse_prior_post.fig}: when @code{lik_only=1}, this shows +the MCF tests for the filtering of the best 10% log-posterior values. +@end itemize + +@node Screening Analysis +@subsubsection Screening Analysis + +Screening analysis does not require any additional options with respect to +those listed in @ref{Sampling Options}. The toolbox performs all the +analyses required and displays results. + +The results of the screening analysis with Morris sampling design are stored +in the subfolder @code{/gsa/screen}. The data file @code{_prior} stores +all the information of the analysis (Morris sample, reduced form coefficients, +etc.). + +Screening analysis merely concerns reduced form coefficients. Similar +synthetic bar charts as for the reduced form analysis with Monte-Carlo samples are +saved: +@itemize +@item +@code{_redform__vs_lags_*.fig}: shows bar charts +of the elementary effect tests for the ten most important parameters +driving the reduced form coefficients of the selected endogenous variables +(@code{namendo}) versus lagged endogenous variables (@code{namlagendo}); + +@item +@code{_redform__vs_shocks_*.fig}: shows bar charts +of the elementary effect tests for the ten most important parameters +driving the reduced form coefficients of the selected endogenous variables +(@code{namendo}) versus exogenous variables (@code{namexo}); + +@item +@code{_redform_screen.fig}: shows bar chart of all elementary +effect tests for each parameter: this allows one to identify parameters that +have a minor effect for any of the reduced form coefficients. +@end itemize + +@node Identification Analysis +@subsubsection Identification Analysis + +Setting the option @code{identification=1}, an identification analysis based on +theoretical moments is performed. Sensitivity plots are provided that allow +to infer which parameters are most likely to be less identifiable. + +Prerequisite for properly running all the identification routines, is the keyword +@code{identification}; in the Dynare model file. This keyword triggers +the computation of analytic derivatives of the model with respect to estimated +parameters and shocks. This is required for option @code{morris=2}, +which implements @cite{Iskrev (2010)} identification analysis. + +For example, the placing @code{identification; dynare_sensitivity(identification=1, morris=2);} +in the Dynare model file trigger identification analysis using analytic derivatives +@cite{Iskrev (2010)}, jointly with the mapping of the acceptable region. + +The identification analysis with derivatives can also be triggered by the +commands @code{identification;} This does not do the mapping of +acceptable regions for the model and uses the standard random sampler of Dynare. +It completely offsets any use of the sensitivity analysis toolbox. + + @node Markov-switching SBVAR @section Markov-switching SBVAR @@ -11787,7 +12080,7 @@ with the same base name as specified by @ref{tableName} with the ending @end defmethod @anchor{addSeries} -@defmethod Report addSeries data, graphBar, graphBarColor, graphBarFillColor, graphBarWidth, graphHline, graphLegendName, graphLineColor, graphLineStyle, graphLineWidth, graphMarker, graphMarkerEdgeColor, graphMarkerFaceColor, graphMarkerSize, graphMiscTikzAddPlotOptions, graphShowInLegend, graphVline, tableDataRhs, tableRowColor, tableRowIndent, tableShowMarkers, tableAlignRight, tableNegColor, tablePosColor, tableSubSectionHeader, zeroTol +@defmethod Report addSeries data, graphBar, graphBarColor, graphBarFillColor, graphBarWidth, graphFanShadeColor, graphFanShadeOpacity, graphHline, graphLegendName, graphLineColor, graphLineStyle, graphLineWidth, graphMarker, graphMarkerEdgeColor, graphMarkerFaceColor, graphMarkerSize, graphMiscTikzAddPlotOptions, graphShowInLegend, graphVline, tableDataRhs, tableRowColor, tableRowIndent, tableShowMarkers, tableAlignRight, tableNegColor, tablePosColor, tableSubSectionHeader, zeroTol Adds a @code{Series} to a @code{Graph} or a @code{Table}. NB: Options specific to graphs begin with `@code{graph}' while options specific to tables begin with `@code{table}'. @@ -11802,6 +12095,15 @@ to graphs begin with `@code{graph}' while options specific to tables begin with Whether or not to display this series as a bar graph as oppsed to the default of displaying it as a line graph. Default: @code{false} +@anchor{graphFanShadeColor} +@item graphFanShadeColor, @code{STRING} +The shading color to use between a series and the previously-added +series in a graph. Useful for making fan charts. Default: @code{empty} + +@item graphFanShadeOpacity, @code{INTEGER} +The opacity of the color passed in @ref{graphFanShadeColor}. Default: +@code{50} + @item graphBarColor, @code{STRING} The outline color of each bar in the bar graph. Only active if @ref{graphBar} is passed. Default: @code{`black'} @@ -12220,6 +12522,11 @@ Expansion Approach to Simulation of Stochastic Forward-Looking Models with an Application to a Non-Linear Phillips Curve,'' @i{Computational Economics}, 17, 125--139 +@item +Corona, Angelo, M. Marchesi, Claudio Martini, and Sandro Ridella (1987): +``Minimizing multimodal functions of continuous variables with the ``simulated annealing'' algorithm'', +@i{ACM Transactions on Mathematical Software}, 13(3), 262--280 + @item Christiano, Lawrence J., Mathias Trabandt and Karl Walentin (2011): ``Introducing financial frictions and unemployment into a small open @@ -12268,6 +12575,16 @@ International Meeting on Bayesian Statistics, pp. 169--194, Oxford University Pr Geweke, John (1999): ``Using simulation methods for Bayesian econometric models: Inference, development and communication,'' @i{Econometric Reviews}, 18(1), 1--73 +@item +Goffe, William L., Gary D. Ferrier, and John Rogers (1994): ``Global Optimization +of Statistical Functions with Simulated Annealing,'' @i{Journal of Econometrics}, 60(1/2), +65--100 + +@item +Hansen, Nikolaus and Stefan Kern (2004): ``Evaluating the CMA Evolution Strategy +on Multimodal Test Functions''. In: @i{Eighth International Conference on Parallel +Problem Solving from Nature PPSN VIII, Proceedings}, Berlin: Springer, 282--291 + @item Ireland, Peter (2004): ``A Method for Taking Models to the Data,'' @i{Journal of Economic Dynamics and Control}, 28, 1205--26 @@ -12287,6 +12604,11 @@ Juillard, Michel (1996): ``Dynare: A program for the resolution and simulation of dynamic models with forward variables through the use of a relaxation algorithm,'' CEPREMAP, @i{Couverture Orange}, 9602 +@item +Kim, Jinill and Sunghyun Kim (2003): ``Spurious welfare reversals in +international business cycle models,'' @i{Journal of International +Economics}, 60, 471--500 + @item Kim, Jinill, Sunghyun Kim, Ernst Schaumburg, and Christopher A. Sims (2008): ``Calculating and using second-order accurate solutions of @@ -12301,6 +12623,11 @@ Koopman, S. J. and J. Durbin (2003): ``Filtering and Smoothing of State Vector for Diffuse State Space Models,'' @i{Journal of Time Series Analysis}, 24(1), 85--98 +@item +Kuntsevich, Alexei V. and Franz Kappel (1997): ``SolvOpt - The solver +for local nonlinear optimization problems (version 1.1, Matlab, C, FORTRAN)'', +University of Graz, Graz, Austria + @item Laffargue, Jean-Pierre (1990): ``Résolution d'un modèle macroéconomique avec anticipations rationnelles'', @i{Annales @@ -12357,6 +12684,12 @@ Villemot, Sébastien (2011): ``Solving rational expectations models at first order: what Dynare does,'' @i{Dynare Working Papers}, 2, CEPREMAP +@item +Woodford, Michael (2011): ``Commentary: How Should Monetary Policy Be +Conducted in an Era of Price Stability?'' @i{Proceedings - Economic Policy Symposium - Jackson Hole}, +277-316 + + @end itemize @node Command and Function Index diff --git a/license.txt b/license.txt index 52fce2880..0f9bcbaf4 100644 --- a/license.txt +++ b/license.txt @@ -53,6 +53,19 @@ Copyright: 2001-2012 Nikolaus Hansen 2012 Dynare Team License: GPL-3+ +Files: matlab/optimization/solvopt.m +Copyright: 1997-2008 Alexei Kuntsevich and Franz Kappel + 2008-2015 Giovanni Lombardo + 2015 Dynare Team +License: GPL-3+ + +Files: matlab/optimization/simulated_annealing.m +Copyright: 1995 E.G.Tsionas + 1995-2002 Thomas Werner + 2002-2015 Giovanni Lombardo + 2015 Dynare Team +License: GPL-3+ + Files: matlab/endogenous_prior.m Copyright: 2011 Lawrence J. Christiano, Mathias Trabandt and Karl Walentin 2013 Dynare Team diff --git a/matlab/McMCDiagnostics.m b/matlab/McMCDiagnostics.m index ed719034c..ce85ecbf3 100644 --- a/matlab/McMCDiagnostics.m +++ b/matlab/McMCDiagnostics.m @@ -86,14 +86,14 @@ if nblck == 1 % Brooks and Gelman tests need more than one block fprintf('\nCONVERGENCE DIAGNOSTICS: Invalid option for geweke_interval. Using the default of [0.2 0.5].\n') options_.convergence.geweke.geweke_interval=[0.2 0.5]; end - first_obs_begin_sample = max(1,ceil(options_.mh_drop*options_.mh_replic)); - last_obs_begin_sample = first_obs_begin_sample+round(options_.convergence.geweke.geweke_interval(1)*options_.mh_replic*(1-options_.mh_drop)); - first_obs_end_sample = first_obs_begin_sample+round(options_.convergence.geweke.geweke_interval(2)*options_.mh_replic*(1-options_.mh_drop)); + first_obs_begin_sample = max(1,ceil(options_.mh_drop*NumberOfDraws)); + last_obs_begin_sample = first_obs_begin_sample+round(options_.convergence.geweke.geweke_interval(1)*NumberOfDraws*(1-options_.mh_drop)); + first_obs_end_sample = first_obs_begin_sample+round(options_.convergence.geweke.geweke_interval(2)*NumberOfDraws*(1-options_.mh_drop)); param_name=[]; for jj=1:npar param_name = strvcat(param_name,get_the_name(jj,options_.TeX,M_,estim_params_,options_)); end - fprintf('\nGeweke (1992) Convergence Tests, based on means of draws %d to %d vs %d to %d.\n',first_obs_begin_sample,last_obs_begin_sample,first_obs_end_sample,options_.mh_replic); + fprintf('\nGeweke (1992) Convergence Tests, based on means of draws %d to %d vs %d to %d.\n',first_obs_begin_sample,last_obs_begin_sample,first_obs_end_sample,NumberOfDraws); fprintf('p-values are for Chi2-test for equality of means.\n'); Geweke_header={'Parameter', 'Post. Mean', 'Post. Std', 'p-val No Taper'}; print_string=['%',num2str(size(param_name,2)+3),'s \t %12.3f \t %12.3f \t %12.3f']; diff --git a/matlab/PosteriorIRF.m b/matlab/PosteriorIRF.m index fc1c3bcf5..47da7e86f 100644 --- a/matlab/PosteriorIRF.m +++ b/matlab/PosteriorIRF.m @@ -16,7 +16,7 @@ function PosteriorIRF(type) % functions associated with it(the _core1 and _core2). % See also the comments random_walk_metropolis_hastings.m funtion. -% Copyright (C) 2006-2013 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -93,8 +93,15 @@ elseif strcmpi(type,'gsa') else MhDirectoryName = CheckPath('prior',M_.dname); end -delete([MhDirectoryName filesep M_.fname '_IRF_DSGEs*.mat']); -delete([MhDirectoryName filesep M_.fname '_IRF_BVARDSGEs*.mat']); + +%delete old stale files before creating new ones +delete_stale_file([MhDirectoryName filesep M_.fname '_IRF_DSGEs*.mat']); +delete_stale_file([MhDirectoryName filesep M_.fname '_IRF_BVARDSGEs*.mat']); +delete_stale_file([MhDirectoryName filesep M_.fname '_irf_dsge*.mat']); +delete_stale_file([MhDirectoryName filesep M_.fname '_irf_bvardsge*.mat']); +delete_stale_file([MhDirectoryName filesep M_.fname '_param_irf*.mat']); + + if strcmpi(type,'posterior') B = options_.sub_draws; options_.B = B; @@ -112,16 +119,7 @@ else% type = 'prior' B = options_.prior_draws; options_.B = B; end -try - delete([MhDirectoryName filesep M_.fname '_irf_dsge*.mat']) -catch - disp('No _IRFs (dsge) files to be deleted!') -end -try - delete([MhDirectoryName filesep M_.fname '_irf_bvardsge*.mat']) -catch - disp('No _IRFs (bvar-dsge) files to be deleted!') -end + irun = 0; IRUN = 0; irun2 = 0; diff --git a/matlab/PosteriorIRF_core2.m b/matlab/PosteriorIRF_core2.m index c20702eb5..1fef8cdff 100644 --- a/matlab/PosteriorIRF_core2.m +++ b/matlab/PosteriorIRF_core2.m @@ -1,17 +1,28 @@ -function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam, ThisMatlab) +function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam,ThisMatlab) +% function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam, ThisMatlab) % Generates the Posterior IRFs plot from the IRFs generated in % PosteriorIRF_core1 +% % PARALLEL CONTEXT -% Perform in parallel execution a portion of the PosteriorIRF.m code. -% See also the comment in random_walk_metropolis_hastings_core.m funtion. +% Performs in parallel execution a portion of the PosteriorIRF.m code. +% For more information, see the comment in random_walk_metropolis_hastings_core.m +% function. % % INPUTS -% See the comment in random_walk_metropolis_hastings_core.m funtion. +% o myimput [struc] The mandatory variables for local/remote +% parallel computing obtained from random_walk_metropolis_hastings.m +% function. +% o fblck and nblck [integer] The Metropolis-Hastings chains. +% o whoiam [integer] In concurrent programming a modality to refer to the differents thread running in parallel is needed. +% The integer whoaim is the integer that +% allows us to distinguish between them. Then it is the index number of this CPU among all CPUs in the +% cluster. +% o ThisMatlab [integer] Allows us to distinguish between the +% 'main' matlab, the slave matlab worker, local matlab, remote matlab, +% ... Then it is the index number of this slave machine in the cluster. % % OUTPUTS -% o myoutput [struc] -% Contained: -% OutputFileName (i.e. the figures without the file .txt). +% o myoutput [struc] Contained: OutputFileName (i.e. the figures without the file .txt). % % ALGORITHM % Portion of PosteriorIRF.m function code. Specifically the last 'for' cycle. @@ -19,7 +30,7 @@ function myoutput=PosteriorIRF_core2(myinputs,fpar,npar,whoiam, ThisMatlab) % SPECIAL REQUIREMENTS. % None. % -% Copyright (C) 2006-2013 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -100,13 +111,9 @@ for i=fpar:npar, set(0,'CurrentFigure',hh) subplot(nn,nn,subplotnum); if ~MAX_nirfs_dsgevar - h1 = area(1:options_.irf,HPDIRF(:,2,j,i)); - set(h1,'FaceColor',[.9 .9 .9]); - set(h1,'BaseValue',min(HPDIRF(:,1,j,i))); + h1 = area(1:options_.irf,HPDIRF(:,2,j,i),'FaceColor',[.9 .9 .9],'BaseValue',min(HPDIRF(:,1,j,i))); %grey below HPDIsup and minimum of HPDIinf hold on - h2 = area(1:options_.irf,HPDIRF(:,1,j,i),'FaceColor',[1 1 1],'BaseValue',min(HPDIRF(:,1,j,i))); - set(h2,'FaceColor',[1 1 1]); - set(h2,'BaseValue',min(HPDIRF(:,1,j,i))); + h2 = area(1:options_.irf,HPDIRF(:,1,j,i),'FaceColor',[1 1 1],'BaseValue',min(HPDIRF(:,1,j,i))); %white below HPDIinf and minimum of HPDIinf plot(1:options_.irf,MeanIRF(:,j,i),'-k','linewidth',3) % plot([1 options_.irf],[0 0],'-r','linewidth',0.5); box on @@ -114,18 +121,14 @@ for i=fpar:npar, xlim([1 options_.irf]); hold off else - h1 = area(1:options_.irf,HPDIRF(:,2,j,i)); - set(h1,'FaceColor',[.9 .9 .9]); - set(h1,'BaseValue',min([min(HPDIRF(:,1,j,i)),min(HPDIRFdsgevar(:,1,j,i))])); - hold on; - h2 = area(1:options_.irf,HPDIRF(:,1,j,i)); - set(h2,'FaceColor',[1 1 1]); - set(h2,'BaseValue',min([min(HPDIRF(:,1,j,i)),min(HPDIRFdsgevar(:,1,j,i))])); + h1 = area(1:options_.irf,HPDIRF(:,2,j,i),'FaceColor',[.9 .9 .9],'BaseValue',min([min(HPDIRF(:,1,j,i)),min(HPDIRFdsgevar(:,1,j,i))])); %grey below HPDIsup and minimum of HPDIinf and HPDIRFdsgevar + hold on + h2 = area(1:options_.irf,HPDIRF(:,1,j,i),'FaceColor',[1 1 1],'BaseValue',min([min(HPDIRF(:,1,j,i)),min(HPDIRFdsgevar(:,1,j,i))])); %white below HPDIinf and minimum of HPDIinf and HPDIRFdsgevar plot(1:options_.irf,MeanIRF(:,j,i),'-k','linewidth',3) - % plot([1 options_.irf],[0 0],'-r','linewidth',0.5); plot(1:options_.irf,MeanIRFdsgevar(:,j,i),'--k','linewidth',2) plot(1:options_.irf,HPDIRFdsgevar(:,1,j,i),'--k','linewidth',1) plot(1:options_.irf,HPDIRFdsgevar(:,2,j,i),'--k','linewidth',1) + % plot([1 options_.irf],[0 0],'-r','linewidth',0.5); box on axis tight xlim([1 options_.irf]); @@ -156,6 +159,4 @@ for i=fpar:npar, end end% loop over exo_var - - myoutput.OutputFileName = OutputFileName; diff --git a/matlab/add_path_to_mex_files.m b/matlab/add_path_to_mex_files.m index ea9065a51..70f9fa7f5 100644 --- a/matlab/add_path_to_mex_files.m +++ b/matlab/add_path_to_mex_files.m @@ -29,7 +29,7 @@ if isoctave else % Add win32 specific paths for Dynare Windows package if strcmp(computer, 'PCWIN') - tmp = [dynareroot '../mex/matlab/win32-7.5-8.4/']; + tmp = [dynareroot '../mex/matlab/win32-7.5-8.5/']; if exist(tmp, 'dir') mexpath = tmp; if modifypath diff --git a/matlab/bfgsi1.m b/matlab/bfgsi1.m index 48d58562d..c3b87ca49 100644 --- a/matlab/bfgsi1.m +++ b/matlab/bfgsi1.m @@ -1,13 +1,20 @@ function H = bfgsi1(H0,dg,dx) % H = bfgsi1(H0,dg,dx) -% dg is previous change in gradient; dx is previous change in x; +% Update Inverse Hessian matrix +% +% Inputs: +% H0 [npar by npar] initial inverse Hessian matrix +% dg [npar by 1] previous change in gradient +% dx [npar by 1] previous change in x; +% % 6/8/93 version that updates inverse hessian instead of hessian % itself. - +% % Original file downloaded from: % http://sims.princeton.edu/yftp/optimize/mfiles/bfgsi.m - +% % Copyright (C) 1993-2009 Christopher Sims +% Copyright (C) 2009-2015 Dynare Team % % This file is part of Dynare. % @@ -41,4 +48,4 @@ else disp(['|H*dg| = ' num2str(Hdg'*Hdg)]) H=H0; end -save H.dat H +save('H.dat','H') diff --git a/matlab/check_valid_ver.m b/matlab/check_valid_ver.m new file mode 100644 index 000000000..9b61813ad --- /dev/null +++ b/matlab/check_valid_ver.m @@ -0,0 +1,39 @@ +function check_valid_ver(ver) +%function check_valid_ver(ver) +% Checks that ver is valid +% +% INPUTS +% ver [string] dynare version number +% +% OUTPUTS +% none +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2015 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 . + +test_ver = strsplit(ver, {'.', '-'}); +errmsg = 'check_valid_ver: the desired version must be in the proper format'; +assert (length(test_ver) == 3 && ... + ~isempty(str2double(test_ver{1})) && ... + ~isempty(str2double(test_ver{2})), errmsg); +if isnan(str2double(test_ver{3})) + assert(strcmp(test_ver{3}, 'unstable'), errmsg); +end +end \ No newline at end of file diff --git a/matlab/cli/prior.m b/matlab/cli/prior.m index f490a570b..d00e0555b 100644 --- a/matlab/cli/prior.m +++ b/matlab/cli/prior.m @@ -28,6 +28,18 @@ function varargout = prior(varargin) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +if isempty(varargin) || ( isequal(length(varargin), 1) && isequal(varargin{1},'help')) + skipline() + disp('Possible options are:') + disp(' + table Prints a table describing the priors.') + disp(' + moments Computes and displays moments of the endogenous variables at the prior mode.') + disp(' + optimize Optimizes the prior density (starting from a random initial guess).') + disp(' + simulate Computes the effective prior mass (using a Monte-Carlo).') + disp(' + plot Plots the marginal prior densities.') + skipline() + return +end + global options_ M_ estim_params_ bayestopt_ oo_ objective_function_penalty_base donesomething = false; diff --git a/matlab/conditional_variance_decomposition_mc_analysis.m b/matlab/conditional_variance_decomposition_mc_analysis.m index 004239800..22273f2be 100644 --- a/matlab/conditional_variance_decomposition_mc_analysis.m +++ b/matlab/conditional_variance_decomposition_mc_analysis.m @@ -1,7 +1,27 @@ function oo_ = ... conditional_variance_decomposition_mc_analysis(NumberOfSimulations, type, dname, fname, Steps, exonames, exo, var_list, endogenous_variable_index, mh_conf_sig, oo_) % This function analyses the (posterior or prior) distribution of the -% endogenous conditional variance decomposition. +% endogenous variables' conditional variance decomposition. +% +% INPUTS +% NumberOfSimulations [integer] scalar, number of simulations. +% type [string] 'prior' or 'posterior' +% dname [string] directory name where to save +% fname [string] name of the mod-file +% Steps [integers] horizons at which to conduct decomposition +% exonames [string] (n_exo*char_length) character array with names of exogenous variables +% exo [string] name of current exogenous +% variable +% var_list [string] (n_endo*char_length) character array with name +% of endogenous variables +% endogenous_variable_index [integer] index of the current +% endogenous variable +% mh_conf_sig [double] 2 by 1 vector with upper +% and lower bound of HPD intervals +% oo_ [structure] Dynare structure where the results are saved. +% +% OUTPUTS +% oo_ [structure] Dynare structure where the results are saved. % Copyright (C) 2009-2013 Dynare Team % diff --git a/matlab/convert_oo_.m b/matlab/convert_oo_.m new file mode 100644 index 000000000..355f5a812 --- /dev/null +++ b/matlab/convert_oo_.m @@ -0,0 +1,47 @@ +function oo_ = convert_oo_(oo_, ver) +%function oo_ = convert_oo_(oo_, ver) +% Converts oo_ from oo_.dynare_version to ver +% +% INPUTS +% oo_ [struct] dynare output struct +% ver [string] desired oo_ output version +% +% OUTPUTS +% oo_ [struct] dynare output struct +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2015 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 . + +check_valid_ver(ver); + +if isfield(oo_, 'dynare_version') + ver_orig = oo_.dynare_version; +else + ver_orig = '4.4.3'; +end + +if strcmp(ver_orig, ver) + return; +end + +if ver_less_than(ver_orig, '4.5.0') && ver_greater_than_equal(ver, '4.5.0') + oo_.exo_simul = oo_.exo_simul'; +end +end diff --git a/matlab/covariance_mc_analysis.m b/matlab/covariance_mc_analysis.m index a24ec665e..d98992f0e 100644 --- a/matlab/covariance_mc_analysis.m +++ b/matlab/covariance_mc_analysis.m @@ -1,8 +1,24 @@ function oo_ = covariance_mc_analysis(NumberOfSimulations,type,dname,fname,vartan,nvar,var1,var2,mh_conf_sig,oo_) % This function analyses the (posterior or prior) distribution of the -% endogenous variables covariance matrix. +% endogenous variables' covariance matrix. +% +% INPUTS +% NumberOfSimulations [integer] scalar, number of simulations. +% type [string] 'prior' or 'posterior' +% dname [string] directory name where to save +% fname [string] name of the mod-file +% vartan [char] array of characters (with nvar rows). +% nvar [integer] nvar is the number of stationary variables. +% var1 [string] name of the first variable +% var2 [string] name of the second variable +% mh_conf_sig [double] 2 by 1 vector with upper +% and lower bound of HPD intervals +% oo_ [structure] Dynare structure where the results are saved. +% +% OUTPUTS +% oo_ [structure] Dynare structure where the results are saved. -% Copyright (C) 2008-2013 Dynare Team +% Copyright (C) 2008-2015 Dynare Team % % This file is part of Dynare. % diff --git a/matlab/disp_dr.m b/matlab/disp_dr.m index 34fd620c3..906431437 100644 --- a/matlab/disp_dr.m +++ b/matlab/disp_dr.m @@ -1,5 +1,5 @@ - function disp_dr(dr,order,var_list) +% function disp_dr(dr,order,var_list) % Display the decision rules % % INPUTS @@ -7,8 +7,8 @@ function disp_dr(dr,order,var_list) % order [int]: order of approximation % var_list [char array]: list of endogenous variables for which the % decision rules should be printed - -% Copyright (C) 2001-2012 Dynare Team +% +% Copyright (C) 2001-2015 Dynare Team % % This file is part of Dynare. % @@ -55,44 +55,67 @@ for i=1:nvar end end +% get length of display strings +header_label_length=16; %default +for ii=1:length(ivar) + header_label_length=max(header_label_length,length(deblank(M_.endo_names(k1(ivar(ii)),:)))+2); +end +header_label_format = sprintf('%%%ds',header_label_length); +value_format_float = sprintf('%%%d.6f',header_label_length); +value_format_zero = sprintf('%%%dd',header_label_length); + +% account for additional characters introduced by auxiliary variables +if ~isempty(M_.aux_vars) + aux_vars_type = [M_.aux_vars.type]; + if any(aux_vars_type==4) + aux_var_additional_characters=14; + else + aux_var_additional_characters=3; + end +else + aux_var_additional_characters=0; +end + +var_name_width=max([max(size(deblank(M_.endo_names(k1(ivar),:)),2)),max(size(deblank(M_.exo_names),2))]); + +%deal with covariances +if order > 1 + var_name_width=max(2*(var_name_width+aux_var_additional_characters)+2,20); %account for covariances, separated by comma +else + var_name_width=max(var_name_width+aux_var_additional_characters,20); +end +label_format = sprintf('%%-%ds',var_name_width); + + +%% start displayimg disp('POLICY AND TRANSITION FUNCTIONS') % variable names -str = ' '; +str = char(32*ones(1,var_name_width)); for i=1:nvar - str = [str sprintf('%16s',M_.endo_names(k1(ivar(i)),:))]; + str = [str sprintf(header_label_format,deblank(M_.endo_names(k1(ivar(i)),:)))]; end disp(str); % % constant % -str = 'Constant '; +str=sprintf(label_format,'Constant'); flag = 0; for i=1:nvar x = dr.ys(k1(ivar(i))); if order > 1 x = x + dr.ghs2(ivar(i))/2; end - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) end if order > 1 - str = '(correction) '; + str = sprintf(label_format,'(correction)'); flag = 0; for i=1:nvar x = dr.ghs2(ivar(i))/2; - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -108,15 +131,10 @@ for k=1:nx else str1 = subst_auxvar(k1(klag(k,1)),klag(k,2)-M_.maximum_lag-2); end - str = sprintf('%-20s',str1); + str = sprintf(label_format,str1); for i=1:nvar x = dr.ghx(ivar(i),k); - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -127,15 +145,10 @@ end % for k=1:nu flag = 0; - str = sprintf('%-20s',M_.exo_names(k,:)); + str = sprintf(label_format,M_.exo_names(k,:)); for i=1:nvar x = dr.ghu(ivar(i),k); - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -149,19 +162,14 @@ if order > 1 flag = 0; str1 = sprintf('%s,%s',subst_auxvar(k1(klag(k,1)),klag(k,2)-M_.maximum_lag-2), ... subst_auxvar(k1(klag(j,1)),klag(j,2)-M_.maximum_lag-2)); - str = sprintf('%-20s',str1); + str = sprintf(label_format,str1); for i=1:nvar if k == j x = dr.ghxx(ivar(i),(k-1)*nx+j)/2; else x = dr.ghxx(ivar(i),(k-1)*nx+j); end - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -174,19 +182,14 @@ if order > 1 for k = 1:nu for j = 1:k flag = 0; - str = sprintf('%-20s',[M_.exo_names(k,:) ',' M_.exo_names(j,:)] ); + str = sprintf(label_format,[deblank(M_.exo_names(k,:)) ',' deblank(M_.exo_names(j,:))] ); for i=1:nvar if k == j x = dr.ghuu(ivar(i),(k-1)*nu+j)/2; else x = dr.ghuu(ivar(i),(k-1)*nu+j); end - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -200,16 +203,11 @@ if order > 1 for j = 1:nu flag = 0; str1 = sprintf('%s,%s',subst_auxvar(k1(klag(k,1)),klag(k,2)-M_.maximum_lag-2), ... - M_.exo_names(j,:)); - str = sprintf('%-20s',str1); + deblank(M_.exo_names(j,:))); + str = sprintf(label_format,str1); for i=1:nvar x = dr.ghxu(ivar(i),(k-1)*nu+j); - if abs(x) > 1e-6 - flag = 1; - str = [str sprintf('%16.6f',x)]; - else - str = [str ' 0']; - end + [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_); end if flag disp(str) @@ -253,3 +251,12 @@ for i = 1:length(M_.aux_vars) end error(sprintf('Could not find aux var: %s', M_.endo_names(aux_index, :))) end + +function [str,flag]=get_print_string(str,x,value_format_zero,value_format_float,flag,options_) + if abs(x) > options_.dr_display_tol + flag = 1; + str = [str sprintf(value_format_float,x)]; + else + str = [str sprintf(value_format_zero,0)]; + end +end \ No newline at end of file diff --git a/matlab/distributions/rand_multivariate_student.m b/matlab/distributions/rand_multivariate_student.m index 6d9b52df6..eca1d0585 100644 --- a/matlab/distributions/rand_multivariate_student.m +++ b/matlab/distributions/rand_multivariate_student.m @@ -1,4 +1,5 @@ function draw = rand_multivariate_student(Mean,Sigma_upper_chol,df) +% function draw = rand_multivariate_student(Mean,Sigma_upper_chol,df) % Pseudo random draws from a multivariate student distribution, % with expectation Mean, variance Sigma*df/(df-2) and degrees of freedom df>0. % @@ -13,10 +14,14 @@ function draw = rand_multivariate_student(Mean,Sigma_upper_chol,df) % draw [double] 1*n vector drawn from a multivariate normal distribution with expectation Mean and % covariance Sigma. % -% REMARK This is certainly not the most efficient way... % % NOTE See Zellner (appendix B.2, 1971) for a definition. -% +% Computes the t-distributed random numbers from +% X = \mu + Y\sqrt{\frac{\nu}{U}} +% where +% Y~N(0,Sigma) with Sigma=Sigma_upper_chol'*Sigma_upper_chol +% U~\Chi^2_{\nu} +% The latter is constructed as the sum of \nu standard normals. % Copyright (C) 2003-2009 Dynare Team % diff --git a/matlab/dsge_likelihood.m b/matlab/dsge_likelihood.m index 41b326c14..56c8dc2fa 100644 --- a/matlab/dsge_likelihood.m +++ b/matlab/dsge_likelihood.m @@ -328,7 +328,7 @@ mm = length(T); pp = DynareDataset.vobs; rr = length(Q); kalman_tol = DynareOptions.kalman_tol; -diffuse_kalman_tol = DynareOptions.kalman_tol; +diffuse_kalman_tol = DynareOptions.diffuse_kalman_tol; riccati_tol = DynareOptions.riccati_tol; Y = transpose(DynareDataset.data)-trend; diff --git a/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m b/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m index 7ef623b81..1c0441361 100644 --- a/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m +++ b/matlab/dsge_simulated_theoretical_conditional_variance_decomposition.m @@ -1,10 +1,13 @@ function [nvar,vartan,NumberOfConditionalDecompFiles] = ... dsge_simulated_theoretical_conditional_variance_decomposition(SampleSize,Steps,M_,options_,oo_,type) +% function [nvar,vartan,NumberOfConditionalDecompFiles] = ... +% dsge_simulated_theoretical_conditional_variance_decomposition(SampleSize,Steps,M_,options_,oo_,type) % This function computes the posterior or prior distribution of the conditional variance % decomposition of the endogenous variables (or a subset of the endogenous variables). % % INPUTS % SampleSize [integer] scalar, number of simulations. +% Steps [integers] horizons at which to conduct decomposition % M_ [structure] Dynare structure describing the model. % options_ [structure] Dynare structure defining global options. % oo_ [structure] Dynare structure where the results are saved. @@ -16,7 +19,7 @@ function [nvar,vartan,NumberOfConditionalDecompFiles] = ... % vartan [char] array of characters (with nvar rows). % NumberOfConditionalDecompFiles [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2009-2012 Dynare Team +% Copyright (C) 2009-2015 Dynare Team % % This file is part of Dynare. % @@ -47,6 +50,13 @@ else error() end +%delete old stale files before creating new ones +if posterior + delete_stale_file([M_.dname '/metropolis/' M_.fname '_PosteriorConditionalVarianceDecomposition*']) +else + delete_stale_file([M_.dname '/prior/moments/' M_.fname '_PriorConditionalVarianceDecomposition*']) +end + % Set varlist (vartan) if ~posterior if isfield(options_,'varlist') diff --git a/matlab/dsge_simulated_theoretical_correlation.m b/matlab/dsge_simulated_theoretical_correlation.m index 59ffa4e4e..265336dbb 100644 --- a/matlab/dsge_simulated_theoretical_correlation.m +++ b/matlab/dsge_simulated_theoretical_correlation.m @@ -1,21 +1,23 @@ function [nvar,vartan,CorrFileNumber] = dsge_simulated_theoretical_correlation(SampleSize,nar,M_,options_,oo_,type) +% function [nvar,vartan,CorrFileNumber] = dsge_simulated_theoretical_correlation(SampleSize,nar,M_,options_,oo_,type) % This function computes the posterior or prior distribution of the endogenous -% variables second order moments. +% variables' second order moments. % % INPUTS -% SampleSize [integer] -% nar [integer] -% M_ [structure] -% options_ [structure] -% oo_ [structure] -% type [string] +% SampleSize [integer] scalar, number of simulations. +% nar [integer] maximum number of autocorrelations to +% consider +% M_ [structure] Dynare structure describing the model. +% options_ [structure] Dynare structure defining global options +% oo_ [structure] Dynare structure where the results are saved. +% type [string] 'prior' or 'posterior' % % OUTPUTS -% nvar [integer] -% vartan [char] -% CorrFileNumber [integer] - -% Copyright (C) 2007-2012 Dynare Team +% nvar [integer] nvar is the number of stationary variables. +% vartan [char] array of characters (with nvar rows). +% CorrFileNumber [integer] scalar, number of prior or posterior data files (for correlation). + +% Copyright (C) 2007-2015 Dynare Team % % This file is part of Dynare. % @@ -48,6 +50,13 @@ else end NumberOfDrawsFiles = length(DrawsFiles); +%delete old stale files before creating new ones +if posterior + delete_stale_file([M_.dname '/metropolis/' M_.fname '_PosteriorCorrelations*']); +else + delete_stale_file([M_.dname '/prior/moments/' M_.fname '_PriorCorrelations*']); +end + % Set varlist (vartan) if ~posterior if isfield(options_,'varlist') diff --git a/matlab/dsge_simulated_theoretical_covariance.m b/matlab/dsge_simulated_theoretical_covariance.m index 5d39e77fb..38ef7c3b6 100644 --- a/matlab/dsge_simulated_theoretical_covariance.m +++ b/matlab/dsge_simulated_theoretical_covariance.m @@ -1,4 +1,5 @@ function [nvar,vartan,CovarFileNumber] = dsge_simulated_theoretical_covariance(SampleSize,M_,options_,oo_,type) +% function [nvar,vartan,CovarFileNumber] = dsge_simulated_theoretical_covariance(SampleSize,M_,options_,oo_,type) % This function computes the posterior or prior distribution of the endogenous % variables second order moments. % @@ -15,7 +16,7 @@ function [nvar,vartan,CovarFileNumber] = dsge_simulated_theoretical_covariance(S % vartan [char] array of characters (with nvar rows). % CovarFileNumber [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2007-2012 Dynare Team +% Copyright (C) 2007-2015 Dynare Team % % This file is part of Dynare. % @@ -48,6 +49,13 @@ else end NumberOfDrawsFiles = length(DrawsFiles); +%delete old stale files before creating new ones +if posterior + delete_stale_file([M_.dname '/metropolis/' M_.fname '_Posterior2ndOrderMoments*']) +else + delete_stale_file([M_.dname '/prior/moments/' M_.fname '_Prior2ndOrderMoments*']) +end + % Set varlist (vartan) if ~posterior if isfield(options_,'varlist') diff --git a/matlab/dsge_simulated_theoretical_variance_decomposition.m b/matlab/dsge_simulated_theoretical_variance_decomposition.m index 7059e6d13..74335840e 100644 --- a/matlab/dsge_simulated_theoretical_variance_decomposition.m +++ b/matlab/dsge_simulated_theoretical_variance_decomposition.m @@ -1,5 +1,7 @@ function [nvar,vartan,NumberOfDecompFiles] = ... dsge_simulated_theoretical_variance_decomposition(SampleSize,M_,options_,oo_,type) +% function [nvar,vartan,NumberOfDecompFiles] = ... +% dsge_simulated_theoretical_variance_decomposition(SampleSize,M_,options_,oo_,type) % This function computes the posterior or prior distribution of the variance % decomposition of the observed endogenous variables. % @@ -16,7 +18,7 @@ function [nvar,vartan,NumberOfDecompFiles] = ... % vartan [char] array of characters (with nvar rows). % CovarFileNumber [integer] scalar, number of prior or posterior data files (for covariance). -% Copyright (C) 2007-2012 Dynare Team +% Copyright (C) 2007-2015 Dynare Team % % This file is part of Dynare. % @@ -47,7 +49,13 @@ else disp('dsge_simulated_theoretical_variance_decomposition:: Unknown type!') error() end -NumberOfDrawsFiles = length(DrawsFiles); + +%delete old stale files before creating new ones +if posterior + delete_stale_file([M_.dname '/metropolis/' M_.fname '_PosteriorVarianceDecomposition*']); +else + delete_stale_file([M_.dname '/prior/moments/' M_.fname '_PosteriorVarianceDecomposition*']); +end % Set varlist (vartan) if ~posterior diff --git a/matlab/dsge_var_likelihood.m b/matlab/dsge_var_likelihood.m index 07b5d1b73..a8a9e8710 100644 --- a/matlab/dsge_var_likelihood.m +++ b/matlab/dsge_var_likelihood.m @@ -239,10 +239,38 @@ else% Evaluation of the likelihood of the dsge-var model when the dsge prior wei lik = .5*lik;% Minus likelihood end +if isnan(lik) + info = 45; + fval = objective_function_penalty_base + 100; + exit_flag = 0; + return +end + +if imag(lik)~=0 + info = 46; + fval = objective_function_penalty_base + 100; + exit_flag = 0; + return +end + % Add the (logged) prior density for the dsge-parameters. lnprior = priordens(xparam1,BayesInfo.pshape,BayesInfo.p6,BayesInfo.p7,BayesInfo.p3,BayesInfo.p4); fval = (lik-lnprior); +if isnan(fval) + info = 47; + fval = objective_function_penalty_base + 100; + exit_flag = 0; + return +end + +if imag(fval)~=0 + info = 48; + fval = objective_function_penalty_base + 100; + exit_flag = 0; + return +end + if (nargout == 8) if isinf(dsge_prior_weight) iXX = iGXX; diff --git a/matlab/dyn_second_order_solver.m b/matlab/dyn_second_order_solver.m index f4f1f8519..dd2d2bfb8 100644 --- a/matlab/dyn_second_order_solver.m +++ b/matlab/dyn_second_order_solver.m @@ -1,7 +1,7 @@ -function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_BC) +function dr = dyn_second_order_solver(jacobia,hessian_mat,dr,M_,threads_ABC,threads_BC) %@info: -%! @deftypefn {Function File} {@var{dr} =} dyn_second_order_solver (@var{jacobia},@var{hessian},@var{dr},@var{M_},@var{threads_ABC},@var{threads_BC}) +%! @deftypefn {Function File} {@var{dr} =} dyn_second_order_solver (@var{jacobia},@var{hessian_mat},@var{dr},@var{M_},@var{threads_ABC},@var{threads_BC}) %! @anchor{dyn_second_order_solver} %! @sp 1 %! Computes the second order reduced form of the DSGE model @@ -11,7 +11,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ %! @table @ @var %! @item jacobia %! Matrix containing the Jacobian of the model -%! @item hessian +%! @item hessian_mat %! Matrix containing the second order derivatives of the model %! @item dr %! Matlab's structure describing the reduced form solution of the model. @@ -73,7 +73,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ kk1 = reshape([1:nk^2],nk,nk); kk1 = kk1(kk,kk); % reordering second order derivatives - hessian = hessian(:,kk1(:)); + hessian_mat = hessian_mat(:,kk1(:)); zx = zeros(np,np); zu=zeros(np,M_.exo_nbr); @@ -91,7 +91,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ zu=[zu; eye(M_.exo_nbr);zeros(M_.exo_det_nbr,M_.exo_nbr)]; [nrzx,nczx] = size(zx); - [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian,zx,threads_BC); + [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat,zx,threads_BC); mexErrCheck('sparse_hessian_times_B_kronecker_C', err); rhs = -rhs; @@ -118,7 +118,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ %ghxu %rhs hu = dr.ghu(nstatic+1:nstatic+nspred,:); - [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian,zx,zu,threads_BC); + [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat,zx,zu,threads_BC); mexErrCheck('sparse_hessian_times_B_kronecker_C', err); hu1 = [hu;zeros(np-nspred,M_.exo_nbr)]; @@ -136,7 +136,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ %ghuu %rhs - [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian,zu,threads_BC); + [rhs, err] = sparse_hessian_times_B_kronecker_C(hessian_mat,zu,threads_BC); mexErrCheck('sparse_hessian_times_B_kronecker_C', err); [B1, err] = A_times_B_kronecker_C(B*dr.ghxx,hu1,threads_ABC); @@ -164,7 +164,7 @@ function dr = dyn_second_order_solver(jacobia,hessian,dr,M_,threads_ABC,threads_ hxx = dr.ghxx(nstatic+[1:nspred],:); [junk,k2a,k2] = find(M_.lead_lag_incidence(M_.maximum_endo_lag+2,order_var)); k3 = nnz(M_.lead_lag_incidence(1:M_.maximum_endo_lag+1,:))+(1:M_.nsfwrd)'; - [B1, err] = sparse_hessian_times_B_kronecker_C(hessian(:,kh(k3,k3)),gu(k2a,:),threads_BC); + [B1, err] = sparse_hessian_times_B_kronecker_C(hessian_mat(:,kh(k3,k3)),gu(k2a,:),threads_BC); mexErrCheck('sparse_hessian_times_B_kronecker_C', err); RHS = RHS + jacobia(:,k2)*guu(k2a,:)+B1; diff --git a/matlab/dynare.m b/matlab/dynare.m index 026670af9..3ab08aef4 100644 --- a/matlab/dynare.m +++ b/matlab/dynare.m @@ -96,6 +96,10 @@ end % Testing if file have extension % If no extension default .mod is added +dot_location=(strfind(fname,'.')); +if length(dot_location)>1 + error('DYNARE: Periods in filenames are only allowed for .mod or .dyn extensions') +end if isempty(strfind(fname,'.')) fnamelength = length(fname); fname1 = [fname '.dyn']; @@ -106,9 +110,10 @@ if isempty(strfind(fname,'.')) fname = fname1; % Checking file extension else - if ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.MOD') ... + if dot_location~=length(fname)-3 ... %if the file name has fewer than 4 characters and there is a period + || ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.MOD') ... && ~strcmp(upper(fname(size(fname,2)-3:size(fname,2))),'.DYN') - error('DYNARE: argument must be a filename with .mod or .dyn extension') + error('DYNARE: argument must be a filename with .mod or .dyn extension and must not include any other periods') end; fnamelength = length(fname) - 4; end; @@ -155,6 +160,10 @@ if ~exist(fname,'file') || isequal(fname,'dir') error(['dynare:: can''t open ' fname]) end +if ~isvarname(fname(1:end-4)) + 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.') +end + % pre-dynare-preprocessor-hook 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']) diff --git a/matlab/dynare_estimation.m b/matlab/dynare_estimation.m index 348bdf8c4..7bb49f380 100644 --- a/matlab/dynare_estimation.m +++ b/matlab/dynare_estimation.m @@ -1,9 +1,10 @@ function oo_recursive_=dynare_estimation(var_list,dname) -% function dynare_estimation(var_list) +% function dynare_estimation(var_list, dname) % runs the estimation of the model % % INPUTS % var_list: selected endogenous variables vector +% dname: alternative directory name % % OUTPUTS % oo_recursive_: cell array containing the results structures from recursive estimation @@ -11,7 +12,7 @@ function oo_recursive_=dynare_estimation(var_list,dname) % SPECIAL REQUIREMENTS % none -% Copyright (C) 2003-2014 Dynare Team +% Copyright (C) 2003-2015 Dynare Team % % This file is part of Dynare. % @@ -28,7 +29,7 @@ function oo_recursive_=dynare_estimation(var_list,dname) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -global options_ oo_ M_ +global options_ oo_ M_ dataset_ oo_recursive_={}; @@ -55,7 +56,7 @@ nnobs = length(nobs); horizon = options_.forecast; if nargin<2 || ~exist(dname) || isempty(dname) - dname = M_.fname; + dname = options_.dirname; end M_.dname = dname; @@ -91,20 +92,12 @@ else dynare_estimation_1(var_list,dname); end -if options_.mode_compute && options_.analytic_derivation, +if isnumeric(options_.mode_compute) && options_.mode_compute && options_.analytic_derivation, options_.analytic_derivation=analytic_derivation0; end if nnobs > 1 && horizon > 0 mh_replic = options_.mh_replic; - rawdata = read_variables(options_.datafile,options_.varobs,[],options_.xls_sheet,options_.xls_range); - gend = options_.nobs; - data_plot_end_point=min(options_.first_obs+gend-1+horizon,size(rawdata,1)); %compute last observation that can be plotted - rawdata = rawdata(options_.first_obs:data_plot_end_point,:); - % Take the log of the variables if needed - if options_.loglinear && ~options_.logdata % and if the data are not in logs, then... - rawdata = log(rawdata); - end endo_names = M_.endo_names; n_varobs = length(options_.varobs); @@ -132,11 +125,12 @@ if nnobs > 1 && horizon > 0 IdObs(j,1) = iobs; end end - + + gend = dataset_.nobs; time_offset=min(3,gend-1); %for observables, plot 3 previous periods unless data is shorter k = time_offset+min(nobs(end)-nobs(1)+horizon, ... - size(rawdata,1)-nobs(1)); - data2 = rawdata(end-k+1:end,:); + size(dataset_.data,1)-nobs(1)); + data2 = dataset_.data(end-k+1:end,:); [nbplt,nr,nc,lr,lc,nstar] = pltorg(nvar); m = 1; plot_index=0; diff --git a/matlab/dynare_estimation_1.m b/matlab/dynare_estimation_1.m index 5fdd91895..eba52ea28 100644 --- a/matlab/dynare_estimation_1.m +++ b/matlab/dynare_estimation_1.m @@ -261,14 +261,14 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation [xparam1, fval, exitflag, hh, options_, Scale] = dynare_minimize_objective(objective_function,xparam1,options_.mode_compute,options_,[bounds.lb bounds.ub],bayestopt_.name,bayestopt_,hh,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_); fprintf('\nFinal value of minus the log posterior (or likelihood):%f \n', fval); - if options_.mode_compute==5 && options_.analytic_derivation==-1 %reset options changed by newrat + if isnumeric(options_.mode_compute) && options_.mode_compute==5 && options_.analytic_derivation==-1 %reset options changed by newrat options_.analytic_derivation = options_analytic_derivation_old; %reset - elseif options_.mode_compute==6 %save scaling factor + elseif isnumeric(options_.mode_compute) && options_.mode_compute==6 %save scaling factor save([M_.fname '_optimal_mh_scale_parameter.mat'],'Scale'); options_.mh_jscale = Scale; bayestopt_.jscale = ones(length(xparam1),1)*Scale; end - if ~isequal(options_.mode_compute,6) %always already computes covariance matrix + if ~isnumeric(options_.mode_compute) || ~isequal(options_.mode_compute,6) %always already computes covariance matrix if options_.cova_compute == 1 %user did not request covariance not to be computed if options_.analytic_derivation && strcmp(func2str(objective_function),'dsge_likelihood'), ana_deriv_old = options_.analytic_derivation; @@ -276,12 +276,12 @@ if ~isequal(options_.mode_compute,0) && ~options_.mh_posterior_mode_estimation [junk1, junk2, hh] = feval(objective_function,xparam1, ... dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_); options_.analytic_derivation = ana_deriv_old; - elseif ~(isequal(options_.mode_compute,5) && newratflag~=1), + elseif ~isnumeric(options_.mode_compute) || ~(isequal(options_.mode_compute,5) && newratflag~=1), % with flag==0, we force to use the hessian from outer % product gradient of optimizer 5 hh = reshape(hessian(objective_function,xparam1, ... options_.gstep,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,bounds,oo_),nx,nx); - elseif isequal(options_.mode_compute,5) + elseif isnumeric(options_.mode_compute) && isequal(options_.mode_compute,5) % other numerical hessian options available with optimizer 5 % % if newratflag == 0 diff --git a/matlab/dynare_sensitivity.m b/matlab/dynare_sensitivity.m index 9d4a5085d..0a4aa0035 100644 --- a/matlab/dynare_sensitivity.m +++ b/matlab/dynare_sensitivity.m @@ -163,6 +163,11 @@ options_gsa = set_default_option(options_gsa,'istart_rmse',options_.presample+1) options_gsa = set_default_option(options_gsa,'alpha_rmse',0.001); options_gsa = set_default_option(options_gsa,'alpha2_rmse',1.e-5); +if options_gsa.neighborhood_width, + options_gsa.pprior=0; + options_gsa.ppost=0; +end + if options_gsa.redform && options_gsa.neighborhood_width==0 && isempty(options_gsa.threshold_redform), options_gsa.pprior=1; options_gsa.ppost=0; diff --git a/matlab/dynasave.m b/matlab/dynasave.m index 748b2e789..f2cc991ca 100644 --- a/matlab/dynasave.m +++ b/matlab/dynasave.m @@ -35,6 +35,10 @@ if size(var_list,1) == 0 var_list = M_.endo_names(1:M_.orig_endo_nbr, :); end +if ~isfield(oo_,'endo_simul') || isempty(oo_.endo_simul) + error('dynasave:: The results structure does not contain simulated series. Maybe the periods option has not been set.') +end + n = size(var_list,1); ivar=zeros(n,1); for i=1:n diff --git a/matlab/dyntable.m b/matlab/dyntable.m index 181d7e3ab..2330dc3ba 100644 --- a/matlab/dyntable.m +++ b/matlab/dyntable.m @@ -1,7 +1,16 @@ -function dyntable(title,headers,labels,values,label_width,val_width, ... - val_precis) - -% Copyright (C) 2002-2013 Dynare Team +function dyntable(title,headers,labels,values,label_width,val_width,val_precis) +% function dyntable(title,headers,labels,values,label_width,val_width,val_precis) +% Inputs: +% title [string] Table title +% headers [n by nchar] character array of labels for header row +% labels [n by nchar] character array of labels for label column +% values [matrix] matrix of values to display +% label_width [scalar] Width of the label +% val_width [scalar] Width of value column +% val_precis [integer] precision of displayed values +% +% +% Copyright (C) 2002-2015 Dynare Team % % This file is part of Dynare. % @@ -24,48 +33,46 @@ if options_.noprint return end -%label_width = max(size(deblank(char(headers(1,:),labels)),2)+2, ... -% label_width); -label_width = max(size(deblank(char(headers(1,:),labels)),2))+2; - -label_fmt = sprintf('%%-%ds',label_width); +%% get width of label column +if ~isempty(label_width) + label_width = max(size(deblank(char(headers(1,:),labels)),2)+2, ... + label_width); +else %use default length + label_width = max(size(deblank(char(headers(1,:),labels)),2))+2; +end +label_format_leftbound = sprintf('%%-%ds',label_width); +%% get width of label column if all(~isfinite(values)) values_length = 4; else values_length = max(ceil(max(max(log10(abs(values(isfinite(values))))))),1)+val_precis+1; end -if any(values) < 0 +if any(values) < 0 %add one character for minus sign values_length = values_length+1; end -headers_length = max(size(deblank(headers(2:end,:)),2)); -%val_width = max(values_length,val_width); -val_width = max(headers_length,values_length)+2; -%header_fmt = sprintf('%%-%ds',val_width); -val_fmt = sprintf('%%%d.%df',val_width,val_precis); -headers_offset = 0; -values_offset = 0; -if headers_length > values_length - % values_offset = ceil((val_width-values_length)/2); +%% get width of header strings +headers_length = max(size(deblank(headers(2:end,:)),2)); +if ~isempty(val_width) + val_width = max(max(headers_length,values_length)+2,val_width); +else + val_width = max(headers_length,values_length)+2; end +value_format = sprintf('%%%d.%df',val_width,val_precis); +header_string_format = sprintf('%%%ds',val_width); if length(title) > 0 - disp(sprintf('\n\n%s\n',title)); + fprintf('\n\n%s\n',title); end +%Create and print header string if length(headers) > 0 - hh = sprintf(label_fmt,headers(1,:)); + hh = sprintf(label_format_leftbound ,deblank(headers(1,:))); for i=2:size(headers,1) - hla = size(deblank(headers(i,:)),2); - hlb = ceil((val_width - hla)/2); - hla = val_width - hla - hlb; - hh = [hh char(32*ones(1,hlb)) deblank(headers(i,:)) ... - char(32*ones(1,hla))]; + hh = [hh sprintf(header_string_format,deblank(headers(i,:)))]; end disp(hh); end for i=1:size(values,1) - disp([sprintf(label_fmt,deblank(labels(i,:))) char(32*ones(1,values_offset)) sprintf(val_fmt,values(i,:))]); -end - -% 10/30/02 MJ \ No newline at end of file + disp([sprintf(label_format_leftbound ,deblank(labels(i,:))) sprintf(value_format ,values(i,:))]); +end \ No newline at end of file diff --git a/matlab/global_initialization.m b/matlab/global_initialization.m index 93deba482..690a30212 100644 --- a/matlab/global_initialization.m +++ b/matlab/global_initialization.m @@ -33,6 +33,7 @@ global oo_ M_ options_ estim_params_ bayestopt_ estimation_info ex0_ ys0_ estim_params_ = []; bayestopt_ = []; options_.datafile = ''; +options_.dirname = M_.fname; options_.dataset = []; options_.verbosity = 1; options_.terminal_condition = 0; @@ -55,6 +56,7 @@ options_.qz_zero_threshold = 1e-6; options_.lyapunov_complex_threshold = 1e-15; options_.solve_tolf = eps^(1/3); options_.solve_tolx = eps^(2/3); +options_.dr_display_tol=1e-6; options_.dp.maxit = 3000; options_.steady.maxit = 50; @@ -66,6 +68,8 @@ options_.mode_check.symmetric_plots = 1; options_.mode_check.number_of_points = 20; options_.mode_check.nolik = 0; +options_.huge_number = 1e7; + % Default number of threads for parallelized mex files. options_.threads.kronecker.A_times_B_kronecker_C = 1; options_.threads.kronecker.sparse_hessian_times_B_kronecker_C = 1; @@ -409,6 +413,7 @@ options_.recursive_estimation_restart = 0; options_.MCMC_jumping_covariance='hessian'; options_.use_calibration_initialization = 0; options_.endo_vars_for_moment_computations_in_estimation=[]; +options_.TaRB.use_TaRB = 0; % Prior restrictions options_.prior_restrictions.status = 0; @@ -525,6 +530,30 @@ simpsa.MAX_FUN_EVALS = 20000; simpsa.DISPLAY = 'iter'; options_.simpsa = simpsa; +%solveopt optimizer +solveopt.minimizer_indicator=-1; %use minimizer +solveopt.TolX=1e-6; %accuracy of argument +solveopt.TolFun=1e-6; %accuracy of function +solveopt.MaxIter=15000; +solveopt.verbosity=1; +solveopt.TolXConstraint=1.e-8; +solveopt.SpaceDilation=2.5; +solveopt.LBGradientStep=1.e-11; +options_.solveopt=solveopt; + +%simulated annealing +options_.saopt.neps=10; +options_.saopt.maximizer_indicator=0; +options_.saopt.rt=0.10; +options_.saopt.MaxIter=100000; +options_.saopt.verbosity=1; +options_.saopt.TolFun=1.0e-8; +options_.saopt.initial_temperature=15; +options_.saopt.ns=10; +options_.saopt.nt=10; +options_.saopt.step_length_c=0.1; +options_.saopt.initial_step_length=1; + % prior analysis options_.prior_mc = 20000; options_.prior_analysis_endo_var_list = []; diff --git a/matlab/gsa/filt_mc_.m b/matlab/gsa/filt_mc_.m index 329c6919d..472480135 100644 --- a/matlab/gsa/filt_mc_.m +++ b/matlab/gsa/filt_mc_.m @@ -43,7 +43,7 @@ alpha = options_gsa_.alpha_rmse; % alpha2 = options_gsa_.alpha2_rmse; alpha2 = 0; pvalue = options_gsa_.alpha2_rmse; -istart = options_gsa_.istart_rmse; +istart = max(2,options_gsa_.istart_rmse); alphaPC = 0.5; fname_ = M_.fname; @@ -242,41 +242,66 @@ end if ~options_.opt_gsa.ppost && options_.opt_gsa.lik_only if options_.opt_gsa.pprior anam='rmse_prior_post'; + atitle='RMSE prior: Log Posterior Kernel'; else anam='rmse_mc_post'; + atitle='RMSE MC: Log Posterior Kernel'; end - stab_map_1(x, ipost(1:nfilt), ipost(nfilt+1:end), anam, 1,[],OutDir); - stab_map_2(x(ipost(1:nfilt),:),alpha2,pvalue,anam, OutDir); + + options_mcf.pvalue_ks = alpha; + options_mcf.pvalue_corr = pvalue; + options_mcf.alpha2 = alpha2; + options_mcf.param_names = char(bayestopt_.name); + options_mcf.fname_ = fname_; + options_mcf.OutputDirectoryName = OutDir; + options_mcf.amcf_name = anam; + options_mcf.amcf_title = atitle; + options_mcf.title = atitle; + options_mcf.beha_title = 'better posterior kernel'; + options_mcf.nobeha_title = 'worse posterior kernel'; + mcf_analysis(x, ipost(1:nfilt), ipost(nfilt+1:end), options_mcf, options_); + if options_.opt_gsa.pprior - anam='rmse_prior_lik'; + anam = 'rmse_prior_lik'; + atitle = 'RMSE prior: Log Likelihood Kernel'; else anam='rmse_mc_lik'; + atitle = 'RMSE MC: Log Likelihood Kernel'; end - stab_map_1(x, ilik(1:nfilt), ilik(nfilt+1:end), anam, 1,[],OutDir); - stab_map_2(x(ilik(1:nfilt),:),alpha2,pvalue,anam, OutDir); + options_mcf.amcf_name = anam; + options_mcf.amcf_title = atitle; + options_mcf.title = atitle; + options_mcf.beha_title = 'better likelihood'; + options_mcf.nobeha_title = 'worse likelihood'; + mcf_analysis(x, ilik(1:nfilt), ilik(nfilt+1:end), options_mcf, options_); + else - for i=1:size(vvarvecm,1), - [dum, ixx(:,i)]=sort(rmse_MC(:,i)); - if options_.opt_gsa.ppost, + if options_.opt_gsa.ppost, + rmse_txt=rmse_pmean; + r2_txt=r2_pmean; + else + if options_.opt_gsa.pprior || ~exist('rmse_pmean'), + if exist('rmse_mode'), + rmse_txt=rmse_mode; + r2_txt=r2_mode; + else + rmse_txt=NaN(1,size(rmse_MC,2)); + r2_txt=NaN(1,size(r2_MC,2)); + end + else %nfilt0(i)=length(find(rmse_MC(:,i)alphaPC); - % if ~isempty(i2), - % j2=j2+1; - % if mod(j2,12)==1, - % ifig=ifig+1; - % figure('name',['PCA of the filtered sample ',deblank(vvarvecm(i,:)),' ',num2str(ifig)]), - % end - % subplot(3,4,j2-(ifig-1)*12) - % bar(pc(i2,j)), - % set(gca,'xticklabel',bayestopt_.name(i2)), - % set(gca,'xtick',[1:length(i2)]) - % title(['PC ',num2str(j),'. Explained ',num2str(explained(j)),'%']) - % end - % if (mod(j2,12)==0 | j==(npar+nshock)) & j2, - % saveas(gcf,[fname_,'_SA_PCA_',deblank(vvarvecm(i,:)),'_',int2str(ifig)]) - % end - % end - % close all - end +% skipline() +% disp('Starting bivariate analysis:') +% +% for i=1:size(vvarvecm,1) +% if options_.opt_gsa.ppost +% fnam = ['rmse_post_',deblank(vvarvecm(i,:))]; +% else +% if options_.opt_gsa.pprior +% fnam = ['rmse_prior_',deblank(vvarvecm(i,:))]; +% else +% fnam = ['rmse_mc_',deblank(vvarvecm(i,:))]; +% end +% end +% stab_map_2(x(ixx(1:nfilt0(i),i),:),alpha2,pvalue,fnam, OutDir,[],[temp_name ' observed variable ' deblank(vvarvecm(i,:))]); +% +% % [pc,latent,explained] = pcacov(c0); +% % %figure, bar([explained cumsum(explained)]) +% % ifig=0; +% % j2=0; +% % for j=1:npar+nshock, +% % i2=find(abs(pc(:,j))>alphaPC); +% % if ~isempty(i2), +% % j2=j2+1; +% % if mod(j2,12)==1, +% % ifig=ifig+1; +% % figure('name',['PCA of the filtered sample ',deblank(vvarvecm(i,:)),' ',num2str(ifig)]), +% % end +% % subplot(3,4,j2-(ifig-1)*12) +% % bar(pc(i2,j)), +% % set(gca,'xticklabel',bayestopt_.name(i2)), +% % set(gca,'xtick',[1:length(i2)]) +% % title(['PC ',num2str(j),'. Explained ',num2str(explained(j)),'%']) +% % end +% % if (mod(j2,12)==0 | j==(npar+nshock)) & j2, +% % saveas(gcf,[fname_,'_SA_PCA_',deblank(vvarvecm(i,:)),'_',int2str(ifig)]) +% % end +% % end +% % close all +% end end \ No newline at end of file diff --git a/matlab/gsa/log_trans_.m b/matlab/gsa/log_trans_.m index d8c726c5f..2f48c7156 100644 --- a/matlab/gsa/log_trans_.m +++ b/matlab/gsa/log_trans_.m @@ -1,4 +1,4 @@ -function [yy, xdir, isig, lam]=log_trans_(y0,xdir0) +function [yy, xdir, isig, lam]=log_trans_(y0,xdir0,isig,lam) % Copyright (C) 2012 Dynare Team % @@ -17,6 +17,12 @@ function [yy, xdir, isig, lam]=log_trans_(y0,xdir0) % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +if nargin==4, + % inverse transformation + yy = (exp(y0)-lam)*isig; + return +end + if nargin==1, xdir0=''; end @@ -67,5 +73,6 @@ else lam = -min(y0)+abs(median(y0)); %abs(100*(1+min(y0))); end end + lam = max(lam,0); yy = log(y0+lam); end diff --git a/matlab/gsa/map_calibration.m b/matlab/gsa/map_calibration.m index da933023d..6dae9fe51 100644 --- a/matlab/gsa/map_calibration.m +++ b/matlab/gsa/map_calibration.m @@ -55,7 +55,7 @@ else load(filetoload,'lpmat','lpmat0','istable','iunstable','iindeterm','iwrong' ,'infox') lpmat = [lpmat0 lpmat]; type = 'mc'; - end + end end [Nsam, np] = size(lpmat); npar = size(pnames,1); @@ -65,58 +65,91 @@ nbr_irf_restrictions = size(DynareOptions.endogenous_prior_restrictions.irf,1); nbr_moment_restrictions = size(DynareOptions.endogenous_prior_restrictions.moment,1); if init -mat_irf=cell(nbr_irf_restrictions,1); -for ij=1:nbr_irf_restrictions, - mat_irf{ij}=NaN(Nsam,length(DynareOptions.endogenous_prior_restrictions.irf{ij,3})); -end - -mat_moment=cell(nbr_moment_restrictions,1); -for ij=1:nbr_moment_restrictions, - mat_moment{ij}=NaN(Nsam,length(DynareOptions.endogenous_prior_restrictions.moment{ij,3})); -end - -irestrictions = [1:Nsam]; -h = dyn_waitbar(0,'Please wait...'); -for j=1:Nsam, - Model = set_all_parameters(lpmat(j,:)',EstimatedParameters,Model); - [Tt,Rr,SteadyState,info] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); - if info(1)==0, - [info, info_irf, info_moment, data_irf, data_moment]=endogenous_prior_restrictions(Tt,Rr,Model,DynareOptions,DynareResults); - if ~isempty(info_irf) - for ij=1:nbr_irf_restrictions, - mat_irf{ij}(j,:)=data_irf{ij}(:,2)'; - end - indx_irf(j,:)=info_irf(:,1); - end - if ~isempty(info_moment) - for ij=1:nbr_moment_restrictions, - mat_moment{ij}(j,:)=data_moment{ij}(:,2)'; - end - indx_moment(j,:)=info_moment(:,1); - end - else - irestrictions(j)=0; + mat_irf=cell(nbr_irf_restrictions,1); + for ij=1:nbr_irf_restrictions, + mat_irf{ij}=NaN(Nsam,length(DynareOptions.endogenous_prior_restrictions.irf{ij,3})); end - dyn_waitbar(j/Nsam,h,['MC iteration ',int2str(j),'/',int2str(Nsam)]) -end -dyn_waitbar_close(h); - -irestrictions=irestrictions(find(irestrictions)); -xmat=lpmat(irestrictions,:); -skipline() -endo_prior_restrictions=DynareOptions.endogenous_prior_restrictions; -save([OutputDirectoryName,filesep,fname_,'_',type,'_restrictions'],'xmat','mat_irf','mat_moment','irestrictions','indx_irf','indx_moment','endo_prior_restrictions'); -else -load([OutputDirectoryName,filesep,fname_,'_',type,'_restrictions'],'xmat','mat_irf','mat_moment','irestrictions','indx_irf','indx_moment','endo_prior_restrictions'); -end -if ~isempty(indx_irf), - % For single legend search which has maximum nbr of restrictions + mat_moment=cell(nbr_moment_restrictions,1); + for ij=1:nbr_moment_restrictions, + mat_moment{ij}=NaN(Nsam,length(DynareOptions.endogenous_prior_restrictions.moment{ij,3})); + end + + irestrictions = [1:Nsam]; + h = dyn_waitbar(0,'Please wait...'); + for j=1:Nsam, + Model = set_all_parameters(lpmat(j,:)',EstimatedParameters,Model); + if nbr_moment_restrictions, + [Tt,Rr,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults); + else + [Tt,Rr,SteadyState,info,Model,DynareOptions,DynareResults] = dynare_resolve(Model,DynareOptions,DynareResults,'restrict'); + end + if info(1)==0, + [info, info_irf, info_moment, data_irf, data_moment]=endogenous_prior_restrictions(Tt,Rr,Model,DynareOptions,DynareResults); + if ~isempty(info_irf) + for ij=1:nbr_irf_restrictions, + mat_irf{ij}(j,:)=data_irf{ij}(:,2)'; + end + indx_irf(j,:)=info_irf(:,1); + end + if ~isempty(info_moment) + for ij=1:nbr_moment_restrictions, + mat_moment{ij}(j,:)=data_moment{ij}(:,2)'; + end + indx_moment(j,:)=info_moment(:,1); + end + else + irestrictions(j)=0; + end + dyn_waitbar(j/Nsam,h,['MC iteration ',int2str(j),'/',int2str(Nsam)]) + end + dyn_waitbar_close(h); + + irestrictions=irestrictions(find(irestrictions)); + xmat=lpmat(irestrictions,:); + skipline() + endo_prior_restrictions=DynareOptions.endogenous_prior_restrictions; + save([OutputDirectoryName,filesep,fname_,'_',type,'_restrictions'],'xmat','mat_irf','mat_moment','irestrictions','indx_irf','indx_moment','endo_prior_restrictions'); +else + load([OutputDirectoryName,filesep,fname_,'_',type,'_restrictions'],'xmat','mat_irf','mat_moment','irestrictions','indx_irf','indx_moment','endo_prior_restrictions'); +end +if ~isempty(indx_irf), + skipline() + disp('Deleting old IRF calibration plots ...') + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_calib*.eps']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_calib*.fig']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_calib*.pdf']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_restrictions.eps']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_restrictions.fig']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_irf_restrictions.pdf']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + disp('done !') + skipline() + + % For single legend search which has maximum nbr of restrictions all_irf_couples = cellstr([char(endo_prior_restrictions.irf(:,1)) char(endo_prior_restrictions.irf(:,2))]); irf_couples = unique(all_irf_couples); nbr_irf_couples = size(irf_couples,1); plot_indx = NaN(nbr_irf_couples,1); time_matrix=cell(nbr_irf_couples,1); + indx_irf_matrix=zeros(length(irestrictions),nbr_irf_couples); irf_matrix=cell(nbr_irf_couples,1); irf_mean=cell(nbr_irf_couples,1); irf_median=cell(nbr_irf_couples,1); @@ -131,17 +164,21 @@ if ~isempty(indx_irf), plot_indx(ij) = find(strcmp(irf_couples,all_irf_couples(ij,:))); time_matrix{plot_indx(ij)} = [time_matrix{plot_indx(ij)} endo_prior_restrictions.irf{ij,3}]; end + iplot_indx = ones(size(plot_indx)); indx_irf = indx_irf(irestrictions,:); - h1=dyn_figure(DynareOptions,'name',[type ' evaluation of irf restrictions']); - nrow=ceil(sqrt(nbr_irf_couples)); - ncol=nrow; - if nrow*(nrow-1)>nbr_irf_couples, - ncol=nrow-1; + if ~DynareOptions.nograph, + h1=dyn_figure(DynareOptions,'name',[type ' evaluation of irf restrictions']); + nrow=ceil(sqrt(nbr_irf_couples)); + ncol=nrow; + if nrow*(nrow-1)>nbr_irf_couples, + ncol=nrow-1; + end end for ij=1:nbr_irf_restrictions, mat_irf{ij}=mat_irf{ij}(irestrictions,:); irf_matrix{plot_indx(ij)} = [irf_matrix{plot_indx(ij)} mat_irf{ij}]; + indx_irf_matrix(:,plot_indx(ij)) = indx_irf_matrix(:,plot_indx(ij)) + indx_irf(:,ij); for ik=1:size(mat_irf{ij},2), [Mean,Median,Var,HPD,Distrib] = ... posterior_moments(mat_irf{ij}(:,ik),0,DynareOptions.mh_conf_sig); @@ -156,18 +193,21 @@ if ~isempty(indx_irf), if size(mat_irf{ij},2)>1, leg = [leg,':' ,num2str(endo_prior_restrictions.irf{ij,3}(end))]; aleg = [aleg,'-' ,num2str(endo_prior_restrictions.irf{ij,3}(end))]; - end - if length(time_matrix{plot_indx(ij)})==1, - figure(h1), + iplot_indx(ij)=0; + end + if ~DynareOptions.nograph && length(time_matrix{plot_indx(ij)})==1, + set(0,'currentfigure',h1), subplot(nrow,ncol, plot_indx(ij)), hc = cumplot(mat_irf{ij}(:,ik)); - set(hc,'color','k','linewidth',2) - hold all, a=axis; + delete(hc); x1val=max(endo_prior_restrictions.irf{ij,4}(1),a(1)); x2val=min(endo_prior_restrictions.irf{ij,4}(2),a(2)); hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b'); - set(hp,'FaceAlpha', 0.5) + hold all, + set(hp,'FaceColor', [0.7 0.8 1]) + hc = cumplot(mat_irf{ij}(:,ik)); + set(hc,'color','k','linewidth',2) hold off, % hold off, title([endo_prior_restrictions.irf{ij,1},' vs ',endo_prior_restrictions.irf{ij,2}, '(', leg,')'],'interpreter','none'), @@ -185,75 +225,133 @@ if ~isempty(indx_irf), indx1 = find(indx_irf(:,ij)==0); indx2 = find(indx_irf(:,ij)~=0); atitle0=[endo_prior_restrictions.irf{ij,1},' vs ',endo_prior_restrictions.irf{ij,2}, '(', leg,')']; - fprintf(['%4.1f%% of the prior support matches IRF ',atitle0,' inside [%4.1f, %4.1f]\n'],length(indx1)/length(irestrictions)*100,endo_prior_restrictions.irf{ij,4}) + fprintf(['%4.1f%% of the ',type,' support matches IRF ',atitle0,' inside [%4.1f, %4.1f]\n'],length(indx1)/length(irestrictions)*100,endo_prior_restrictions.irf{ij,4}) % aname=[type '_irf_calib_',int2str(ij)]; aname=[type '_irf_calib_',endo_prior_restrictions.irf{ij,1},'_vs_',endo_prior_restrictions.irf{ij,2},'_',aleg]; atitle=[type ' IRF Calib: Parameter(s) driving ',endo_prior_restrictions.irf{ij,1},' vs ',endo_prior_restrictions.irf{ij,2}, '(', leg,')']; options_mcf.amcf_name = aname; options_mcf.amcf_title = atitle; - options_mcf.beha_title = 'IRF prior restriction'; - options_mcf.nobeha_title = 'NO IRF prior restriction'; + options_mcf.beha_title = 'IRF restriction'; + options_mcf.nobeha_title = 'NO IRF restriction'; options_mcf.title = atitle0; if ~isempty(indx1) && ~isempty(indx2) mcf_analysis(xmat(:,nshock+1:end), indx1, indx2, options_mcf, DynareOptions); end - -% [proba, dproba] = stab_map_1(xmat, indx1, indx2, aname, 0); -% indplot=find(proba1, - subplot(nrow,ncol, ij) - itmp = (find(plot_indx==ij)); - plot(time_matrix{ij},[max(irf_matrix{ij})' min(irf_matrix{ij})'],'k--','linewidth',2) - hold on, - plot(time_matrix{ij},irf_median{ij},'k','linewidth',2) - plot(time_matrix{ij},[irf_distrib{ij}],'k-') - a=axis; - tmp=[]; - for ir=1:length(itmp), - for it=1:length(endo_prior_restrictions.irf{itmp(ir),3}) - temp_index = find(time_matrix{ij}==endo_prior_restrictions.irf{itmp(ir),3}(it)); - tmp(temp_index,:) = endo_prior_restrictions.irf{itmp(ir),4}; + if ~DynareOptions.nograph, + set(0,'currentfigure',h1); + subplot(nrow,ncol, ij) + itmp = (find(plot_indx==ij)); + htmp = plot(time_matrix{ij},[max(irf_matrix{ij})' min(irf_matrix{ij})'],'k--','linewidth',2); + a=axis; + delete(htmp); + tmp=[]; + for ir=1:length(itmp), + for it=1:length(endo_prior_restrictions.irf{itmp(ir),3}) + temp_index = find(time_matrix{ij}==endo_prior_restrictions.irf{itmp(ir),3}(it)); + tmp(temp_index,:) = endo_prior_restrictions.irf{itmp(ir),4}; + end + end + % tmp = cell2mat(endo_prior_restrictions.irf(itmp,4)); + tmp(isinf(tmp(:,1)),1)=a(3); + tmp(isinf(tmp(:,2)),2)=a(4); + hp = patch([time_matrix{ij} time_matrix{ij}(end:-1:1)],[tmp(:,1); tmp(end:-1:1,2)],'c'); + set(hp,'FaceColor',[0.7 0.8 1]) + hold on, + plot(time_matrix{ij},[max(irf_matrix{ij})' min(irf_matrix{ij})'],'k--','linewidth',2) + plot(time_matrix{ij},irf_median{ij},'k','linewidth',2) + plot(time_matrix{ij},[irf_distrib{ij}],'k-') + plot(a(1:2),[0 0],'r') + hold off, + axis([max(1,a(1)) a(2:4)]) + box on, + set(gca,'xtick',sort(time_matrix{ij})) + itmp = min(itmp); + title([endo_prior_restrictions.irf{itmp,1},' vs ',endo_prior_restrictions.irf{itmp,2}],'interpreter','none'), + end + if any(iplot_indx.*plot_indx==ij), + % MCF of the couples with logical AND + itmp = min(find(plot_indx==ij)); + indx1 = find(indx_irf_matrix(:,ij)==0); + indx2 = find(indx_irf_matrix(:,ij)~=0); + leg = num2str(time_matrix{ij}(1)); + leg = [leg '...' num2str(time_matrix{ij}(end))]; + aleg = 'ALL'; + atitle0=[endo_prior_restrictions.irf{itmp,1},' vs ',endo_prior_restrictions.irf{itmp,2}, '(', leg,')']; + fprintf(['%4.1f%% of the ',type,' support matches IRF restrictions ',atitle0,'\n'],length(indx1)/length(irestrictions)*100) + % aname=[type '_irf_calib_',int2str(ij)]; + aname=[type '_irf_calib_',endo_prior_restrictions.irf{itmp,1},'_vs_',endo_prior_restrictions.irf{itmp,2},'_',aleg]; + atitle=[type ' IRF Calib: Parameter(s) driving ',endo_prior_restrictions.irf{itmp,1},' vs ',endo_prior_restrictions.irf{itmp,2}, '(', leg,')']; + options_mcf.amcf_name = aname; + options_mcf.amcf_title = atitle; + options_mcf.beha_title = 'IRF restriction'; + options_mcf.nobeha_title = 'NO IRF restriction'; + options_mcf.title = atitle0; + if ~isempty(indx1) && ~isempty(indx2) + mcf_analysis(xmat(:,nshock+1:end), indx1, indx2, options_mcf, DynareOptions); end end -% tmp = cell2mat(endo_prior_restrictions.irf(itmp,4)); - tmp(isinf(tmp(:,1)),1)=a(3); - tmp(isinf(tmp(:,2)),2)=a(4); - hp = patch([time_matrix{ij} time_matrix{ij}(end:-1:1)],tmp(:),'b'); - set(hp,'FaceAlpha',[0.5]) - plot(a(1:2),[0 0],'r') - hold off, - axis([max(1,a(1)) a(2:4)]) - box on, - set(gca,'xtick',sort(time_matrix{ij})) - itmp = min(itmp); - title([endo_prior_restrictions.irf{itmp,1},' vs ',endo_prior_restrictions.irf{itmp,2}],'interpreter','none'), end end - dyn_saveas(h1,[OutputDirectoryName,filesep,fname_,'_',type,'_irf_restrictions'],DynareOptions); - + if ~DynareOptions.nograph, + dyn_saveas(h1,[OutputDirectoryName,filesep,fname_,'_',type,'_irf_restrictions'],DynareOptions); + end + skipline() end if ~isempty(indx_moment) + skipline() + disp('Deleting old MOMENT calibration plots ...') + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_calib*.eps']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_calib*.fig']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_calib*.pdf']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_restrictions.eps']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_restrictions.fig']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + a=dir([OutputDirectoryName,filesep,fname_,'_',type,'_moment_restrictions.pdf']); + for j=1:length(a), + delete([OutputDirectoryName,filesep,a(j).name]); + end + disp('done !') + skipline() + options_mcf.param_names = char(BayesInfo.name); all_moment_couples = cellstr([char(endo_prior_restrictions.moment(:,1)) char(endo_prior_restrictions.moment(:,2))]); moment_couples = unique(all_moment_couples); nbr_moment_couples = size(moment_couples,1); plot_indx = NaN(nbr_moment_couples,1); time_matrix=cell(nbr_moment_couples,1); + indx_moment_matrix=zeros(length(irestrictions),nbr_moment_couples); moment_matrix=cell(nbr_moment_couples,1); moment_mean=cell(nbr_moment_couples,1); moment_median=cell(nbr_moment_couples,1); moment_var=cell(nbr_moment_couples,1); moment_HPD=cell(nbr_moment_couples,1); moment_distrib=cell(nbr_moment_couples,1); - % For single legend search which has maximum nbr of restrictions + % For single legend search which has maximum nbr of restrictions maxijv=0; for ij=1:nbr_moment_restrictions if length(endo_prior_restrictions.moment{ij,3})>maxijv @@ -262,18 +360,22 @@ if ~isempty(indx_moment) plot_indx(ij) = find(strcmp(moment_couples,all_moment_couples(ij,:))); time_matrix{plot_indx(ij)} = [time_matrix{plot_indx(ij)} endo_prior_restrictions.moment{ij,3}]; end + iplot_indx = ones(size(plot_indx)); indx_moment = indx_moment(irestrictions,:); - h2=dyn_figure(DynareOptions,'name',[type ' evaluation of moment restrictions']); - nrow=ceil(sqrt(nbr_moment_couples)); - ncol=nrow; - if nrow*(nrow-1)>nbr_moment_couples, - ncol=nrow-1; + if ~DynareOptions.nograph, + h2=dyn_figure(DynareOptions,'name',[type ' evaluation of moment restrictions']); + nrow=ceil(sqrt(nbr_moment_couples)); + ncol=nrow; + if nrow*(nrow-1)>nbr_moment_couples, + ncol=nrow-1; + end end for ij=1:nbr_moment_restrictions, mat_moment{ij}=mat_moment{ij}(irestrictions,:); moment_matrix{plot_indx(ij)} = [moment_matrix{plot_indx(ij)} mat_moment{ij}]; + indx_moment_matrix(:,plot_indx(ij)) = indx_moment_matrix(:,plot_indx(ij)) + indx_moment(:,ij); for ik=1:size(mat_moment{ij},2), [Mean,Median,Var,HPD,Distrib] = ... posterior_moments(mat_moment{ij}(:,ik),0,DynareOptions.mh_conf_sig); @@ -288,82 +390,113 @@ if ~isempty(indx_moment) if size(mat_moment{ij},2)>1, leg = [leg,':' ,num2str(endo_prior_restrictions.moment{ij,3}(end))]; aleg = [aleg,'_' ,num2str(endo_prior_restrictions.moment{ij,3}(end))]; + iplot_indx(ij)=0; end - if length(time_matrix{plot_indx(ij)})==1, - figure(h2), + if ~DynareOptions.nograph && length(time_matrix{plot_indx(ij)})==1, + set(0,'currentfigure',h2); subplot(nrow,ncol,plot_indx(ij)), hc = cumplot(mat_moment{ij}(:,ik)); - set(hc,'color','k','linewidth',2) - hold all, + a=axis; delete(hc), % hist(mat_moment{ij}), - a=axis; x1val=max(endo_prior_restrictions.moment{ij,4}(1),a(1)); x2val=min(endo_prior_restrictions.moment{ij,4}(2),a(2)); hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b'); - set(hp,'FaceAlpha', 0.5) + set(hp,'FaceColor', [0.7 0.8 1]) + hold all, + hc = cumplot(mat_moment{ij}(:,ik)); + set(hc,'color','k','linewidth',2) hold off, title([endo_prior_restrictions.moment{ij,1},' vs ',endo_prior_restrictions.moment{ij,2},'(',leg,')'],'interpreter','none'), -% if ij==maxij -% leg1 = num2str(endo_prior_restrictions.moment{ij,3}(:)); -% [legend_h,object_h,plot_h,text_strings]=legend(leg1); -% Position=get(legend_h,'Position');Position(1:2)=[-0.055 0.95-Position(4)]; -% set(legend_h,'Position',Position); -% end + % if ij==maxij + % leg1 = num2str(endo_prior_restrictions.moment{ij,3}(:)); + % [legend_h,object_h,plot_h,text_strings]=legend(leg1); + % Position=get(legend_h,'Position');Position(1:2)=[-0.055 0.95-Position(4)]; + % set(legend_h,'Position',Position); + % end end indx1 = find(indx_moment(:,ij)==0); indx2 = find(indx_moment(:,ij)~=0); atitle0=[endo_prior_restrictions.moment{ij,1},' vs ',endo_prior_restrictions.moment{ij,2}, '(', leg,')']; - fprintf(['%4.1f%% of the prior support matches MOMENT ',atitle0,' inside [%4.1f, %4.1f]\n'],length(indx1)/length(irestrictions)*100,endo_prior_restrictions.moment{ij,4}) + fprintf(['%4.1f%% of the ',type,' support matches MOMENT ',atitle0,' inside [%4.1f, %4.1f]\n'],length(indx1)/length(irestrictions)*100,endo_prior_restrictions.moment{ij,4}) % aname=[type '_moment_calib_',int2str(ij)]; aname=[type '_moment_calib_',endo_prior_restrictions.moment{ij,1},'_vs_',endo_prior_restrictions.moment{ij,2},'_',aleg]; atitle=[type ' MOMENT Calib: Parameter(s) driving ',endo_prior_restrictions.moment{ij,1},' vs ',endo_prior_restrictions.moment{ij,2}, '(', leg,')']; options_mcf.amcf_name = aname; options_mcf.amcf_title = atitle; - options_mcf.beha_title = 'moment prior restriction'; - options_mcf.nobeha_title = 'NO moment prior restriction'; + options_mcf.beha_title = 'moment restriction'; + options_mcf.nobeha_title = 'NO moment restriction'; options_mcf.title = atitle0; if ~isempty(indx1) && ~isempty(indx2) mcf_analysis(xmat, indx1, indx2, options_mcf, DynareOptions); end -% [proba, dproba] = stab_map_1(xmat, indx1, indx2, aname, 0); -% indplot=find(proba1, - subplot(nrow,ncol, ij) - itmp = (find(plot_indx==ij)); - plot(time_matrix{ij},[max(moment_matrix{ij})' min(moment_matrix{ij})'],'k--','linewidth',2) - hold on, - plot(time_matrix{ij},moment_median{ij},'k','linewidth',2) - plot(time_matrix{ij},[moment_distrib{ij}],'k-') - a=axis; - tmp=[]; - for ir=1:length(itmp), - for it=1:length(endo_prior_restrictions.moment{itmp(ir),3}) - temp_index = find(time_matrix{ij}==endo_prior_restrictions.moment{itmp(ir),3}(it)); - tmp(temp_index,:) = endo_prior_restrictions.moment{itmp(ir),4}; + if ~DynareOptions.nograph + itmp = (find(plot_indx==ij)); + set(0,'currentfigure',h2); + subplot(nrow,ncol, ij) + htmp = plot(time_matrix{ij},[max(moment_matrix{ij})' min(moment_matrix{ij})'],'k--','linewidth',2); + a=axis; + delete(htmp); + tmp=[]; + for ir=1:length(itmp), + for it=1:length(endo_prior_restrictions.moment{itmp(ir),3}) + temp_index = find(time_matrix{ij}==endo_prior_restrictions.moment{itmp(ir),3}(it)); + tmp(temp_index,:) = endo_prior_restrictions.moment{itmp(ir),4}; + end + end + % tmp = cell2mat(endo_prior_restrictions.moment(itmp,4)); + tmp(isinf(tmp(:,1)),1)=a(3); + tmp(isinf(tmp(:,2)),2)=a(4); + hp = patch([time_matrix{ij} time_matrix{ij}(end:-1:1)],[tmp(:,1); tmp(end:-1:1,2)],'b'); + set(hp,'FaceColor',[0.7 0.8 1]) + hold on, + plot(time_matrix{ij},[max(moment_matrix{ij})' min(moment_matrix{ij})'],'k--','linewidth',2) + plot(time_matrix{ij},moment_median{ij},'k','linewidth',2) + plot(time_matrix{ij},[moment_distrib{ij}],'k-') + plot(a(1:2),[0 0],'r') + hold off, + axis(a) + box on, + set(gca,'xtick',sort(time_matrix{ij})) + itmp = min(itmp); + title([endo_prior_restrictions.moment{itmp,1},' vs ',endo_prior_restrictions.moment{itmp,2}],'interpreter','none'), + end + if any(iplot_indx.*plot_indx==ij), + % MCF of the couples with logical AND + itmp = min(find(plot_indx==ij)); + indx1 = find(indx_moment_matrix(:,ij)==0); + indx2 = find(indx_moment_matrix(:,ij)~=0); + leg = num2str(time_matrix{ij}(1)); + leg = [leg '...' num2str(time_matrix{ij}(end))]; + aleg = 'ALL'; + atitle0=[endo_prior_restrictions.moment{itmp,1},' vs ',endo_prior_restrictions.moment{itmp,2}, '(', leg,')']; + fprintf(['%4.1f%% of the ',type,' support matches MOMENT restrictions ',atitle0,'\n'],length(indx1)/length(irestrictions)*100) + % aname=[type '_moment_calib_',int2str(ij)]; + aname=[type '_moment_calib_',endo_prior_restrictions.moment{itmp,1},'_vs_',endo_prior_restrictions.moment{itmp,2},'_',aleg]; + atitle=[type ' MOMENT Calib: Parameter(s) driving ',endo_prior_restrictions.moment{itmp,1},' vs ',endo_prior_restrictions.moment{itmp,2}, '(', leg,')']; + options_mcf.amcf_name = aname; + options_mcf.amcf_title = atitle; + options_mcf.beha_title = 'moment restriction'; + options_mcf.nobeha_title = 'NO moment restriction'; + options_mcf.title = atitle0; + if ~isempty(indx1) && ~isempty(indx2) + mcf_analysis(xmat, indx1, indx2, options_mcf, DynareOptions); end end -% tmp = cell2mat(endo_prior_restrictions.moment(itmp,4)); - tmp(isinf(tmp(:,1)),1)=a(3); - tmp(isinf(tmp(:,2)),2)=a(4); - hp = patch([time_matrix{ij} time_matrix{ij}(end:-1:1)],tmp(:),'b'); - set(hp,'FaceAlpha',[0.5]) - plot(a(1:2),[0 0],'r') - hold off, - axis(a) - box on, - set(gca,'xtick',sort(time_matrix{ij})) - itmp = min(itmp); - title([endo_prior_restrictions.moment{itmp,1},' vs ',endo_prior_restrictions.moment{itmp,2}],'interpreter','none'), end end - dyn_saveas(h2,[OutputDirectoryName,filesep,fname_,'_',type,'_moment_restrictions'],DynareOptions); + if ~DynareOptions.nograph, + dyn_saveas(h2,[OutputDirectoryName,filesep,fname_,'_',type,'_moment_restrictions'],DynareOptions); + end + skipline() end return diff --git a/matlab/gsa/mcf_analysis.m b/matlab/gsa/mcf_analysis.m index fb46c51bc..cb7e92a10 100644 --- a/matlab/gsa/mcf_analysis.m +++ b/matlab/gsa/mcf_analysis.m @@ -1,4 +1,4 @@ -function mcf_analysis(lpmat, ibeha, inobeha, options_mcf, DynareOptions) +function indmcf = mcf_analysis(lpmat, ibeha, inobeha, options_mcf, DynareOptions) % % Written by Marco Ratto % Joint Research Centre, The European Commission, @@ -53,7 +53,7 @@ if length(ibeha)>10 && length(inobeha)>10, indcorr = indcorr(~ismember(indcorr(:),indmcf)); indmcf = [indmcf(:); indcorr(:)]; end -if ~isempty(indmcf) +if ~isempty(indmcf) && ~DynareOptions.nograph, skipline() scatter_mcf(lpmat(ibeha,indmcf),lpmat(inobeha,indmcf), param_names(indmcf,:), ... '.', [fname_,'_',amcf_name], OutputDirectoryName, amcf_title,[], DynareOptions, ... diff --git a/matlab/gsa/redform_map.m b/matlab/gsa/redform_map.m index 7421e1c92..448b1a634 100644 --- a/matlab/gsa/redform_map.m +++ b/matlab/gsa/redform_map.m @@ -53,21 +53,31 @@ alpha2 = options_gsa_.alpha2_redform; alpha2=0; pvalue_ks = options_gsa_.ksstat_redform; pvalue_corr = options_gsa_.alpha2_redform; +pnames = M_.param_names(estim_params_.param_vals(:,1),:); +fname_ = M_.fname; bounds = prior_bounds(bayestopt_,options_); -pnames = M_.param_names(estim_params_.param_vals(:,1),:); if nargin==0, dirname=''; end if pprior load([dirname,filesep,M_.fname,'_prior'],'lpmat', 'lpmat0', 'istable','T'); - adir=[dirname filesep 'redform_stab']; + adir=[dirname filesep 'redform_prior']; + type = 'prior'; else load([dirname,filesep,M_.fname,'_mc'],'lpmat', 'lpmat0', 'istable','T'); adir=[dirname filesep 'redform_mc']; + type = 'mc'; end +options_mcf.pvalue_ks = options_gsa_.ksstat_redform; +options_mcf.pvalue_corr = options_gsa_.alpha2_redform; +options_mcf.alpha2 = options_gsa_.alpha2_redform; +options_mcf.param_names = pnames; +options_mcf.fname_ = M_.fname; +options_mcf.OutputDirectoryName = adir; + if ~exist('T') stab_map_(dirname,options_gsa_); if pprior @@ -106,6 +116,15 @@ else pd = [bayestopt_.p6(offset+1:end) bayestopt_.p7(offset+1:end) bayestopt_.p3(offset+1:end) bayestopt_.p4(offset+1:end)]; end +options_map.param_names = pnames; +options_map.fname_ = M_.fname; +options_map.OutputDirectoryName = adir; +options_map.iload = iload; +options_map.log_trans = ilog; +options_map.prior_range = options_gsa_.prior_range; +options_map.pshape = pshape; +options_map.pd = pd; + nsok = length(find(M_.lead_lag_incidence(M_.maximum_lag,:))); lpmat=[]; lpmat0=[]; @@ -119,7 +138,7 @@ for j=1:size(anamendo,1) namexo=deblank(anamexo(jx,:)); iexo=strmatch(namexo,M_.exo_names,'exact'); skipline() - disp(['[', namendo,' vs. ',namexo,']']) + disp(['[', namendo,' vs ',namexo,']']) if ~isempty(iexo), @@ -128,7 +147,7 @@ for j=1:size(anamendo,1) if (max(y0)-min(y0))>1.e-10, if mod(iplo,9)==0 && isempty(threshold) && ~options_.nograph, ifig=ifig+1; - hfig = dyn_figure(options_,'name',['Reduced Form Mapping: ', namendo,' vs. shocks ',int2str(ifig)]); + hfig = dyn_figure(options_,'name',['Reduced Form Mapping: ', namendo,' vs shocks ',int2str(ifig)]); iplo=0; end iplo=iplo+1; @@ -139,7 +158,15 @@ for j=1:size(anamendo,1) if isempty(dir(xdir0)) mkdir(xdir0) end - si(:,js) = redform_private(x0, y0, pshape, pd, iload, pnames, namendo, namexo, xdir0, options_gsa_); + atitle0=['Reduced Form Mapping (ANOVA) for ',namendo,' vs ', namexo]; + aname=[type '_' namendo '_vs_' namexo]; + atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs ',namexo]; + options_map.amap_name = aname; + options_map.amap_title = atitle; + options_map.figtitle = atitle0; + options_map.title = [namendo,' vs ', namexo]; + options_map.OutputDirectoryName = xdir0; + si(:,js) = redform_private(x0, y0, options_map, options_); else iy=find( (y0>threshold(1)) & (y0=threshold(2))); @@ -148,41 +175,65 @@ for j=1:size(anamendo,1) mkdir(xdir) end if ~options_.nograph, - hf=dyn_figure(options_,'name',['Reduced Form Mapping: ',namendo,' vs. ', namexo]); hist(y0,30), title([namendo,' vs. ', namexo],'interpreter','none') - dyn_saveas(hf,[xdir,filesep, namendo,'_vs_', namexo],options_); + hf=dyn_figure(options_,'name',['Reduced Form Mapping (Monte Carlo Filtering): ',namendo,' vs ', namexo]); + hc = cumplot(y0); + a=axis; delete(hc); + % hist(mat_moment{ij}), + x1val=max(threshold(1),a(1)); + x2val=min(threshold(2),a(2)); + hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b'); + set(hp,'FaceColor', [0.7 0.8 1]) + hold all, + hc = cumplot(y0); + set(hc,'color','k','linewidth',2) + hold off, + title([namendo,' vs ', namexo ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','none') + dyn_saveas(hf,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namexo],options_); end - % if ~isempty(iy), - % si(:,js) = redform_private(x0(iy,:), y0(iy), pshape, pd, iload, pnames, namendo, namexo, xdir, options_gsa_); - % else si(:,js) = NaN(np,1); - % end - if length(iy)>size(x0,2) && length(iyc)>size(x0,2) - delete([xdir, '/*threshold*.*']) - [proba, dproba] = stab_map_1(x0, iy, iyc, 'threshold',0); - % indsmirnov = find(dproba>ksstat); - indsmirnov = find(proba1.e-10, if mod(iplo,9)==0 && isempty(threshold) && ~options_.nograph, ifig=ifig+1; - hfig = dyn_figure(options_,'name',['Reduced Form Mapping: ' namendo,' vs. lags ',int2str(ifig)]); + hfig = dyn_figure(options_,'name',['Reduced Form Mapping: ' namendo,' vs lags ',int2str(ifig)]); iplo=0; end iplo=iplo+1; @@ -240,7 +291,15 @@ for j=1:size(anamendo,1) if isempty(dir(xdir0)) mkdir(xdir0) end - si(:,js) = redform_private(x0, y0, pshape, pd, iload, pnames, namendo, namlagendo, xdir0, options_gsa_); + atitle0=['Reduced Form Mapping (ANOVA) for ',namendo,' vs ', namlagendo]; + aname=[type '_' namendo '_vs_' namlagendo]; + atitle=[type ' Reduced Form Mapping (ANOVA): Parameter(s) driving ',namendo,' vs ',namlagendo]; + options_map.amap_name = aname; + options_map.amap_title = atitle; + options_map.figtitle = atitle0; + options_map.title = [namendo,' vs ', namlagendo]; + options_map.OutputDirectoryName = xdir0; + si(:,js) = redform_private(x0, y0, options_map, options_); else iy=find( (y0>threshold(1)) & (y0=threshold(2))); @@ -248,41 +307,67 @@ for j=1:size(anamendo,1) if isempty(dir(xdir)) mkdir(xdir) end - % if ~isempty(iy) - % si(:,js) = redform_private(x0(iy,:), y0(iy), pshape, pd, iload, pnames, namendo, namlagendo, xdir, options_gsa_); - % end if ~options_.nograph, - hf=dyn_figure(options_,'name',['Reduced Form Mapping: ',namendo,' vs. lagged ', namlagendo]); hist(y0,30), title([namendo,' vs. lagged ', namlagendo],'interpreter','none') - dyn_saveas(hf,[xdir,filesep, namendo,'_vs_', namlagendo],options_); + hf=dyn_figure(options_,'name',['Reduced Form Mapping (Monte Carlo Filtering): ',namendo,' vs lagged ', namlagendo]); + hc = cumplot(y0); + a=axis; delete(hc); + % hist(mat_moment{ij}), + x1val=max(threshold(1),a(1)); + x2val=min(threshold(2),a(2)); + hp = patch([x1val x2val x2val x1val],a([3 3 4 4]),'b'); + set(hp,'FaceColor', [0.7 0.8 1]) + hold all, + hc = cumplot(y0); + set(hc,'color','k','linewidth',2) + hold off, + title([namendo,' vs lagged ', namlagendo ' - threshold [' num2str(threshold(1)) ' ' num2str(threshold(2)) ']'],'interpreter','none') + dyn_saveas(hf,[xdir,filesep, fname_ '_' type '_' namendo,'_vs_', namlagendo],options_); end - if length(iy)>size(x0,2) && length(iyc)>size(x0,2), - delete([xdir, '/*threshold*.*']) - [proba, dproba] = stab_map_1(x0, iy, iyc, 'threshold',0); - % indsmirnov = find(dproba>ksstat); - indsmirnov = find(probanest, - gsa_ = gsa_sdp(y0(1:nfit), x0(1:nfit,:), -2, gsa_.nvr*nest^3/nfit^3,[-1 -1 -1 -1 -1 0],[],0,fname, pnames); +% gsa_ = gsa_sdp(y0(1:nest), x0(1:nest,:), 2, [],[-1 -1 -1 -1 -1 0],[],0,[fname,'_est'], pnames); + [ys,is] = sort(y0); + istep = ceil(nrun/nest); + iest = is(floor(istep/2):istep:end); + nest = length(iest); + irest = is(setdiff([1:nrun],[floor(istep/2):istep:nrun])); + istep = ceil(length(irest)/(nfit-nest)); + ifit = union(iest, irest(1:istep:end)); + if ~ismember(irest(end),ifit), + ifit = union(ifit, irest(end)); + end + nfit=length(ifit); +% ifit = union(iest, irest(randperm(nrun-nest,nfit-nest))); +% ifit = iest; +% nfit=nest; + ipred = setdiff([1:nrun],ifit); + + if ilog, + [y1, tmp, isig, lam] = log_trans_(y0(iest)); + y1 = log(y0*isig+lam); end - save([fname,'.mat'],'gsa_') - [sidum, iii]=sort(-gsa_.si); - gsa_.x0=x00(1:nfit,:); if ~options_.nograph, - hfig=gsa_sdp_plot(gsa_,fname,pnames,iii(1:min(12,np))); - if options_.nodisplay - close(hfig); + hfig=dyn_figure(options_,'name',options_map.figtitle); + subplot(221) + if ilog, + hist(y1,30), + else + hist(y0,30), end + title(options_map.title,'interpreter','none') + subplot(222) + if ilog, + hc = cumplot(y1); + else + hc = cumplot(y0); + end + set(hc,'color','k','linewidth',2) + title([options_map.title ' CDF'],'interpreter','none') end - gsa_.x0=x0(1:nfit,:); + + gsa0 = ss_anova(y0(iest), x0(iest,:), 1); + if ilog, + [gsa22, gsa1, gsax] = ss_anova_log(y1(iest), x0(iest,:), isig, lam, gsa0); + end +% if (gsa1.out.bic-gsa0.out.bic) < 10, +% y00=y0; +% gsa00=gsa0; +% gsa0=gsa1; +% y0=y1; +% ilog=1; +% end +if nfit>nest, + % gsa_ = gsa_sdp(y0(1:nfit), x0(1:nfit,:), -2, gsa_.nvr*nest^3/nfit^3,[-1 -1 -1 -1 -1 0],[],0,fname, pnames); + nvr = gsa0.nvr*nest^3/nfit^3; + nvr(gsa0.stat<2) = gsa0.nvr(gsa0.stat<2)*nest^5/nfit^5; + gsa_ = ss_anova(y0(ifit), x0(ifit,:), 1, 0, 2, nvr); + if ilog + gsa0 = gsa_; + nvr1 = gsa1.nvr*nest^3/nfit^3; + nvr1(gsa1.stat<2) = gsa1.nvr(gsa1.stat<2)*nest^5/nfit^5; + nvrx = gsax.nvr*nest^3/nfit^3; + nvrx(gsax.stat<2) = gsax.nvr(gsax.stat<2)*nest^5/nfit^5; + [gsa22, gsa1, gsax] = ss_anova_log(y1(ifit), x0(ifit,:), isig, lam, gsa0, [nvr1' nvrx']); +% gsa1 = ss_anova(y1(ifit), x0(ifit,:), 1, 0, 2, nvr); +% gsa2=gsa1; +% gsa2.y = gsa0.y; +% gsa2.fit = (exp(gsa1.fit)-lam)*isig; +% gsa2.f0 = mean(gsa2.fit); +% gsa2.out.SSE = sum((gsa2.fit-gsa2.y).^2); +% gsa2.out.bic = gsa2.out.bic-nest*log(gsa1.out.SSE)+nest*log(gsa2.out.SSE); +% gsa2.r2 = 1-cov(gsa2.fit-gsa2.y)/cov(gsa2.y); +% for j=1:np, +% gsa2.fs(:,j) = exp(gsa1.fs(:,j)).*mean(exp(gsa1.fit-gsa1.f(:,j)))*isig-lam*isig-gsa2.f0; +% gsa2.f(:,j) = exp(gsa1.f(:,j)).*mean(exp(gsa1.fit-gsa1.f(:,j)))*isig-lam*isig-gsa2.f0; +% gsa2.si(j) = var(gsa2.f(:,j))/var(gsa2.y); +% end +% nvr = gsax.nvr*nest^3/nfit^3; +% nvr(gsax.stat<2) = gsax.nvr(gsax.stat<2)*nest^5/nfit^5; +% gsax = ss_anova([gsa2.y-gsa2.fit], x0(ifit,:), 1, 0, 2, nvr); +% gsa22=gsa2; +% gsa22.fit = gsa2.fit+gsax.fit; +% gsa22.f0 = mean(gsa22.fit); +% gsa22.out.SSE = sum((gsa22.fit-gsa22.y).^2); +% gsa22.out.bic = nest*log(gsa22.out.SSE/nest) + (gsax.out.df+gsa2.out.df-1)*log(nest); +% gsa22.r2 = 1-sum((gsa22.fit-gsa22.y).^2)/sum((gsa22.y-mean(gsa22.y)).^2); +% for j=1:np, +% gsa22.fs(:,j) = gsa2.fs(:,j)+gsax.fs(:,j); +% gsa22.f(:,j) = gsa2.f(:,j)+gsax.f(:,j); +% gsa22.si(j) = var(gsa22.f(:,j))/var(gsa22.y); +% end + gsa_ = gsa22; + end +else + if ilog + gsa_ = gsa22; + else + gsa_ = gsa0; + end +end + save([fname,'_map.mat'],'gsa_') + [sidum, iii]=sort(-gsa_.si); + gsa_.x0=x00(ifit,:); + if ~options_.nograph, + hmap=gsa_sdp_plot(gsa_,[fname '_map'],pnames,iii(1:min(12,np))); + set(hmap,'name',options_map.amap_title); + end + gsa_.x0=x0(ifit,:); % copyfile([fname,'_est.mat'],[fname,'.mat']) if ~options_.nograph, - hfig=dyn_figure(options_,'name',['Reduced Form Mapping: ' namy,'_vs_', namx,'_fit']); - plot(y0(1:nfit),[gsa_.fit y0(1:nfit)],'.'), - title([namy,' vs. ', namx,' fit'],'interpreter','none') - dyn_saveas(hfig,[xdir,filesep, namy,'_vs_', namx,'_fit'],options_); + figure(hfig); + subplot(223), + plot(y0(ifit),[gsa_.fit y0(ifit)],'.'), + r2 = gsa_.r2; +% if ilog, +% plot(y00(ifit),[log_trans_(gsa_.fit,'',isig,lam) y00(ifit)],'.'), +% r2 = 1 - cov(log_trans_(gsa_.fit,'',isig,lam)-y00(ifit))/cov(y00(ifit)); +% else +% plot(y0(ifit),[gsa_.fit y0(ifit)],'.'), +% r2 = gsa_.r2; +% end + title(['Learning sample fit - R2=' num2str(r2,2)],'interpreter','none') if nfit=5 && ~isempty(gsa0), + for j=1:np, + nvr2(j) = var(diff(gsa2.fs(:,j),2)); + nvr0(j) = var(diff(gsa0.fs(:,j),2)); + end + inda = find((gsa0.stat<2)&(gsa1.stat>2)); + inda = inda(log10(nvr0(inda)./nvr2(inda))/2<0); + gsa1.nvr(inda)=gsa1.nvr(inda).*10.^(log10(nvr0(inda)./nvr2(inda))); + gsa1 = ss_anova(y, x, 1, 0, 2, gsa1.nvr); + gsa2 = log2level_map(gsa1, isig, lam); +end +if nargin==6, + gsax = ss_anova(gsa2.y-gsa2.fit, x, 1, 0, 2, nvrs(:,2)); +else + gsax = ss_anova(gsa2.y-gsa2.fit, x, 1); +end +gsa22=gsa2; +gsa22.fit = gsa2.fit+gsax.fit; +gsa22.f0 = mean(gsa22.fit); +gsa22.out.SSE = sum((gsa22.fit-gsa22.y).^2); +gsa22.out.bic = nest*log(gsa22.out.SSE/nest) + (gsax.out.df+gsa2.out.df-1)*log(nest); +gsa22.r2 = 1-sum((gsa22.fit-gsa22.y).^2)/sum((gsa22.y-mean(gsa22.y)).^2); +for j=1:np, + gsa22.fs(:,j) = gsa2.fs(:,j)+gsax.fs(:,j); + gsa22.fses(:,j) = gsax.fses(:,j); + gsa22.f(:,j) = gsa2.f(:,j)+gsax.f(:,j); + gsa22.si(j) = var(gsa22.f(:,j))/var(gsa22.y); +end + +return + +function indmcf = redform_mcf(y0, x0, options_mcf, options_) + +hfig=dyn_figure(options_,'name',options_mcf.amcf_title); + +[post_mean, post_median, post_var, hpd_interval, post_deciles, ... + density] = posterior_moments(y0,1,0.9); +post_deciles = [-inf; post_deciles; inf]; + +for jt=1:10, + indy{jt}=find( (y0>post_deciles(jt)) & (y0<=post_deciles(jt+1))); + leg{jt}=[int2str(jt) '-dec']; +end +[proba, dproba] = stab_map_1(x0, indy{1}, indy{end}, [],0); +indmcf=find(probanbr_par, + ncol=nrow-1; +end + +cmap = colormap(jet(10)); +for jx=1:nbr_par, + subplot(nrow,ncol,jx) + hold off + for jt=1:10, + h=cumplot(x0(indy{jt},indmcf(jx))); + set(h,'color', cmap(jt,:), 'linewidth', 2) + hold all, + end + title(options_mcf.param_names(indmcf(jx),:),'interpreter','none') +end +hleg = legend(leg); +aa=get(hleg,'Position'); +aa(1)=1-aa(3)-0.02; +aa(2)=0.02; +set(hleg,'Position',aa); +if ~isoctave + annotation('textbox', [0.25,0.01,0.5,0.05], ... + 'String', options_mcf.title, ... + 'Color','black',... + 'FontWeight','bold',... + 'interpreter','none',... + 'horizontalalignment','center'); +end + +dyn_saveas(hfig,[options_mcf.OutputDirectoryName filesep options_mcf.fname_,'_',options_mcf.amcf_name],options_); + +return diff --git a/matlab/gsa/scatter_mcf.m b/matlab/gsa/scatter_mcf.m index 90d363cb3..226549890 100644 --- a/matlab/gsa/scatter_mcf.m +++ b/matlab/gsa/scatter_mcf.m @@ -158,8 +158,8 @@ for i = 1:p end end if ~isoctave - annotation('textbox', [0.1,0,0.35,0.05],'String', beha_name,'Color','Blue','horizontalalignment','center'); - annotation('textbox', [0.55,0,0.35,0.05],'String', non_beha_name,'Color','Red','horizontalalignment','center'); + annotation('textbox', [0.1,0,0.35,0.05],'String', beha_name,'Color','Blue','horizontalalignment','center','interpreter','none'); + annotation('textbox', [0.55,0,0.35,0.05],'String', non_beha_name,'Color','Red','horizontalalignment','center','interpreter','none'); end if ~nograph, diff --git a/matlab/gsa/stab_map_.m b/matlab/gsa/stab_map_.m index f7db079df..876a75e8a 100644 --- a/matlab/gsa/stab_map_.m +++ b/matlab/gsa/stab_map_.m @@ -267,7 +267,11 @@ if fload==0, M_ = set_all_parameters([lpmat0(j,:) lpmat(j,:)]',estim_params_,M_); %try stoch_simul([]); try - [Tt,Rr,SteadyState,info,M_,options_,oo_] = dynare_resolve(M_,options_,oo_,'restrict'); + if ~ isempty(options_.endogenous_prior_restrictions.moment) + [Tt,Rr,SteadyState,info,M_,options_,oo_] = dynare_resolve(M_,options_,oo_); + else + [Tt,Rr,SteadyState,info,M_,options_,oo_] = dynare_resolve(M_,options_,oo_,'restrict'); + end infox(j,1)=info(1); if infox(j,1)==0 && ~exist('T'), dr_=oo_.dr; @@ -557,7 +561,7 @@ if length(iunstable)>0 || length(iwrong)>0, options_mcf.beha_title = 'unique Stable Saddle-Path'; options_mcf.nobeha_title = 'NO unique Stable Saddle-Path'; options_mcf.title = 'unique solution'; - mcf_analysis(lpmat, istable, itmp, options_mcf, options_) + mcf_analysis(lpmat, istable, itmp, options_mcf, options_); if ~isempty(iindeterm), itmp = itot(find(~ismember(itot,iindeterm))); @@ -566,7 +570,7 @@ if length(iunstable)>0 || length(iwrong)>0, options_mcf.beha_title = 'NO indeterminacy'; options_mcf.nobeha_title = 'indeterminacy'; options_mcf.title = 'indeterminacy'; - mcf_analysis(lpmat, itmp, iindeterm, options_mcf, options_) + mcf_analysis(lpmat, itmp, iindeterm, options_mcf, options_); end if ~isempty(ixun), @@ -576,7 +580,7 @@ if length(iunstable)>0 || length(iwrong)>0, options_mcf.beha_title = 'NO explosive solution'; options_mcf.nobeha_title = 'explosive solution'; options_mcf.title = 'instability'; - mcf_analysis(lpmat, itmp, ixun, options_mcf, options_) + mcf_analysis(lpmat, itmp, ixun, options_mcf, options_); end inorestriction = istable(find(~ismember(istable,irestriction))); % what went wrong beyong prior restrictions @@ -588,7 +592,7 @@ if length(iunstable)>0 || length(iwrong)>0, options_mcf.beha_title = 'NO inability to find a solution'; options_mcf.nobeha_title = 'inability to find a solution'; options_mcf.title = 'inability to find a solution'; - mcf_analysis(lpmat, itmp, iwrong, options_mcf, options_) + mcf_analysis(lpmat, itmp, iwrong, options_mcf, options_); end if ~isempty(irestriction), @@ -598,7 +602,7 @@ if length(iunstable)>0 || length(iwrong)>0, options_mcf.beha_title = 'prior IRF/moment calibration'; options_mcf.nobeha_title = 'NO prior IRF/moment calibration'; options_mcf.title = 'prior restrictions'; - mcf_analysis([lpmat0 lpmat], irestriction, inorestriction, options_mcf, options_) + mcf_analysis([lpmat0 lpmat], irestriction, inorestriction, options_mcf, options_); iok = irestriction(1); x0 = [lpmat0(iok,:)'; lpmat(iok,:)']; else diff --git a/matlab/identification_analysis.m b/matlab/identification_analysis.m index 070698838..f14e74f71 100644 --- a/matlab/identification_analysis.m +++ b/matlab/identification_analysis.m @@ -85,6 +85,9 @@ if info(1)==0, derivatives_info.DYss=dYss; if init, indJJ = (find(max(abs(JJ'),[],1)>1.e-8)); + if isempty(indJJ) && any(any(isnan(JJ))) + error('There are NaN in the JJ matrix. Please check whether your model has units roots and you forgot to set lik_init~=1.' ) + end while length(indJJ) eps2) Fx = Fxnew; Phix = Phixnew; Psix = Psixnew; - [~,DFx] = feval(FUN,x,varargin{:}); + [junk,DFx] = feval(FUN,x,varargin{:}); DPhix = DPhi(x,Fx,DFx,lb,ub,lambda1,lambda2,n,Indexset); DPsix = DPhix'*Phix; normDPsix = norm(DPsix); diff --git a/matlab/maximize_prior_density.m b/matlab/maximize_prior_density.m index 131e0422d..72df861a4 100644 --- a/matlab/maximize_prior_density.m +++ b/matlab/maximize_prior_density.m @@ -1,4 +1,4 @@ -function [xparams,lpd,hessian] = ... +function [xparams,lpd,hessian_mat] = ... maximize_prior_density(iparams, prior_shape, prior_hyperparameter_1, prior_hyperparameter_2, prior_inf_bound, prior_sup_bound,DynareOptions,DynareModel,BayesInfo,EstimatedParams,DynareResults) % Maximizes the logged prior density using Chris Sims' optimization routine. % @@ -13,7 +13,7 @@ function [xparams,lpd,hessian] = ... % OUTPUTS % xparams [double] vector, prior mode. % lpd [double] scalar, value of the logged prior density at the mode. -% hessian [double] matrix, Hessian matrix at the prior mode. +% hessian_mat [double] matrix, Hessian matrix at the prior mode. % Copyright (C) 2009-2015 Dynare Team % @@ -32,7 +32,7 @@ function [xparams,lpd,hessian] = ... % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -[xparams, lpd, exitflag, hessian]=dynare_minimize_objective('minus_logged_prior_density', ... +[xparams, lpd, exitflag, hessian_mat]=dynare_minimize_objective('minus_logged_prior_density', ... iparams, DynareOptions.mode_compute, DynareOptions, [prior_inf_bound, prior_sup_bound], ... BayesInfo.name, BayesInfo, [], ... prior_shape, prior_hyperparameter_1, prior_hyperparameter_2, prior_inf_bound, prior_sup_bound, ... diff --git a/matlab/metropolis_hastings_initialization.m b/matlab/metropolis_hastings_initialization.m index e8f4d0ef1..4650830e5 100644 --- a/matlab/metropolis_hastings_initialization.m +++ b/matlab/metropolis_hastings_initialization.m @@ -1,7 +1,7 @@ function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = ... metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -%function [ ix2, ilogpo2, ModelName, MhDirectoryName, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = -% metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds, dataset_,dataset_info,,options_,M_,estim_params_,bayestopt_,oo_) +%function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, nruns, NewFile, MAX_nruns, d ] = ... +% metropolis_hastings_initialization(TargetFun, xparam1, vv, mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) % Metropolis-Hastings initialization. % % INPUTS @@ -11,6 +11,7 @@ function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, % o vv [double] (p*p) matrix, posterior covariance matrix (at the mode). % o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. % o dataset_ data structure +% o dataset_info dataset info structure % o options_ options structure % o M_ model structure % o estim_params_ estimated parameters structure @@ -18,12 +19,25 @@ function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, % o oo_ outputs structure % % OUTPUTS -% None +% o ix2 [double] (nblck*npar) vector of starting points for different chains +% o ilogpo2 [double] (nblck*1) vector of initial posterior values for different chains +% o ModelName [string] name of the mod-file +% o MetropolisFolder [string] path to the Metropolis subfolder +% o fblck [scalar] number of the first MH chain to be run (not equal to 1 in case of recovery) +% o fline [double] (nblck*1) vector of first draw in each chain (not equal to 1 in case of recovery) +% o npar [scalar] number of parameters estimated +% o nblck [scalar] Number of MCM chains requested +% o nruns [double] (nblck*1) number of draws in each chain +% o NewFile [scalar] (nblck*1) vector storing the number +% of the first MH-file to created for each chain when saving additional +% draws +% o MAX_nruns [scalar] maximum number of draws in each MH-file on the harddisk +% o d [double] (p*p) matrix, Cholesky decomposition of the posterior covariance matrix (at the mode). % % SPECIAL REQUIREMENTS % None. -% Copyright (C) 2006-2013 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -40,6 +54,7 @@ function [ ix2, ilogpo2, ModelName, MetropolisFolder, fblck, fline, npar, nblck, % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . +%Initialize outputs ix2 = []; ilogpo2 = []; ModelName = []; @@ -68,7 +83,7 @@ MAX_nruns = ceil(options_.MaxNumberOfBytes/(npar+2)/8); d = chol(vv); if ~options_.load_mh_file && ~options_.mh_recover - % Here we start a new metropolis-hastings, previous draws are discarded. + % Here we start a new Metropolis-Hastings, previous draws are discarded. if nblck > 1 disp('Estimation::mcmc: Multiple chains mode.') else @@ -80,7 +95,7 @@ if ~options_.load_mh_file && ~options_.mh_recover delete([BaseName '_mh*_blck*.mat']); disp('Estimation::mcmc: Old mh-files successfully erased!') end - % Delete old metropolis log file. + % Delete old Metropolis log file. file = dir([ MetropolisFolder '/metropolis.log']); if length(file) delete([ MetropolisFolder '/metropolis.log']); @@ -128,11 +143,11 @@ if ~options_.load_mh_file && ~options_.mh_recover if init_iter > 100 && validate == 0 disp(['Estimation::mcmc: I couldn''t get a valid initial value in 100 trials.']) if options_.nointeractive - disp(['Estimation::mcmc: I reduce mh_init_scale by ten percent:']) + disp(['Estimation::mcmc: I reduce mh_init_scale by 10 percent:']) options_.mh_init_scale = .9*options_.mh_init_scale; disp(sprintf('Estimation::mcmc: Parameter mh_init_scale is now equal to %f.',options_.mh_init_scale)) else - disp(['Estimation::mcmc: You should Reduce mh_init_scale...']) + disp(['Estimation::mcmc: You should reduce mh_init_scale...']) disp(sprintf('Estimation::mcmc: Parameter mh_init_scale is equal to %f.',options_.mh_init_scale)) options_.mh_init_scale = input('Estimation::mcmc: Enter a new value... '); end @@ -217,7 +232,7 @@ if ~options_.load_mh_file && ~options_.mh_recover fclose(fidlog); elseif options_.load_mh_file && ~options_.mh_recover % Here we consider previous mh files (previous mh did not crash). - disp('Estimation::mcmc: I am loading past metropolis-hastings simulations...') + disp('Estimation::mcmc: I am loading past Metropolis-Hastings simulations...') load_last_mh_history_file(MetropolisFolder, ModelName); mh_files = dir([ MetropolisFolder filesep ModelName '_mh*.mat']); if ~length(mh_files) @@ -238,7 +253,7 @@ elseif options_.load_mh_file && ~options_.mh_recover nblck = past_number_of_blocks; options_.mh_nblck = nblck; end - % I read the last line of the last mh-file for initialization of the new metropolis-hastings simulations: + % I read the last line of the last mh-file for initialization of the new Metropolis-Hastings simulations: LastFileNumber = record.LastFileNumber; LastLineNumber = record.LastLineNumber; if LastLineNumber < MAX_nruns @@ -252,7 +267,7 @@ elseif options_.load_mh_file && ~options_.mh_recover ix2 = record.LastParameters; fblck = 1; NumberOfPreviousSimulations = sum(record.MhDraws(:,1),1); - fprintf('Estimation::mcmc: I am writting a new mh-history file... '); + fprintf('Estimation::mcmc: I am writing a new mh-history file... '); record.MhDraws = [record.MhDraws;zeros(1,3)]; NumberOfDrawsWrittenInThePastLastFile = MAX_nruns - LastLineNumber; NumberOfDrawsToBeSaved = nruns(1) - NumberOfDrawsWrittenInThePastLastFile; @@ -318,7 +333,7 @@ elseif options_.mh_recover disp('Estimation::mcmc: It appears that you don''t need to use the mh_recover option!') disp(' You have to edit the mod file and remove the mh_recover option') disp(' in the estimation command') - error() + error('Estimation::mcmc: mh_recover option not required!') end % I count the number of saved mh files per block. NumberOfMhFilesPerBlock = zeros(nblck,1); @@ -339,7 +354,7 @@ elseif options_.mh_recover end % How many mh-files are saved in this block? NumberOfSavedMhFilesInTheCrashedBlck = NumberOfMhFilesPerBlock(fblck); - % Correct the number of saved mh files if the crashed metropolis was not the first session (so + % Correct the number of saved mh files if the crashed Metropolis was not the first session (so % that NumberOfSavedMhFilesInTheCrashedBlck is the number of saved mh files in the crashed chain % of the current session). if OldMh diff --git a/matlab/mode_check.m b/matlab/mode_check.m index 180ba3592..39b40c4da 100644 --- a/matlab/mode_check.m +++ b/matlab/mode_check.m @@ -1,8 +1,8 @@ -function mode_check(fun,x,hessian,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults) +function mode_check(fun,x,hessian_mat,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults) % Checks the estimated ML mode or Posterior mode. %@info: -%! @deftypefn {Function File} mode_check (@var{fun}, @var{x}, @var{hessian}, @var{DynareDataset}, @var{DynareOptions}, @var{Model}, @var{EstimatedParameters}, @var{BayesInfo}, @var{DynareResults}) +%! @deftypefn {Function File} mode_check (@var{fun}, @var{x}, @var{hessian_mat}, @var{DynareDataset}, @var{DynareOptions}, @var{Model}, @var{EstimatedParameters}, @var{BayesInfo}, @var{DynareResults}) %! @anchor{mode_check} %! @sp 1 %! Checks the estimated ML mode or Posterior mode by plotting sections of the likelihood/posterior kernel. @@ -58,17 +58,17 @@ function mode_check(fun,x,hessian,DynareDataset,DatasetInfo,DynareOptions,Model, % along with Dynare. If not, see . TeX = DynareOptions.TeX; -if ~isempty(hessian); - [ s_min, k ] = min(diag(hessian)); +if ~isempty(hessian_mat); + [ s_min, k ] = min(diag(hessian_mat)); end fval = feval(fun,x,DynareDataset,DatasetInfo,DynareOptions,Model,EstimatedParameters,BayesInfo,BoundsInfo,DynareResults); -if ~isempty(hessian); +if ~isempty(hessian_mat); skipline() disp('MODE CHECK') skipline() - disp(sprintf('Fval obtained by the minimization routine: %f', fval)) + fprintf('Fval obtained by the minimization routine (minus the posterior/likelihood)): %f', fval); skipline() if s_min at a +% point used in solveopt +% +% Inputs: +% x: point at which to evaluate gradient +% f: calculated function value at a point x; +% fun: Name of the Matlab function calculating the function values +% deltax: vector of the relative stepsizes, +% obj flag indicating whether the gradient of the objective +% function (1) or the constraint function (0) is to be calculated. +% +% Modified by Giovanni Lombardo and Johannes Pfeifer to accomodate Dynare +% structure +% +% +% Copyright (C) 1997-2008, Alexei Kuntsevich and Franz Kappel +% Copyright (C) 2008-2015 Giovanni Lombardo +% Copyright (C) 2015 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 . + +n=max(size(x)); ee=ones(size(x)); +di=abs(x); idx=find(di<5e-15); di(idx)=5e-15*ee(idx); +di=deltax.*di; +if obj + idx=find(abs(di)<2e-10); + di(idx)=2e-10*sign(di(idx)); +else + idx=find(abs(di)<5e-15); + di(idx)=5e-15*sign(di(idx)); +end +y=x; + +g=NaN(n,1); +for i=1:n + y(i)=x(i)+di(i); + fi=feval(fun,y,varargin{:}); + if obj + if fi==f, + for j=1:3 + di(i)=di(i)*10; y(i)=x(i)+di(i); + fi=feval(fun,y,varargin{:}); + if fi~=f + break + end + end + end + end + g(i)=(fi-f)/di(i); + if obj + if ~isempty(idx) && any(idx==i) + y(i)=x(i)-di(i); + fi=feval(fun,y,varargin{:}); + g(i)=.5*(g(i)+(f-fi)/di(i)); + end + end + y(i)=x(i); +end diff --git a/matlab/optimization/csminit1.m b/matlab/optimization/csminit1.m index b6eb95da0..b6574b005 100644 --- a/matlab/optimization/csminit1.m +++ b/matlab/optimization/csminit1.m @@ -1,10 +1,24 @@ function [fhat,xhat,fcount,retcode] = csminit1(fcn,x0,f0,g0,badg,H0,varargin) -% [fhat,xhat,fcount,retcode] = csminit1(fcn,x0,f0,g0,badg,H0,... -% P1,P2,P3,P4,P5,P6,P7,P8) -% retcodes: 0, normal step. 5, largest step still improves too fast. -% 4,2 back and forth adjustment of stepsize didn't finish. 3, smallest -% stepsize still improves too slow. 6, no improvement found. 1, zero -% gradient. +% [fhat,xhat,fcount,retcode] = csminit1(fcn,x0,f0,g0,badg,H0,varargin) +% +% Inputs: +% fcn: [string] string naming the objective function to be minimized +% x0: [npar by 1] initial value of the parameter vector +% g0: [npar by 1] initial value of the gradient vector +% H0: [npar by npar] initial value for the inverse Hessian. Must be positive definite. +% varargin: Optional additional inputs that get handed off to fcn each +% time it is called. + +% Outputs: +% fhat: [scalar] function value at minimum +% xhat: [npar by 1] parameter vector at minimum +% fcount [scalar] function iteration count upon termination +% retcode [scalar] 0: normal step +% 1: zero gradient. +% 5: largest step still improves too fast. +% 2,4: back and forth adjustment of stepsize didn't finish. +% 3: smallest stepsize still improves too slow +% 6: no improvement found %--------------------- % Modified 7/22/96 to omit variable-length P list, for efficiency and compilation. % Places where the number of P's need to be altered or the code could be returned to @@ -15,12 +29,12 @@ function [fhat,xhat,fcount,retcode] = csminit1(fcn,x0,f0,g0,badg,H0,varargin) % % Fixed 7/19/93 to flip eigenvalues of H to get better performance when % it's not psd. - +% % Original file downloaded from: % http://sims.princeton.edu/yftp/optimize/mfiles/csminit.m - +% % Copyright (C) 1993-2007 Christopher Sims -% Copyright (C) 2008-2011 Dynare Team +% Copyright (C) 2008-2015 Dynare Team % % This file is part of Dynare. % diff --git a/matlab/optimization/csminwel1.m b/matlab/optimization/csminwel1.m index b6e38fedc..dcc579f50 100644 --- a/matlab/optimization/csminwel1.m +++ b/matlab/optimization/csminwel1.m @@ -1,29 +1,48 @@ function [fh,xh,gh,H,itct,fcount,retcodeh] = csminwel1(fcn,x0,H0,grad,crit,nit,method,epsilon,varargin) -%[fhat,xhat,ghat,Hhat,itct,fcount,retcodehat] = csminwel1(fcn,x0,H0,grad,crit,nit,method,epsilon,varargin) -% fcn: string naming the objective function to be minimized -% x0: initial value of the parameter vector -% H0: initial value for the inverse Hessian. Must be positive definite. -% grad: Either a string naming a function that calculates the gradient, or the null matrix. -% If it's null, the program calculates a numerical gradient. In this case fcn must -% be written so that it can take a matrix argument and produce a row vector of values. -% crit: Convergence criterion. Iteration will cease when it proves impossible to improve the -% function value by more than crit. -% nit: Maximum number of iterations. -% method: integer scalar, 2, 3 or 5 points formula. -% epsilon: scalar double, numerical differentiation increment -% varargin: A list of optional length of additional parameters that get handed off to fcn each -% time it is called. +%[fhat,xhat,ghat,Hhat,itct,fcount,retcodeh] = csminwel1(fcn,x0,H0,grad,crit,nit,method,epsilon,varargin) +% Inputs: +% fcn: [string] string naming the objective function to be minimized +% x0: [npar by 1] initial value of the parameter vector +% H0: [npar by npar] initial value for the inverse Hessian. Must be positive definite. +% grad: [string or empty matrix] Either a string naming a function that calculates the gradient, or the null matrix. +% If it's null, the program calculates a numerical gradient. In this case fcn must +% be written so that it can take a matrix argument and produce a row vector of values. +% crit: [scalar] Convergence criterion. Iteration will cease when it proves impossible to improve the +% function value by more than crit. +% nit: [scalar] Maximum number of iterations. +% method: [scalar] integer scalar for selecting gradient method: 2, 3 or 5 points formula. +% epsilon: [scalar] scalar double, numerical differentiation increment +% varargin: Optional additional inputs that get handed off to fcn each +% time it is called. +% % Note that if the program ends abnormally, it is possible to retrieve the current x, % f, and H from the files g1.mat and H.mat that are written at each iteration and at each % hessian update, respectively. (When the routine hits certain kinds of difficulty, it -% write g2.mat and g3.mat as well. If all were written at about the same time, any of them -% may be a decent starting point. One can also start from the one with best function value.) - +% writes g2.mat and g3.mat as well. If all were written at about the same time, any of them +% may be a decent starting point. One can also start from the one with best function value.) +% +% Outputs: +% fh: [scalar] function value at minimum +% xh: [npar by 1] parameter vector at minimum +% gh [npar by 1] gradient vector +% H [npar by npar] inverse of the Hessian matrix +% itct [scalar] iteration count upon termination +% fcount [scalar] function iteration count upon termination +% retcodeh [scalar] return code: +% 0: normal step +% 1: zero gradient +% 2: back and forth on step length never finished +% 3: smallest step still improving too slow +% 4: back and forth on step length never finished +% 5: largest step still improving too fast +% 6: smallest step still improving too slow, reversed gradient +% 7: warning: possible inaccuracy in H matrix +% % Original file downloaded from: % http://sims.princeton.edu/yftp/optimize/mfiles/csminwel.m - +% % Copyright (C) 1993-2007 Christopher Sims -% Copyright (C) 2006-2012 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -51,7 +70,6 @@ NumGrad= isempty(grad); done=0; itct=0; fcount=0; -snit=100; gh = []; H = []; retcodeh = []; @@ -74,20 +92,7 @@ if ~cost_flag end if NumGrad - switch method - case 2 - [g,badg] = numgrad2(fcn, f0, x0, epsilon, varargin{:}); - case 3 - [g,badg] = numgrad3(fcn, f0, x0, epsilon, varargin{:}); - case 5 - [g,badg] = numgrad5(fcn, f0, x0, epsilon, varargin{:}); - case 13 - [g,badg] = numgrad3_(fcn, f0, x0, epsilon, varargin{:}); - case 15 - [g,badg] = numgrad5_(fcn, f0, x0, epsilon, varargin{:}); - otherwise - error('csminwel1: Unknown method for gradient evaluation!') - end + [g, badg]=get_num_grad(method,fcn,f0,x0,epsilon,varargin{:}); elseif ischar(grad) [g,badg] = feval(grad,x0,varargin{:}); else @@ -105,19 +110,15 @@ while ~done g1=[]; g2=[]; g3=[]; %addition fj. 7/6/94 for control - disp('-----------------') - disp('-----------------') - %disp('f and x at the beginning of new iteration') - disp(sprintf('f at the beginning of new iteration, %20.10f',f)) + if Verbose + disp('-----------------') + disp(sprintf('f at the beginning of new iteration, %20.10f',f)) + end %-----------Comment out this line if the x vector is long---------------- % disp([sprintf('x = ') sprintf('%15.8g %15.8g %15.8g %15.8g\n',x)]); %------------------------- itct=itct+1; - [f1 x1 fc retcode1] = csminit1(fcn,x,f,g,badg,H,varargin{:}); - %ARGLIST - %[f1 x1 fc retcode1] = csminit(fcn,x,f,g,badg,H,P1,P2,P3,P4,P5,P6,P7,... - % P8,P9,P10,P11,P12,P13); - % itct=itct+1; + [f1, x1, fc, retcode1] = csminit1(fcn,x,f,g,badg,H,varargin{:}); fcount = fcount+fc; % erased on 8/4/94 % if (retcode == 1) || (abs(f1-f) < crit) @@ -132,22 +133,9 @@ while ~done wall1=1; badg1=1; else if NumGrad - switch method - case 2 - [g1 badg1] = numgrad2(fcn, f1, x1, epsilon, varargin{:}); - case 3 - [g1 badg1] = numgrad3(fcn, f1, x1, epsilon, varargin{:}); - case 5 - [g1,badg1] = numgrad5(fcn, f1, x1, epsilon, varargin{:}); - case 13 - [g1,badg1] = numgrad3_(fcn, f1, x1, epsilon, varargin{:}); - case 15 - [g1,badg1] = numgrad5_(fcn, f1, x1, epsilon, varargin{:}); - otherwise - error('csminwel1: Unknown method for gradient evaluation!') - end + [g1, badg1]=get_num_grad(method,fcn,f1,x1,epsilon,varargin{:}); elseif ischar(grad), - [g1 badg1] = feval(grad,x1,varargin{:}); + [g1, badg1] = feval(grad,x1,varargin{:}); else [junk1,g1,junk2, cost_flag] = feval(fcn,x1,varargin{:}); badg1 = ~cost_flag; @@ -155,8 +143,6 @@ while ~done wall1=badg1; % g1 save g1.mat g1 x1 f1 varargin; - %ARGLIST - %save g1 g1 x1 f1 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; end if wall1 % && (~done) by Jinill % Bad gradient or back and forth on step length. Possibly at @@ -164,33 +150,19 @@ while ~done % %fcliff=fh;xcliff=xh; Hcliff=H+diag(diag(H).*rand(nx,1)); - disp('Cliff. Perturbing search direction.') - [f2 x2 fc retcode2] = csminit1(fcn,x,f,g,badg,Hcliff,varargin{:}); - %ARGLIST - %[f2 x2 fc retcode2] = csminit(fcn,x,f,g,badg,Hcliff,P1,P2,P3,P4,... - % P5,P6,P7,P8,P9,P10,P11,P12,P13); + if Verbose + disp('Cliff. Perturbing search direction.') + end + [f2, x2, fc, retcode2] = csminit1(fcn,x,f,g,badg,Hcliff,varargin{:}); fcount = fcount+fc; % put by Jinill if f2 < f if retcode2==2 || retcode2==4 wall2=1; badg2=1; else if NumGrad - switch method - case 2 - [g2 badg2] = numgrad2(fcn, f2, x2, epsilon, varargin{:}); - case 3 - [g2 badg2] = numgrad3(fcn, f2, x2, epsilon, varargin{:}); - case 5 - [g2,badg2] = numgrad5(fcn, f2, x2, epsilon, varargin{:}); - case 13 - [g2,badg2] = numgrad3_(fcn, f2, x2, epsilon, varargin{:}); - case 15 - [g2,badg2] = numgrad5_(fcn, f2, x2, epsilon, varargin{:}); - otherwise - error('csminwel1: Unknown method for gradient evaluation!') - end + [g2, badg2]=get_num_grad(method,fcn,f2,x2,epsilon,varargin{:}); elseif ischar(grad), - [g2 badg2] = feval(grad,x2,varargin{:}); + [g2, badg2] = feval(grad,x2,varargin{:}); else [junk1,g2,junk2, cost_flag] = feval(fcn,x1,varargin{:}); badg2 = ~cost_flag; @@ -199,8 +171,6 @@ while ~done % g2 badg2 save g2.mat g2 x2 f2 varargin - %ARGLIST - %save g2 g2 x2 f2 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; end if wall2 disp('Cliff again. Try traversing') @@ -208,33 +178,19 @@ while ~done f3=f; x3=x; badg3=1;retcode3=101; else gcliff=((f2-f1)/((norm(x2-x1))^2))*(x2-x1); - if(size(x0,2)>1), gcliff=gcliff', end - [f3 x3 fc retcode3] = csminit1(fcn,x,f,gcliff,0,eye(nx),varargin{:}); - %ARGLIST - %[f3 x3 fc retcode3] = csminit(fcn,x,f,gcliff,0,eye(nx),P1,P2,P3,... - % P4,P5,P6,P7,P8,... - % P9,P10,P11,P12,P13); + if(size(x0,2)>1) + gcliff=gcliff'; + end + [f3, x3, fc, retcode3] = csminit1(fcn,x,f,gcliff,0,eye(nx),varargin{:}); fcount = fcount+fc; % put by Jinill if retcode3==2 || retcode3==4 - wall3=1; badg3=1; + wall3=1; + badg3=1; else if NumGrad - switch method - case 2 - [g3 badg3] = numgrad2(fcn, f3, x3, epsilon, varargin{:}); - case 3 - [g3 badg3] = numgrad3(fcn, f3, x3, epsilon, varargin{:}); - case 5 - [g3,badg3] = numgrad5(fcn, f3, x3, epsilon, varargin{:}); - case 13 - [g3,badg3] = numgrad3_(fcn, f3, x3, epsilon, varargin{:}); - case 15 - [g3,badg3] = numgrad5_(fcn, f3, x3, epsilon, varargin{:}); - otherwise - error('csminwel1: Unknown method for gradient evaluation!') - end + [g3, badg3]=get_num_grad(method,fcn,f3,x3,epsilon,varargin{:}); elseif ischar(grad), - [g3 badg3] = feval(grad,x3,varargin{:}); + [g3, badg3] = feval(grad,x3,varargin{:}); else [junk1,g3,junk2, cost_flag] = feval(fcn,x1,varargin{:}); badg3 = ~cost_flag; @@ -242,8 +198,6 @@ while ~done wall3=badg3; % g3 save g3.mat g3 x3 f3 varargin; - %ARGLIST - %save g3 g3 x3 f3 P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 P11 P12 P13; end end else @@ -292,22 +246,9 @@ while ~done end if nogh if NumGrad - switch method - case 2 - [gh,badgh] = numgrad2(fcn, fh, xh, epsilon, varargin{:}); - case 3 - [gh,badgh] = numgrad3(fcn, fh, xh, epsilon, varargin{:}); - case 5 - [gh,badgh] = numgrad5(fcn, fh, xh, epsilon, varargin{:}); - case 13 - [gh,badgh] = numgrad3_(fcn, fh, xh, epsilon, varargin{:}); - case 15 - [gh,badgh] = numgrad5_(fcn, fh, xh, epsilon, varargin{:}); - otherwise - error('csminwel1: Unknown method for gradient evaluation!') - end + [gh, badgh]=get_num_grad(method,fcn,fh,xh,epsilon,varargin{:}); elseif ischar(grad), - [gh badgh] = feval(grad, xh,varargin{:}); + [gh, badgh] = feval(grad, xh,varargin{:}); else [junk1,gh,junk2, cost_flag] = feval(fcn,x1,varargin{:}); badgh = ~cost_flag; @@ -316,11 +257,6 @@ while ~done badgh=1; end %end of picking - %ih - %fh - %xh - %gh - %badgh stuck = (abs(fh-f) < crit); if (~badg) && (~badgh) && (~stuck) H = bfgsi1(H,gh-g,xh-x); @@ -338,24 +274,47 @@ while ~done done = 1; end rc=retcodeh; - if rc == 1 - disp('zero gradient') - elseif rc == 6 - disp('smallest step still improving too slow, reversed gradient') - elseif rc == 5 - disp('largest step still improving too fast') - elseif (rc == 4) || (rc==2) - disp('back and forth on step length never finished') - elseif rc == 3 - disp('smallest step still improving too slow') - elseif rc == 7 - disp('warning: possible inaccuracy in H matrix') + if Verbose || done + if rc ==0 + %do nothing, just a normal step + elseif rc == 1 + disp('zero gradient') + elseif rc == 6 + disp('smallest step still improving too slow, reversed gradient') + elseif rc == 5 + disp('largest step still improving too fast') + elseif (rc == 4) || (rc==2) + disp('back and forth on step length never finished') + elseif rc == 3 + disp('smallest step still improving too slow') + elseif rc == 7 + disp('warning: possible inaccuracy in H matrix') + else + error('Unaccounted Case, please contact the developers') + end end - % end + f=fh; x=xh; g=gh; badg=badgh; end -% what about making an m-file of 10 lines including numgrad.m -% since it appears three times in csminwel.m \ No newline at end of file + +end + +function [g, badg]=get_num_grad(method,fcn,f0,x0,epsilon,varargin) + switch method + case 2 + [g,badg] = numgrad2(fcn, f0, x0, epsilon, varargin{:}); + case 3 + [g,badg] = numgrad3(fcn, f0, x0, epsilon, varargin{:}); + case 5 + [g,badg] = numgrad5(fcn, f0, x0, epsilon, varargin{:}); + case 13 + [g,badg] = numgrad3_(fcn, f0, x0, epsilon, varargin{:}); + case 15 + [g,badg] = numgrad5_(fcn, f0, x0, epsilon, varargin{:}); + otherwise + error('csminwel1: Unknown method for gradient evaluation!') + end +end \ No newline at end of file diff --git a/matlab/optimization/dynare_minimize_objective.m b/matlab/optimization/dynare_minimize_objective.m index 4113bf119..fc0431039 100644 --- a/matlab/optimization/dynare_minimize_objective.m +++ b/matlab/optimization/dynare_minimize_objective.m @@ -46,17 +46,13 @@ function [opt_par_values,fval,exitflag,hessian_mat,options_,Scale]=dynare_minimi %% set bounds and parameter names if not already set n_params=size(start_par_value,1); if isempty(bounds) - if minimizer_algorithm==10 + if isnumeric(minimizer_algorithm) && minimizer_algorithm==10 error('Algorithm 10 (simpsa) requires upper and lower bounds') else bounds=[-Inf(n_params,1) Inf(n_params,1)]; end end -if minimizer_algorithm==10 && any(any(isinf(bounds))) - error('Algorithm 10 (simpsa) requires finite upper and lower bounds') -end - if isempty(parameter_names) parameter_names=[repmat('parameter ',n_params,1),num2str((1:n_params)')]; end @@ -87,7 +83,51 @@ switch minimizer_algorithm [opt_par_values,fval,exitflag,output,lamdba,grad,hessian_mat] = ... fmincon(objective_function,start_par_value,[],[],[],[],bounds(:,1),bounds(:,2),[],optim_options,varargin{:}); case 2 - error('Optimization algorithm 1 option (Lester Ingber''s Adaptive Simulated Annealing) is no longer available') + %simulating annealing + sa_options = options_.saopt; + if ~isempty(options_.optim_opt) + options_list = read_key_value_string(options_.optim_opt); + for i=1:rows(options_list) + switch options_list{i,1} + case 'neps' + sa_options.neps = options_list{i,2}; + case 'rt' + sa_options.rt = options_list{i,2}; + case 'MaxIter' + sa_options.MaxIter = options_list{i,2}; + case 'TolFun' + sa_options.TolFun = options_list{i,2}; + case 'verbosity' + sa_options.verbosity = options_list{i,2}; + case 'initial_temperature' + sa_options.initial_temperature = options_list{i,2}; + case 'ns' + sa_options.ns = options_list{i,2}; + case 'nt' + sa_options.nt = options_list{i,2}; + case 'step_length_c' + sa_options.step_length_c = options_list{i,2}; + case 'initial_step_length' + sa_options.initial_step_length = options_list{i,2}; + otherwise + warning(['solveopt: Unknown option (' options_list{i,1} ')!']) + end + end + end + npar=length(start_par_value); + [LB, UB]=set_bounds_to_finite_values(bounds, options_.huge_number); + fprintf('\nNumber of parameters= %d, initial temperatur= %4.3f \n', npar,sa_options.initial_temperature); + fprintf('rt= %4.3f; TolFun= %4.3f; ns= %4.3f;\n',sa_options.rt,sa_options.TolFun,sa_options.ns); + fprintf('nt= %4.3f; neps= %4.3f; MaxIter= %d\n',sa_options.nt,sa_options.neps,sa_options.MaxIter); + fprintf('Initial step length(vm): %4.3f; step_length_c: %4.3f\n', sa_options.initial_step_length,sa_options.step_length_c); + fprintf('%-20s %-6s %-6s %-6s\n','Name:', 'LB;','Start;','UB;'); + for pariter=1:npar + fprintf('%-20s %6.4f; %6.4f; %6.4f;\n',parameter_names{pariter}, LB(pariter),start_par_value(pariter),UB(pariter)); + end + sa_options.initial_step_length= sa_options.initial_step_length*ones(npar,1); %bring step length to correct vector size + sa_options.step_length_c= sa_options.step_length_c*ones(npar,1); %bring step_length_c to correct vector size + [opt_par_values, fval,exitflag, n_accepted_draws, n_total_draws, n_out_of_bounds_draws, t, vm] =... + simulated_annealing(objective_function,start_par_value,sa_options,LB,UB,varargin{:}); case 3 if isoctave && ~user_has_octave_forge_package('optim') error('Optimization algorithm 3 requires the optim package') @@ -143,8 +183,9 @@ switch minimizer_algorithm analytic_grad=[]; end % Call csminwell. - [fval,opt_par_values,grad,hessian_mat,itct,fcount,exitflag] = ... + [fval,opt_par_values,grad,inverse_hessian_mat,itct,fcount,exitflag] = ... csminwel1(objective_function, start_par_value, H0, analytic_grad, crit, nit, numgrad, epsilon, varargin{:}); + hessian_mat=inv(inverse_hessian_mat); case 5 if options_.analytic_derivation==-1 %set outside as code for use of analytic derivation analytic_grad=1; @@ -192,7 +233,13 @@ switch minimizer_algorithm if ~isempty(options_.optim_opt) eval(['optim_options = optimset(optim_options,' options_.optim_opt ');']); end - [opt_par_values,fval,exitflag] = fminsearch(objective_function,start_par_value,optim_options,varargin{:}); + if ~isoctave + [opt_par_values,fval,exitflag] = fminsearch(objective_function,start_par_value,optim_options,varargin{:}); + else + % Under Octave, use a wrapper, since fminsearch() does not have a 4th arg + func = @(x) objective_function(x,varargin{:}); + [opt_par_values,fval,exitflag] = fminsearch(func,start_par_value,optim_options); + end case 8 % Dynare implementation of the simplex algorithm. simplexOptions = options_.simplex; @@ -273,50 +320,48 @@ switch minimizer_algorithm end simpsaOptionsList = options2cell(simpsaOptions); simpsaOptions = simpsaset(simpsaOptionsList{:}); - [opt_par_values, fval, exitflag] = simpsa(func2str(objective_function),start_par_value,bounds(:,1),bounds(:,2),simpsaOptions,varargin{:}); + [LB, UB]=set_bounds_to_finite_values(bounds, options_.huge_number); + [opt_par_values, fval, exitflag] = simpsa(func2str(objective_function),start_par_value,LB,UB,simpsaOptions,varargin{:}); case 11 options_.cova_compute = 0 ; [opt_par_values,stdh,lb_95,ub_95,med_param] = online_auxiliary_filter(start_par_value,varargin{:}) ; case 101 - myoptions=soptions; - myoptions(2)=1e-6; %accuracy of argument - myoptions(3)=1e-6; %accuracy of function (see Solvopt p.29) - myoptions(5)= 1.0; - [opt_par_values,fval]=solvopt(start_par_value,objective_function,[],myoptions,varargin{:}); + solveoptoptions = options_.solveopt; + if ~isempty(options_.optim_opt) + options_list = read_key_value_string(options_.optim_opt); + for i=1:rows(options_list) + switch options_list{i,1} + case 'TolX' + solveoptoptions.TolX = options_list{i,2}; + case 'TolFun' + solveoptoptions.TolFun = options_list{i,2}; + case 'MaxIter' + solveoptoptions.MaxIter = options_list{i,2}; + case 'verbosity' + solveoptoptions.verbosity = options_list{i,2}; + case 'SpaceDilation' + solveoptoptions.SpaceDilation = options_list{i,2}; + case 'LBGradientStep' + solveoptoptions.LBGradientStep = options_list{i,2}; + otherwise + warning(['solveopt: Unknown option (' options_list{i,1} ')!']) + end + end + end + [opt_par_values,fval]=solvopt(start_par_value,objective_function,[],[],[],solveoptoptions,varargin{:}); case 102 - %simulating annealing - LB = start_par_value - 1; - UB = start_par_value + 1; - neps=10; - % Set input parameters. - maxy=0; - epsilon=1.0e-9; - rt_=.10; - t=15.0; - ns=10; - nt=10; - maxevl=100000000; - idisp =1; - npar=length(start_par_value); - - disp(['size of param',num2str(length(start_par_value))]) - c=.1*ones(npar,1); - %* Set input values of the input/output parameters.* - - vm=1*ones(npar,1); - disp(['number of parameters= ' num2str(npar) 'max= ' num2str(maxy) 't= ' num2str(t)]); - disp(['rt_= ' num2str(rt_) 'eps= ' num2str(epsilon) 'ns= ' num2str(ns)]); - disp(['nt= ' num2str(nt) 'neps= ' num2str(neps) 'maxevl= ' num2str(maxevl)]); - disp ' '; - disp ' '; - disp(['starting values(x) ' num2str(start_par_value')]); - disp(['initial step length(vm) ' num2str(vm')]); - disp(['lower bound(lb)', 'initial conditions', 'upper bound(ub)' ]); - disp([LB start_par_value UB]); - disp(['c vector ' num2str(c')]); - - [opt_par_values, fval, nacc, nfcnev, nobds, ier, t, vm] = sa(objective_function,xparstart_par_valueam1,maxy,rt_,epsilon,ns,nt ... - ,neps,maxevl,LB,UB,c,idisp ,t,vm,varargin{:}); + if isoctave + error('Optimization algorithm 2 is not available under Octave') + elseif ~user_has_matlab_license('GADS_Toolbox') + error('Optimization algorithm 2 requires the Global Optimization Toolbox') + end + % Set default optimization options for fmincon. + optim_options = saoptimset('display','iter','TolFun',1e-8); + if ~isempty(options_.optim_opt) + eval(['optim_options = saoptimset(optim_options,' options_.optim_opt ');']); + end + func = @(x)objective_function(x,varargin{:}); + [opt_par_values,fval,exitflag,output] = simulannealbnd(func,start_par_value,bounds(:,1),bounds(:,2),optim_options); otherwise if ischar(minimizer_algorithm) if exist(options_.mode_compute) @@ -328,3 +373,12 @@ switch minimizer_algorithm error(['Optimization algorithm ' int2str(minimizer_algorithm) ' is unknown!']) end end + +end + +function [LB, UB]=set_bounds_to_finite_values(bounds, huge_number) + LB=bounds(:,1); + LB(isinf(LB))=-huge_number; + UB=bounds(:,2); + UB(isinf(UB))=huge_number; +end diff --git a/matlab/optimization/gmhmaxlik.m b/matlab/optimization/gmhmaxlik.m index 4501f845c..6ac4f79c9 100644 --- a/matlab/optimization/gmhmaxlik.m +++ b/matlab/optimization/gmhmaxlik.m @@ -20,7 +20,7 @@ function [PostMode, HessianMatrix, Scale, ModeValue] = gmhmaxlik(fun, xinit, Hin % Set default options if ~isempty(Hinit); - gmhmaxlikOptionsptions.varinit = 'previous'; + gmhmaxlikOptions.varinit = 'previous'; else gmhmaxlikOptions.varinit = 'prior'; end diff --git a/matlab/optimization/simulated_annealing.m b/matlab/optimization/simulated_annealing.m new file mode 100644 index 000000000..5b505b71d --- /dev/null +++ b/matlab/optimization/simulated_annealing.m @@ -0,0 +1,459 @@ +function [xopt, fopt,exitflag, n_accepted_draws, n_total_draws, n_out_of_bounds_draws, t, vm] = ... + simulated_annealing(fcn,x,optim,lb,ub,varargin) +% function [xopt, fopt,exitflag, n_accepted_draws, n_total_draws, n_out_of_bounds_draws, t, vm] = ... +% simulated_annealing(fcn,x,optim,lb,ub,varargin) +% +% Implements the continuous simulated annealing global optimization +% algorithm described in Corana et al. (1987) +% +% A very quick (perhaps too quick) overview of SA: +% SA tries to find the global optimum of an N dimensional function. +% It moves both up and downhill and as the optimization process +% proceeds, it focuses on the most promising area. +% To start, it randomly chooses a trial point within the step length +% VM (a vector of length N) of the user selected starting point. The +% function is evaluated at this trial point and its value is compared +% to its value at the initial point. +% In a maximization problem, all uphill moves are accepted and the +% algorithm continues from that trial point. Downhill moves may be +% accepted the decision is made by the Metropolis criteria. It uses T +% (temperature) and the size of the downhill move in a probabilistic +% manner. The smaller T and the size of the downhill move are, the more +% likely that move will be accepted. If the trial is accepted, the +% algorithm moves on from that point. If it is rejected, another point +% is chosen instead for a trial evaluation. +% Each element of VM periodically adjusted so that half of all +% function evaluations in that direction are accepted. +% A fall in T is imposed upon the system with the RT option by +% T(i+1) = RT*T(i) where i is the ith iteration. Thus, as T declines, +% downhill moves are less likely to be accepted and the percentage of +% rejections rise. Given the scheme for the selection for VM, VM falls. +% Thus, as T declines, VM falls and SA focuses upon the most promising +% area for optimization. +% +% The importance of the parameter T (initial_temperature): +% The parameter T is crucial in using SA successfully. It influences +% VM, the step length over which the algorithm searches for optima. For +% a small intial T, the step length may be too small thus not enough +% of the function might be evaluated to find the global optima. The user +% should carefully examine VM in the intermediate output (set verbosity = +% 1) to make sure that VM is appropriate. The relationship between the +% initial temperature and the resulting step length is function +% dependent. +% To determine the starting temperature that is consistent with +% optimizing a function, it is worthwhile to run a trial run first. Set +% RT = 1.5 and T = 1.0. With RT > 1.0, the temperature increases and VM +% rises as well. Then select the T that produces a large enough VM. +% +% Input Parameters: +% Note: The suggested values generally come from Corana et al. To +% drastically reduce runtime, see Goffe et al., pp. 90-1 for +% suggestions on choosing the appropriate RT and NT. +% +% fcn - function to be optimized. +% x - The starting values for the variables of the function to be +% optimized. (N) +% optim: Options structure with fields +% +% optim.maximizer_indicator - Denotes whether the function should be maximized or +% minimized. A value =1 denotes maximization while a +% value =0 denotes minimization. Intermediate output (see verbosity) +% takes this into account. +% optim.RT - The temperature reduction factor +% optim.TolFun - Error tolerance for termination. If the final function +% values from the last neps temperatures differ from the +% corresponding value at the current temperature by less than +% optim.TolFun and the final function value at the current temperature +% differs from the current optimal function value by less than +% optim.TolFun, execution terminates and exitflag = 0 is returned. +% optim.ns - Number of cycles. After NS*N function evaluations, each +% element of VM is adjusted so that approximately half of +% all function evaluations are accepted. The suggested value +% is 20. +% optim.nt - Number of iterations before temperature reduction. After +% NT*NS*N function evaluations, temperature (T) is changed +% by the factor optim.RT. Value suggested by Corana et al. is +% max(100, 5*n). See Goffe et al. for further advice. +% optim.neps - Number of final function values used to decide upon termi- +% nation. See optim.TolFun. Suggested value is 4. +% optim.MaxIter - Maximum number of function evaluations. If it is +% exceeded, exitflag = 1. +% optim.step_length_c - Vector that controls the step length adjustment. The suggested +% value for all elements is 2.0. +% optim.verbosity - controls printing inside SA. +% Values: 0 - Nothing printed. +% 1 - Function value for the starting value and summary results before each temperature +% reduction. This includes the optimal function value found so far, the total +% number of moves (broken up into uphill, downhill, accepted and rejected), the +% number of out of bounds trials, the number of new optima found at this +% temperature, the current optimal X and the step length VM. Note that there are +% N*NS*NT function evalutations before each temperature reduction. Finally, notice is +% is also given upon achieveing the termination criteria. +% 2 - Each new step length (VM), the current optimal X (XOPT) and the current trial X (X). This +% gives the user some idea about how far X strays from XOPT as well as how VM is adapting +% to the function. +% 3 - Each function evaluation, its acceptance or rejection and new optima. For many problems, +% this option will likely require a small tree if hard copy is used. This option is best +% used to learn about the algorithm. A small value for optim.MaxIter is thus recommended when +% using optim.verbosity = 3. +% optim.initial_temperature initial temperature. See Goffe et al. for advice. +% optim.initial_step_length (VM) step length vector. On input it should encompass the +% region of interest given the starting value X. For point +% X(I), the next trial point is selected is from X(I) - VM(I) +% to X(I) + VM(I). Since VM is adjusted so that about half +% of all points are accepted, the input value is not very +% important (i.e. is the value is off, SA adjusts VM to the +% correct value) +% +% lb - The lower bound for the allowable solution variables. +% ub - The upper bound for the allowable solution variables. +% If the algorithm chooses X(I) < LB(I) or X(I) > UB(I), +% I = 1, N, a point is from inside is randomly selected. +% This focuses the algorithm on the region inside UB and LB. +% Unless the user wishes to concentrate the search to a par- +% ticular region, UB and LB should be set to very large positive +% and negative values, respectively. Note that the starting +% vector X should be inside this region. Also note that LB and +% UB are fixed in position, while VM is centered on the last +% accepted trial set of variables that optimizes the function. +% +% +% Input/Output Parameters: +% +% Output Parameters: +% xopt - The variables that optimize the function. (N) +% fopt - The optimal value of the function. +% exitflag - The error return number. +% Values: 0 - Normal return termination criteria achieved. +% 1 - Number of function evaluations (NFCNEV) is +% greater than the maximum number (optim.MaxIter). +% 2 - The starting value (X) is not inside the +% bounds (LB and UB). +% 3 - The initial temperature is not positive. +% 99 - Should not be seen only used internally. +% n_accepted_draws - The number of accepted function evaluations. +% n_total_draws - The total number of function evaluations. In a minor +% point, note that the first evaluation is not used in the +% core of the algorithm it simply initializes the +% algorithm. +% n_out_of_bounds_draws - The total number of trial function evaluations that +% would have been out of bounds of LB and UB. Note that +% a trial point is randomly selected between LB and UB. +% t: On output, the final temperature. +% vm: Final step length vector +% +% Algorithm: +% This routine implements the continuous simulated annealing global +% optimization algorithm described in Corana et al.'s article +% "Minimizing Multimodal Functions of Continuous Variables with the +% "Simulated Annealing" Algorithm" in the September 1987 (vol. 13, +% no. 3, pp. 262-280) issue of the ACM Transactions on Mathematical +% Software. +% +% For modifications to the algorithm and many details on its use, +% (particularly for econometric applications) see Goffe, Ferrier +% and Rogers, "Global Optimization of Statistical Functions with +% Simulated Annealing," Journal of Econometrics, vol. 60, no. 1/2, +% Jan./Feb. 1994, pp. 65-100. +% +% Based on the Matlab code written by Thomas Werner (Bundesbank December +% 2002), which in turn is based on the GAUSS version of Bill Goffe's simulated annealing +% program for global optimization, written by E.G.Tsionas (9/4/95). +% +% Copyright (C) 1995 E.G.Tsionas +% Copyright (C) 1995-2002 Thomas Werner +% Copyright (C) 2002-2015 Giovanni Lombardo +% Copyright (C) 2015 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 . + +c=optim.step_length_c; +t=optim.initial_temperature; +vm=optim.initial_step_length; +n=size(x,1); +xp=zeros(n,1); +%* Set initial values.* +n_accepted_draws=0; +n_out_of_bounds_draws=0; +n_total_draws=0; +exitflag=99; +xopt=x; +nacp=zeros(n,1); +fstar=1e20*ones(optim.neps,1); +%* If the initial temperature is not positive, notify the user and abort. * +if(t<=0.0); + fprintf('\nThe initial temperature is not positive. Reset the variable t\n'); + exitflag=3; + return; +end; +%* If the initial value is out of bounds, notify the user and abort. * +if(sum(x>ub)+sum(x0); + fprintf('\nInitial condition out of bounds\n'); + exitflag=2; + return; +end; +%* Evaluate the function with input x and return value as f. * +f=feval(fcn,x,varargin{:}); +%* +% If the function is to be minimized, switch the sign of the function. +% Note that all intermediate and final output switches the sign back +% to eliminate any possible confusion for the user. +%* +if(optim.maximizer_indicator==0); + f=-f; +end; +n_total_draws=n_total_draws+1; +fopt=f; +fstar(1)=f; +if(optim.verbosity >1); + disp ' '; + disp(['initial x ' num2str(x(:)')]); + if(optim.maximizer_indicator); + disp(['initial f ' num2str(f)]); + else + disp(['initial f ' num2str(-f)]); + end; +end; +% Start the main loop. Note that it terminates if (i) the algorithm +% succesfully optimizes the function or (ii) there are too many +% function evaluations (more than optim.MaxIter). + +while (1>0); + nup=0; + nrej=0; + nnew=0; + ndown=0; + lnobds=0; + m=1; + while m<=optim.nt; + j=1; + while j<=optim.ns; + h=1; + while h<=n; + %* Generate xp, the trial value of x. Note use of vm to choose xp. * + i=1; + while i<=n; + if(i==h); + xp(i)=x(i)+(rand(1,1)*2.0-1.0)*vm(i); + else + xp(i)=x(i); + end; + %* If xp is out of bounds, select a point in bounds for the trial. * + if((xp(i)ub(i))); + xp(i)=lb(i)+(ub(i)-lb(i))*rand(1,1); + lnobds=lnobds+1; + n_out_of_bounds_draws=n_out_of_bounds_draws+1; + if(optim.verbosity >=3); + if exist('fp','var') + print_current_invalid_try(optim.maximizer_indicator,xp,x,fp,f); + end + end; + end; + i=i+1; + end; + %* Evaluate the function with the trial point xp and return as fp. * + % fp=feval(fcn,xp,listarg); + fp=feval(fcn,xp,varargin{:}); + if(optim.maximizer_indicator==0); + fp=-fp; + end; + n_total_draws=n_total_draws+1; + if(optim.verbosity >=3); + print_current_valid_try(optim.maximizer_indicator,xp,x,fp,f); + end; + %* If too many function evaluations occur, terminate the algorithm. * + if(n_total_draws>=optim.MaxIter); + fprintf('Too many function evaluations; consider\n'); + fprintf('increasing optim.MaxIter or optim.TolFun or decreasing\n'); + fprintf('optim.nt or optim.rt. These results are likely to be poor\n'); + if(optim.maximizer_indicator==0); + fopt=-fopt; + end; + exitflag=1; + return; + end; + %* Accept the new point if the function value increases. * + if(fp>=f); + if(optim.verbosity >=3); + fprintf('point accepted\n'); + end; + x=xp; + f=fp; + n_accepted_draws=n_accepted_draws+1; + nacp(h)=nacp(h)+1; + nup=nup+1; + %* If greater than any other point, record as new optimum. * + if(fp>fopt); + if(optim.verbosity >=3); + fprintf('new optimum\n'); + end; + xopt=xp; + fopt=fp; + nnew=nnew+1; + end; + %* + % If the point is lower, use the Metropolis criteria to decide on + % acceptance or rejection. + %* + else + p=exp((fp-f)/t); + pp=rand(1,1); + if(pp=3); + if(optim.maximizer_indicator); + fprintf('though lower, point accepted\n'); + else + fprintf('though higher, point accepted\n'); + end; + end; + x=xp; + f=fp; + n_accepted_draws=n_accepted_draws+1; + nacp(h)=nacp(h)+1; + ndown=ndown+1; + else + nrej=nrej+1; + if(optim.verbosity >=3); + if(optim.maximizer_indicator); + fprintf('lower point rejected\n'); + else + fprintf('higher point rejected\n'); + end; + end; + end; + end; + h=h+1; + end; + j=j+1; + end; + %* Adjust vm so that approximately half of all evaluations are accepted. * + i=1; + while i<=n; + ratio=nacp(i)/optim.ns; + if(ratio>.6); + vm(i)=vm(i)*(1.+c(i)*(ratio-.6)/.4); + elseif(ratio<.4); + vm(i)=vm(i)/(1.+c(i)*((.4-ratio)/.4)); + end; + if(vm(i)>(ub(i)-lb(i))); + vm(i)=ub(i)-lb(i); + end; + i=i+1; + end; + if(optim.verbosity >=2); + fprintf('intermediate results after step length adjustment\n'); + fprintf('new step length(vm) %4.3f', vm(:)'); + fprintf('current optimal x %4.3f', xopt(:)'); + fprintf('current x %4.3f', x(:)'); + end; + nacp=zeros(n,1); + m=m+1; + end; + if(optim.verbosity >=1); + print_intermediate_statistics(optim.maximizer_indicator,t,xopt,vm,fopt,nup,ndown,nrej,lnobds,nnew); + end; + %* Check termination criteria. * + quit=0; + fstar(1)=f; + if((fopt-fstar(1))<=optim.TolFun); + quit=1; + end; + if(sum(abs(f-fstar)>optim.TolFun)>0); + quit=0; + end; + %* Terminate SA if appropriate. * + if(quit); + exitflag=0; + if(optim.maximizer_indicator==0); + fopt=-fopt; + end; + if(optim.verbosity >=1); + fprintf('SA achieved termination criteria.exitflag=0\n'); + end; + return; + end; + %* If termination criteria are not met, prepare for another loop. * + t=optim.rt*t; + i=optim.neps; + while i>=2; + fstar(i)=fstar(i-1); + i=i-1; + end; + f=fopt; + x=xopt; + %* Loop again. * +end; + +end + +function print_current_invalid_try(max,xp,x,fp,f) +fprintf('\n'); + disp(['Current x ' num2str(x(:)')]); +if(max); + disp(['Current f ' num2str(f)]); +else + disp(['Current f ' num2str(-f)]); +end; +disp(['Trial x ' num2str(xp(:)')]); +disp 'Point rejected since out of bounds'; +end + +function print_current_valid_try(max,xp,x,fp,f) + +disp(['Current x ' num2str(x(:)')]); +if(max); + disp(['Current f ' num2str(f)]); + disp(['Trial x ' num2str(xp(:)')]); + disp(['Resulting f ' num2str(fp)]); +else + disp(['Current f ' num2str(-f)]); + disp(['Trial x ' num2str(xp(:)')]); + disp(['Resulting f ' num2str(-fp)]); +end; +end + + +function print_intermediate_statistics(max,t,xopt,vm,fopt,nup,ndown,nrej,lnobds,nnew) + +totmov=nup+ndown+nrej; +fprintf('\nIntermediate results before next temperature reduction\n'); +disp(['current temperature ' num2str(t)]); + +if(max) + disp(['Max function value so far ' num2str(fopt)]); + disp(['Total moves ' num2str(totmov)]); + disp(['Uphill ' num2str(nup)]); + disp(['Accepted downhill ' num2str(ndown)]); + disp(['Rejected downhill ' num2str(nrej)]); + disp(['Out of bounds trials ' num2str(lnobds)]); + disp(['New maxima this temperature ' num2str(nnew)]); +else + disp(['Min function value so far ' num2str(-fopt)]); + disp(['Total moves ' num2str(totmov)]); + disp(['Downhill ' num2str(nup)]); + disp(['Accepted uphill ' num2str(ndown)]); + disp(['Rejected uphill ' num2str(nrej)]); + disp(['Trials out of bounds ' num2str(lnobds)]); + disp(['New minima this temperature ' num2str(nnew)]); +end +xopt1=xopt(1:round(length(xopt)/2)); +xopt2=xopt(round(length(xopt)/2)+1:end); + +disp(['Current optimal x1 ' num2str(xopt1')]); +disp(['Current optimal x2 ' num2str(xopt2')]); +disp(['Strength(vm) ' num2str(vm')]); +fprintf('\n'); +end \ No newline at end of file diff --git a/matlab/optimization/solvopt.m b/matlab/optimization/solvopt.m new file mode 100644 index 000000000..6d5693e86 --- /dev/null +++ b/matlab/optimization/solvopt.m @@ -0,0 +1,991 @@ +function [x,f,exitflag,n_f_evals,n_grad_evals,n_constraint_evals,n_constraint_gradient_evals]=solvopt(x,fun,grad,func,gradc,optim,varargin) +% [x,f,options]=solvopt(x,fun,grad,func,gradc,options,varargin) +% +% The function SOLVOPT, developed by Alexei Kuntsevich and Franz Kappe, +% performs a modified version of Shor's r-algorithm in +% order to find a local minimum resp. maximum of a nonlinear function +% defined on the n-dimensional Euclidean space or % a solution of a nonlinear +% constrained problem: +% min { f(x): g(x) (<)= 0, g(x) in R(m), x in R(n) } +% +% Inputs: +% x n-vector (row or column) of the coordinates of the starting +% point, +% fun name of an M-file (M-function) which computes the value +% of the objective function at a point x, +% synopsis: f=fun(x) +% grad name of an M-file (M-function) which computes the gradient +% vector of the function at a point x, +% synopsis: g=grad(x) +% func name of an M-file (M-function) which computes the MAXIMAL +% RESIDUAL(!) for a set of constraints at a point x, +% synopsis: fc=func(x) +% gradc name of an M-file (M-function) which computes the gradient +% vector for the maximal residual constraint at a point x, +% synopsis: gc=gradc(x) +% optim Options structure with fields: +% optim.minimizer_indicator= H, where sign(H)=-1 resp. sign(H)=+1 means minimize +% resp. maximize (valid only for unconstrained problem) +% and H itself is a factor for the initial trial step size +% (optim.minimizer_indicator=-1 by default), +% optim.TolX= relative error for the argument in terms of the +% infinity-norm (1.e-4 by default), +% optim.TolFun= relative error for the function value (1.e-6 by default), +% optim.MaxIter= limit for the number of iterations (15000 by default), +% optim.verbosity= control of the display of intermediate results and error +% resp. warning messages (default value is 0, i.e., no intermediate +% output but error and warning messages, see more in the manual), +% optim.TolXConstraint= admissible maximal residual for a set of constraints +% (optim.TolXConstraint=1e-8 by default, see more in the manual), +% *optim.SpaceDilation= the coefficient of space dilation (2.5 by default), +% *optim.LBGradientStep= lower bound for the stepsize used for the difference +% approximation of gradients (1e-12 by default, see more in the manual). +% (* ... changes should be done with care) +% +% Outputs: +% x optimal parameter vector (row resp. column), +% f optimum function value +% exitflag: the number of iterations, if positive, +% or an abnormal stop code, if negative (see more in the manual), +% n_f_evals: number of objective evaluations +% n_grad_evals: number of gradient evaluations, +% n_constraint_evals: number of constraint function evaluations, +% n_constraint_gradient_evals number of constraint gradient evaluations. +% +% +% Algorithm: Kuntsevich, A.V., Kappel, F., SolvOpt - The solver for local nonlinear optimization problems +% (version 1.1, Matlab, C, FORTRAN). University of Graz, Graz, 1997. +% +% +% Copyright (C) 1997-2008, Alexei Kuntsevich and Franz Kappel +% Copyright (C) 2008-2015 Giovanni Lombardo +% Copyright (C) 2015 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 . + + + +% strings: ----{ +errmes='SolvOpt error:'; +wrnmes='SolvOpt warning:'; +error1='No function name and/or starting point passed to the function.'; +error2='Argument X has to be a row or column vector of dimension > 1.'; +error30=' returns an empty string.'; +error31='Function value does not exist (NaN is returned).'; +error32='Function equals infinity at the point.'; +error40=' returns an improper matrix. Check the dimension.'; +error41='Gradient does not exist (NaN is returned by ).'; +error42='Gradient equals infinity at the starting point.'; +error43='Gradient equals zero at the starting point.'; +error50=' returns an empty string.'; +error51=' returns NaN at the point.'; +error52=' returns infinite value at the point.'; +error60=' returns an improper vector. Check the dimension'; +error61=' returns NaN at the point.'; +error62=' returns infinite vector at the point.'; +error63=' returns zero vector at an infeasible point.'; +error5='Function is unbounded.'; +error6='Choose another starting point.'; +warn1= 'Gradient is zero at the point, but stopping criteria are not fulfilled.'; +warn20='Normal re-setting of a transformation matrix.' ; +warn21='Re-setting due to the use of a new penalty coefficient.' ; +warn4= 'Iterations limit exceeded.'; +warn31='The function is flat in certain directions.'; +warn32='Trying to recover by shifting insensitive variables.'; +warn09='Re-run from recorded point.'; +warn08='Ravine with a flat bottom is detected.'; +termwarn0='SolvOpt: Normal termination.'; +termwarn1='SolvOpt: Termination warning:'; +appwarn='The above warning may be reasoned by inaccurate gradient approximation'; +endwarn=[... + 'Premature stop is possible. Try to re-run the routine from the obtained point. ';... + 'Result may not provide the optimum. The function apparently has many extremum points. ';... + 'Result may be inaccurate in the coordinates. The function is flat at the optimum. ';... + 'Result may be inaccurate in a function value. The function is extremely steep at the optimum.']; +% ----} + +% ARGUMENTS PASSED ----{ +if nargin<2 % Function and/or starting point are not specified + exitflag=-1; + disp(errmes); + disp(error1); + return +end +if nargin<3 + app=1; % No user-supplied gradients +elseif isempty(grad) + app=1; +else + app=0; % Exact gradients are supplied +end + +% OPTIONS ----{ +doptions.minimizer_indicator=1; +doptions.TolX=1e-6; %accuracy of argument +doptions.TolFun=1e-6; %accuracy of function (see Solvopt p.29) +doptions.MaxIter=15000; +doptions.verbosity=1; +doptions.TolXConstraint=1.e-8; +doptions.SpaceDilation=2.5; +doptions.LBGradientStep=1.e-11; + +if nargin<4 + optim=doptions; +elseif isempty(optim) + optim=doptions; +end +% Check the values: +optim.TolX=max(optim.TolX,1.e-12); +optim.TolFun=max(optim.TolFun,1.e-12); +optim.TolX=max(optim.LBGradientStep*1.e2,optim.TolX); +optim.TolX=min(optim.TolX,1); +optim.TolFun=min(optim.TolFun,1); +optim.TolXConstraint=max(optim.TolXConstraint,1e-12); +optim.SpaceDilation=max([optim.SpaceDilation,1.5]); +optim.LBGradientStep=max(optim.LBGradientStep,1e-11); +% ----} + +if isempty(func) + constr=0; +else + constr=1; % Constrained problem + if isempty(gradc), + appconstr=1; + else + appconstr=0; % Exact gradients of constraints are supplied + end +end +% ----} + +% STARTING POINT ----{ +if max(size(x))<=1 + disp(errmes); + disp(error2); + exitflag=-2; + return +elseif size(x,2)==1 + n=size(x,1); + x=x'; + trx=1; +elseif size(x,1)==1 + n=size(x,2); + trx=0; +else + disp(errmes); + disp(error2); + exitflag=-2; + return +end +% ----} + +% WORKING CONSTANTS AND COUNTERS ----{ + +n_f_evals=0; n_grad_evals=0; % function and gradient calculations +if constr + n_constraint_evals=0; + n_constraint_gradient_evals=0; % same for constraints +end +epsnorm=1.e-15; +epsnorm2=1.e-30; % epsilon & epsilon^2 + +if constr, h1=-1; % NLP: restricted to minimization + cnteps=optim.TolXConstraint; % Max. admissible residual +else + h1=sign(optim.minimizer_indicator); % Minimize resp. maximize a function +end + +k=0; % Iteration counter + +wdef=1/optim.SpaceDilation-1; % Default space transf. coeff. + +%Gamma control ---{ +ajb=1+.1/n^2; % Base I +ajp=20; +ajpp=ajp; % Start value for the power +ajs=1.15; % Base II +knorms=0; gnorms=zeros(1,10); % Gradient norms stored +%---} + +%Display control ---{ +if optim.verbosity<=0, dispdata=0; + if optim.verbosity==-1 + dispwarn=0; + else + dispwarn=1; + end +else + dispdata=round(optim.verbosity); + dispwarn=1; +end +ld=dispdata; +%---} + +%Stepsize control ---{ +dq=5.1; % Step divider (at f_{i+1}>gamma*f_{i}) +du20=2;du10=1.5;du03=1.05; % Step multipliers (at certain steps made) +kstore=3;nsteps=zeros(1,kstore); % Steps made at the last 'kstore' iterations +if app + des=6.3; % Desired number of steps per 1-D search +else + des=3.3; +end +mxtc=3; % Number of trial cycles (steep wall detect) +%---} +termx=0; limxterm=50; % Counter and limit for x-criterion + +ddx =max(1e-11,optim.LBGradientStep); % stepsize for gradient approximation + +low_bound=-1+1e-4; % Lower bound cosine used to detect a ravine + +ZeroGrad=n*1.e-16; % Lower bound for a gradient norm + +nzero=0; % Zero-gradient events counter +% Lower bound for values of variables taking into account +lowxbound=max([optim.TolX,1e-3]); +% Lower bound for function values to be considered as making difference +lowfbound=optim.TolFun^2; +krerun=0; % Re-run events counter +detfr=optim.TolFun*100; % relative error for f/f_{record} +detxr=optim.TolX*10; % relative error for norm(x)/norm(x_{record}) + +warnno=0; % the number of warn.mess. to end with + +kflat=0; % counter for points of flatness +stepvanish=0; % counter for vanished steps +stopf=0; +% ----} End of setting constants +% ----} End of the preamble + +% COMPUTE THE FUNCTION ( FIRST TIME ) ----{ +if trx + f=feval(fun,x',varargin{:}); +else + f=feval(fun,x,varargin{:}); +end +n_f_evals=n_f_evals+1; +if isempty(f), if dispwarn,disp(errmes);disp(error30);end + exitflag=-3; if trx, x=x';end, return +elseif isnan(f), if dispwarn,disp(errmes);disp(error31);disp(error6);end + exitflag=-3; if trx, x=x';end, return +elseif abs(f)==Inf, if dispwarn,disp(errmes);disp(error32);disp(error6);end + exitflag=-3; if trx, x=x';end, return +end +xrec=x; frec=f; % record point and function value +% Constrained problem +if constr, fp=f; kless=0; + if trx, + fc=feval(func,x'); + else + fc=feval(func,x); + end + if isempty(fc), + if dispwarn,disp(errmes);disp(error50);end + exitflag=-5; if trx, x=x';end, return + elseif isnan(fc), + if dispwarn,disp(errmes);disp(error51);disp(error6);end + exitflag=-5; if trx, x=x';end, return + elseif abs(fc)==Inf, + if dispwarn,disp(errmes);disp(error52);disp(error6);end + exitflag=-5; if trx, x=x';end, return + end + n_constraint_evals=n_constraint_evals+1; + PenCoef=1; % first rough approximation + if fc<=cnteps + FP=1; fc=0; % feasible point + else + FP=0; % infeasible point + end + f=f+PenCoef*fc; +end +% ----} +% COMPUTE THE GRADIENT ( FIRST TIME ) ----{ +if app + deltax=h1*ddx*ones(size(x)); + if constr + if trx + g=apprgrdn(x',fp,fun,deltax',1,varargin{:}); + else + g=apprgrdn(x ,fp,fun,deltax,1,varargin{:}); + end + else + if trx + g=apprgrdn(x',f,fun,deltax',1,varargin{:}); + else + g=apprgrdn(x ,f,fun,deltax,1,varargin{:}); + end + end + n_f_evals=n_f_evals+n; +else + if trx + g=feval(grad,x',varargin{:}); + else + g=feval(grad,x,varargin{:}); + end + n_grad_evals=n_grad_evals+1; +end +if size(g,2)==1, g=g'; end, ng=norm(g); +if size(g,2)~=n, if dispwarn,disp(errmes);disp(error40);end + exitflag=-4; if trx, x=x';end, return +elseif isnan(ng), if dispwarn,disp(errmes);disp(error41);disp(error6);end + exitflag=-4; if trx, x=x';end, return +elseif ng==Inf, if dispwarn,disp(errmes);disp(error42);disp(error6);end + exitflag=-4; if trx, x=x';end, return +elseif ng2*kd, kd=kd+1; warnno=1; + if any(abs(x-xx)epsnorm*norm(gt)) + z=z/nrmz; + g1=gt+w*(z*gt')*z; B=B+w*(B*z')*z; + else + z=zeros(1,n); + nrmz=0; + g1=gt; + end + d1=norm(g1); g0=(g1/d1)*B'; + % ----} + % RESETTING ----{ + if kcheck>1 + idx=find(abs(g)>ZeroGrad); numelem=size(idx,2); + if numelem>0, grbnd=epsnorm*numelem^2; + if all(abs(g1(idx))<=abs(g(idx))*grbnd) | nrmz==0 + if dispwarn, disp(wrnmes); disp(warn20); end + if abs(fst-f)1.2*PenCoef, + PenCoef=PenCoefNew; Reset=1; kless=0; f=f+PenCoef*fc; break + end + end + end + end + f=f+PenCoef*fc; + end + if abs(f)==Inf || isnan(f) + if dispwarn, disp(wrnmes); + if isnan(f) + disp(error31); + else + disp(error32); + end + end + if ksm || kc>=mxtc + exitflag=-3; + if trx + x=x'; + end + return + else + k2=k2+1; + k1=0; + hp=hp/dq; + x=x1; + f=f1; + knan=1; + if constr + FP=FP1; + fp=fp1; + end + end + % STEP SIZE IS ZERO TO THE EXTENT OF EPSNORM + elseif all(abs(x-x1)=5, + exitflag=-14; + if dispwarn, disp(termwarn1); + disp(endwarn(4,:)); end + if trx,x=x';end, return + else + x=x1; + f=f1; + hp=hp*10; + ksm=1; + if constr + FP=FP1; + fp=fp1; + end + end + % USE SMALLER STEP + elseif h1*f=mxtc, break, end + % 1-D OPTIMIZER IS LEFT BEHIND + else if h1*f<=h1*f1, break, end + % USE LARGER STEP + k1=k1+1; if k2>0, kc=kc+1; end, k2=0; + if k1>=20, hp=du20*hp; + elseif k1>=10, hp=du10*hp; + elseif k1>=3, hp=du03*hp; + end + end + end + % ----} End of 1-D search + % ADJUST THE TRIAL STEP SIZE ----{ + dx=norm(xopt-x); + if kg=2, nsteps(2:kg)=nsteps(1:kg-1); end + nsteps(1)=dx/(abs(h)*norm(g0)); + kk=sum(nsteps(1:kg).*[kg:-1:1])/sum([kg:-1:1]); + if kk>des + if kg==1 + h=h*(kk-des+1); + else + h=h*sqrt(kk-des+1); + end + elseif kk=20, PenCoef=PenCoef/10; Reset=1; kless=0; end + else + kless=0; + end + if appconstr, + deltax=sign(x); idx=find(deltax==0); + deltax(idx)=ones(size(idx)); deltax=ddx*deltax; + if trx + gc=apprgrdn(x',fc,func,deltax',0); + else + gc=apprgrdn(x ,fc,func,deltax ,0); + end + n_constraint_evals=n_constraint_evals+n; + else + if trx + gc=feval(gradc,x'); + else + gc=feval(gradc,x ); + end + n_constraint_gradient_evals=n_constraint_gradient_evals+1; + end + if size(gc,2)==1, gc=gc'; end, ngc=norm(gc); + if isnan(ngc), + if dispwarn,disp(errmes);disp(error61);end + exitflag=-6; if trx, x=x';end, return + elseif ngc==Inf, + if dispwarn,disp(errmes);disp(error62);end + exitflag=-6; if trx, x=x';end, return + elseif ngch1*frec, frec=f; xrec=x; grec=g; end + % ----} + if ng>ZeroGrad, + if knorms<10, knorms=knorms+1; end + if knorms>=2, gnorms(2:knorms)=gnorms(1:knorms-1); end + gnorms(1)=ng; + nng=(prod(gnorms(1:knorms)))^(1/knorms); + end + + % DISPLAY THE CURRENT VALUES ----{ + if k==ld + disp('Iter.# ..... Function ... Step Value ... Gradient Norm '); + disp(sprintf('%5i %13.5e %13.5e %13.5e',k,f,dx,ng)); + ld=k+dispdata; + end + %----} + % CHECK THE STOPPING CRITERIA ----{ + termflag=1; + if constr, if ~FP, termflag=0; end, end + if kcheck<=5, termflag=0; end + if knan, termflag=0; end + if kc>=mxtc, termflag=0; end + % ARGUMENT + if termflag + idx=find(abs(x)>=lowxbound); + if isempty(idx) || all(abs(xopt(idx)-x(idx))<=optim.TolX*abs(x(idx))) + termx=termx+1; + % FUNCTION + if abs(f-frec)> detfr * abs(f) && ... + abs(f-fopt)<=optim.TolFun*abs(f) && ... + krerun<=3 && ... + ~constr + if any(abs(xrec(idx)-x(idx))> detxr * abs(x(idx))) + if dispwarn + disp(wrnmes); + disp(warn09); + end + x=xrec; + f=frec; + g=grec; + ng=norm(g); + krerun=krerun+1; + h=h1*max([dx,detxr*norm(x)])/krerun; + warnno=2; + break + else + h=h*10; + end + elseif abs(f-frec)> optim.TolFun*abs(f) && ... + norm(x-xrec)=limxterm ) + if stopf + if dx<=laststep + if warnno==1 && ng=limxterm + exitflag=-14; + if dispwarn, disp(termwarn1); disp(endwarn(4,:)); + if app, disp(appwarn); end + end + x=xrec; f=frec; + if trx,x=x';end, return + else + stopf=0; + end + end + end + % ITERATIONS LIMIT + if(k==optim.MaxIter) + exitflag=-9; + if trx + x=x'; + end, + if dispwarn, disp(wrnmes); disp(warn4); end + return + end + % ----} + % ZERO GRADIENT ----{ + if constr + if ng<=ZeroGrad, + if dispwarn, disp(termwarn1); disp(warn1); end + exitflag=-8; + if trx + x=x'; + end + return + end + else + if ng<=ZeroGrad, nzero=nzero+1; + if dispwarn, disp(wrnmes); disp(warn1); end + if nzero>=3 + exitflag=-8; + if trx + x=x'; + end + return + end + g0=-h*g0/2; + for i=1:10, + x=x+g0; + if trx + f=feval(fun,x',varargin{:}); + else + f=feval(fun,x,varargin{:}); + end + n_f_evals=n_f_evals+1; + if abs(f)==Inf + if dispwarn + disp(errmes); + disp(error32); + end + exitflag=-3; + if trx + x=x'; + end + return + elseif isnan(f), + if dispwarn + disp(errmes); + disp(error32); + end + exitflag=-3; + if trx + x=x'; + end + return + end + if app, + deltax=sign(g0); + idx=find(deltax==0); + deltax(idx)=ones(size(idx)); + deltax=h1*ddx*deltax; + if trx + g=apprgrdn(x',f,fun,deltax',1,varargin{:}); + else + g=apprgrdn(x,f,fun,deltax,1,varargin{:}); + end + n_f_evals=n_f_evals+n; + else + if trx + g=feval(grad,x',varargin{:}); + else + g=feval(grad,x,varargin{:}); + end + n_grad_evals=n_grad_evals+1; + end + if size(g,2)==1 + g=g'; + end + ng=norm(g); + if ng==Inf + if dispwarn + disp(errmes); + disp(error42); + end + exitflag=-4; + if trx + x=x'; + end + return + elseif isnan(ng) + if dispwarn + disp(errmes); + disp(error41); + end + exitflag=-4; + if trx + x=x'; + end + return + end + if ng>ZeroGrad + break + end + end + if ng<=ZeroGrad, + if dispwarn + disp(termwarn1); + disp(warn1); + end + exitflag=-8; + if trx + x=x'; + end + return + end + h=h1*dx; + break + end + end + % ----} + % FUNCTION IS FLAT AT THE POINT ----{ + if ~constr && abs(f-fopt)5 && ng<1 + idx=find(abs(g)<=epsnorm2); + ni=size(idx,2); + if ni>=1 && ni<=n/2 && kflat<=3, kflat=kflat+1; + if dispwarn, disp(wrnmes); disp(warn31); end, warnno=1; + x1=x; fm=f; + for j=idx, y=x(j); f2=fm; + if y==0, x1(j)=1; elseif abs(y)<1, x1(j)=sign(y); else, x1(j)=y; end + for i=1:20, x1(j)=x1(j)/1.15; + if trx + f1=feval(fun,x1',varargin{:}); + else + f1=feval(fun,x1,varargin{:}); + end + n_f_evals=n_f_evals+1; + if abs(f1)~=Inf && ~isnan(f1), + if h1*f1>h1*fm + y=x1(j); + fm=f1; + elseif h1*f2>h1*f1 + break + elseif f2==f1 + x1(j)=x1(j)/1.5; + end + f2=f1; + end + end + x1(j)=y; + end + if h1*fm>h1*f + if app, + deltax=h1*ddx*ones(size(deltax)); + if trx + gt=apprgrdn(x1',fm,fun,deltax',1,varargin{:}); + else + gt=apprgrdn(x1 ,fm,fun,deltax ,1,varargin{:}); + end + n_f_evals=n_f_evals+n; + else + if trx + gt=feval(grad,x1',varargin{:}); + else + gt=feval(grad,x1,varargin{:}); + end + n_grad_evals=n_grad_evals+1; + end + if size(gt,2)==1 + gt=gt'; + end + ngt=norm(gt); + if ~isnan(ngt) && ngt>epsnorm2, + if dispwarn + disp(warn32); + end + optim.TolFun=optim.TolFun/5; + x=x1; + g=gt; + ng=ngt; + f=fm; + h=h1*dx/3; + break + end + end + end + end + % ----} + end % iterations +end % restart +% end of the function +% +end \ No newline at end of file diff --git a/matlab/optimize_prior.m b/matlab/optimize_prior.m index a3595d0f6..d5b5e0ac1 100644 --- a/matlab/optimize_prior.m +++ b/matlab/optimize_prior.m @@ -51,7 +51,7 @@ objective_function_penalty_base = minus_logged_prior_density(xinit, BayesInfo.ps BayesInfo.p4,DynareOptions,ModelInfo,EstimationInfo,DynareResults); % Maximization of the prior density -[xparams, lpd, hessian] = ... +[xparams, lpd, hessian_mat] = ... maximize_prior_density(xinit, BayesInfo.pshape, ... BayesInfo.p6, ... BayesInfo.p7, ... diff --git a/matlab/parallel/masterParallel.m b/matlab/parallel/masterParallel.m index 6b218310e..75728bb0f 100644 --- a/matlab/parallel/masterParallel.m +++ b/matlab/parallel/masterParallel.m @@ -3,28 +3,38 @@ function [fOutVar,nBlockPerCPU, totCPU] = masterParallel(Parallel,fBlock,nBlock, % This is the most important function for the management of DYNARE parallel % computing. % It is the top-level function called on the master computer when parallelizing a task. - -% This function has two main computational strategies for managing the matlab worker (slave process). +% +% This function has two main computational strategies for managing the +% matlab worker (slave process): +% % 0 Simple Close/Open Stategy: -% In this case the new Matlab instances (slave process) are open when -% necessary and then closed. This can happen many times during the -% simulation of a model. - +% In this case the new Matlab instances (slave process) are open when +% necessary and then closed. This can happen many times during the +% simulation of a model. +% % 1 Always Open Strategy: -% In this case we have a more sophisticated management of slave processes, -% which are no longer closed at the end of each job. The slave processes -% wait for a new job (if it exists). If a slave does not receive a new job after a -% fixed time it is destroyed. This solution removes the computational -% time necessary to Open/Close new Matlab instances. - +% In this case we have a more sophisticated management of slave processes, +% which are no longer closed at the end of each job. The slave processes +% wait for a new job (if it exists). If a slave does not receive a new job after a +% fixed time it is destroyed. This solution removes the computational +% time necessary to Open/Close new Matlab instances. +% % The first (point 0) is the default Strategy % i.e.(Parallel_info.leaveSlaveOpen=0). This value can be changed by the % user in xxx.mod file or it is changed by the programmer if it is necessary to % reduce the overall computational time. See for example the % prior_posterior_statistics.m. - +% % The number of parallelized threads will be equal to (nBlock-fBlock+1). % +% Treatment of global variables: +% Global variables used within the called function (e.g. +% objective_function_penalty_base) are wrapped and passed by storing their +% values at the start of the parallel computation in a file via +% storeGlobalVars.m. This file is then loaded in the separate, +% independent slave Matlab sessions. By keeping them separate, no +% interaction via global variables can take place. +% % INPUTS % o Parallel [struct vector] copy of options_.parallel % o fBlock [int] index number of the first thread @@ -53,7 +63,7 @@ function [fOutVar,nBlockPerCPU, totCPU] = masterParallel(Parallel,fBlock,nBlock, % the number of CPUs declared in "Parallel", if % the number of required threads is lower) -% Copyright (C) 2009-2013 Dynare Team +% Copyright (C) 2009-2015 Dynare Team % % This file is part of Dynare. % @@ -126,7 +136,7 @@ if isHybridMatlabOctave || isoctave end end - if exist('fGlobalVar') && ~isempty(fGlobalVar), + if exist('fGlobalVar','var') && ~isempty(fGlobalVar), fInputNames = fieldnames(fGlobalVar); for j=1:length(fInputNames), TargetVar = fGlobalVar.(fInputNames{j}); @@ -161,7 +171,7 @@ switch Strategy save([fname,'_input.mat'],'fInputVar','Parallel','-append') case 1 - if exist('fGlobalVar'), + if exist('fGlobalVar','var'), save(['temp_input.mat'],'fInputVar','fGlobalVar') else save(['temp_input.mat'],'fInputVar') @@ -540,7 +550,6 @@ else 'Renderer','Painters', ... 'Resize','off'); - vspace = 0.1; ncol = ceil(totCPU/10); hspace = 0.9/ncol; hstatus(1) = axes('position',[0.05/ncol 0.92 0.9/ncol 0.03], ... @@ -882,8 +891,4 @@ switch Strategy end end end -end - - - - +end \ No newline at end of file diff --git a/matlab/perfect-foresight-models/perfect_foresight_setup.m b/matlab/perfect-foresight-models/perfect_foresight_setup.m index da03d46a6..081eaf887 100644 --- a/matlab/perfect-foresight-models/perfect_foresight_setup.m +++ b/matlab/perfect-foresight-models/perfect_foresight_setup.m @@ -34,8 +34,16 @@ global M_ options_ oo_ test_for_deep_parameters_calibration(M_); if size(M_.lead_lag_incidence,2)-nnz(M_.lead_lag_incidence(M_.maximum_endo_lag+1,:)) > 0 - mess = ['PERFECT_FORESIGHT_SETUP: error in model specification : variable ' M_.endo_names(find(M_.lead_lag_incidence(M_.maximum_lag+1,:)==0),:)]; - mess = [mess ' doesn''t appear as current variable.']; + mess = ['PERFECT_FORESIGHT_SETUP: error in model specification : the variable(s) ']; + var_list=M_.endo_names(find(M_.lead_lag_incidence(M_.maximum_lag+1,:)==0),:); + for i=1:size(var_list,1) + if i 0) && ... (isempty(DynareResults.exo_simul) || any(size(DynareResults.exo_simul) ~= [ DynareModel.maximum_lag+DynareOptions.periods+DynareModel.maximum_lead, DynareModel.exo_nbr ])) - if options_.initval_file - disp(sprintf('PERFECT_FORESIGHT_SOLVER: ''oo_.exo_simul'' has wrong size. Check whether your initval-file provides %d periods.',M_.maximum_endo_lag+options_.periods+M_.maximum_endo_lead)) + if DynareOptions.initval_file + fprintf('PERFECT_FORESIGHT_SOLVER: ''oo_.exo_simul'' has wrong size. Check whether your initval-file provides %d periods.',DynareModel.maximum_endo_lag+DynareOptions.periods+DynareModel.maximum_endo_lead) error('perfect_foresight_solver:ArgCheck','PERFECT_FORESIGHT_SOLVER: ''oo_.exo_simul'' has wrong size.') else error('perfect_foresight_solver:ArgCheck','PERFECT_FORESIGHT_SOLVER: ''oo_.exo_simul'' has wrong size. Did you run ''perfect_foresight_setup'' ?') end - error('perfect_foresight_solver:ArgCheck','PERFECT_FORESIGHT_SOLVER: ''oo_.exo_simul'' has wrong size. Did you run ''perfect_foresight_setup'' ?') end diff --git a/matlab/perfect-foresight-models/private/simulation_core.m b/matlab/perfect-foresight-models/private/simulation_core.m index 6e86671df..ecf5c8964 100644 --- a/matlab/perfect-foresight-models/private/simulation_core.m +++ b/matlab/perfect-foresight-models/private/simulation_core.m @@ -75,9 +75,9 @@ else yT = y(:,periods+2); z = y(:,2:periods+1); illi = M_.lead_lag_incidence'; - [i_cols,~,i_cols_j] = find(illi(:)); + [i_cols,junk,i_cols_j] = find(illi(:)); illi = illi(:,2:3); - [i_cols_J1,~,i_cols_1] = find(illi(:)); + [i_cols_J1,junk,i_cols_1] = find(illi(:)); i_cols_T = nonzeros(M_.lead_lag_incidence(1:2,:)'); [y,info] = dynare_solve(@perfect_foresight_problem,z(:),1, ... str2func([M_.fname '_dynamic']),y0,yT, ... @@ -109,9 +109,9 @@ if nargout>1 yy = oo_.endo_simul(:,2:options_.periods+1); if ~exist('illi') illi = M_.lead_lag_incidence'; - [i_cols,~,i_cols_j] = find(illi(:)); + [i_cols,junk,i_cols_j] = find(illi(:)); illi = illi(:,2:3); - [i_cols_J1,~,i_cols_1] = find(illi(:)); + [i_cols_J1,junk,i_cols_1] = find(illi(:)); i_cols_T = nonzeros(M_.lead_lag_incidence(1:2,:)'); end if options_.block && ~options_.bytecode diff --git a/matlab/perfect-foresight-models/sim1.m b/matlab/perfect-foresight-models/sim1.m index 481cffb4e..4e00befbe 100644 --- a/matlab/perfect-foresight-models/sim1.m +++ b/matlab/perfect-foresight-models/sim1.m @@ -69,7 +69,7 @@ i_cols_A1 = find(lead_lag_incidence(2:3,:)'); i_cols_T = nonzeros(lead_lag_incidence(1:2,:)'); i_cols_0 = nonzeros(lead_lag_incidence(2,:)'); i_cols_A0 = find(lead_lag_incidence(2,:)'); -i_cols_j = 1:nd; +i_cols_j = (1:nd)'; i_upd = maximum_lag*ny+(1:periods*ny); Y = endo_simul(:); @@ -86,7 +86,6 @@ z = Y(find(lead_lag_incidence')); [d1,jacobian] = model_dynamic(z,oo_.exo_simul, params, ... steady_state,maximum_lag+1); -A = sparse([],[],[],periods*ny,periods*ny,periods*nnz(jacobian)); res = zeros(periods*ny,1); o_periods = periods; @@ -94,26 +93,32 @@ o_periods = periods; ZERO = zeros(length(i_upd),1); h1 = clock ; +iA = zeros(periods*M_.NNZDerivatives(1),3); for iter = 1:options_.simul.maxit h2 = clock ; - i_rows = 1:ny; + i_rows = (1:ny)'; i_cols_A = find(lead_lag_incidence'); i_cols = i_cols_A+(maximum_lag-1)*ny; - + m = 0; for it = (maximum_lag+1):(maximum_lag+periods) - - [d1,jacobian] = model_dynamic(Y(i_cols), exo_simul, params, steady_state,it); + [d1,jacobian] = model_dynamic(Y(i_cols), exo_simul, params, ... + steady_state,it); if it == maximum_lag+periods && it == maximum_lag+1 - A(i_rows,i_cols_A0) = jacobian(:,i_cols_0); + [r,c,v] = find(jacobian(:,i_cols_0)); + iA((1:length(v))+m,:) = [i_rows(r),i_cols_A0(c),v]; elseif it == maximum_lag+periods - A(i_rows,i_cols_A(i_cols_T)) = jacobian(:,i_cols_T); + [r,c,v] = find(jacobian(:,i_cols_T)); + iA((1:length(v))+m,:) = [i_rows(r),i_cols_A(i_cols_T(c)),v]; elseif it == maximum_lag+1 - A(i_rows,i_cols_A1) = jacobian(:,i_cols_1); + [r,c,v] = find(jacobian(:,i_cols_1)); + iA((1:length(v))+m,:) = [i_rows(r),i_cols_A1(c),v]; else - A(i_rows,i_cols_A) = jacobian(:,i_cols_j); + [r,c,v] = find(jacobian(:,i_cols_j)); + iA((1:length(v))+m,:) = [i_rows(r),i_cols_A(c),v]; end - + m = m + length(v); + res(i_rows) = d1; if endogenous_terminal_period && iter>1 @@ -157,6 +162,9 @@ for iter = 1:options_.simul.maxit break end + iA = iA(1:m,:); + A = sparse(iA(:,1),iA(:,2),iA(:,3),periods*ny,periods*ny); + if endogenous_terminal_period && iter>1 dy = ZERO; dy(1:i_rows(end)) = -A(1:i_rows(end),1:i_rows(end))\res(1:i_rows(end)); diff --git a/matlab/plot_identification.m b/matlab/plot_identification.m index 4f9fcf98a..549224ef0 100644 --- a/matlab/plot_identification.m +++ b/matlab/plot_identification.m @@ -247,13 +247,30 @@ else hist(log10(idelre.cond)) title('log10 of Condition number in the LRE model') dyn_saveas(hh,[IdentifDirectoryName '/' M_.fname '_ident_COND' ],options_); + options_mcf.pvalue_ks = 0.1; + options_mcf.pvalue_corr = 0.001; + options_mcf.alpha2 = 0; + options_mcf.param_names = name; + options_mcf.fname_ = M_.fname; + options_mcf.OutputDirectoryName = IdentifDirectoryName; + options_mcf.beha_title = 'LOW condition nbr'; + options_mcf.nobeha_title = 'HIGH condition nbr'; + options_mcf.amcf_name = 'MC_HighestCondNumberLRE'; + options_mcf.amcf_title = 'MC Highest Condition Number LRE Model'; + options_mcf.title = 'MC Highest Condition Number LRE Model'; ncut=floor(SampleSize/10*9); [dum,is]=sort(idelre.cond); - [proba, dproba] = stab_map_1(params, is(1:ncut), is(ncut+1:end), 'MC_HighestCondNumberLRE', 1, [], IdentifDirectoryName, 0.1,'MC Highest Condition Number LRE Model'); + mcf_analysis(params, is(1:ncut), is(ncut+1:end), options_mcf, options_); + options_mcf.amcf_name = 'MC_HighestCondNumberModel'; + options_mcf.amcf_title = 'MC Highest Condition Number Model Solution'; + options_mcf.title = 'MC Highest Condition Number Model Solution'; [dum,is]=sort(idemodel.cond); - [proba, dproba] = stab_map_1(params, is(1:ncut), is(ncut+1:end), 'MC_HighestCondNumberModel', 1, [], IdentifDirectoryName, 0.1,'MC Highest Condition Number Model Solution'); + mcf_analysis(params, is(1:ncut), is(ncut+1:end), options_mcf, options_); + options_mcf.amcf_name = 'MC_HighestCondNumberMoments'; + options_mcf.amcf_title = 'MC Highest Condition Number Model Moments'; + options_mcf.title = 'MC Highest Condition Number Model Moments'; [dum,is]=sort(idemoments.cond); - [proba, dproba] = stab_map_1(params, is(1:ncut), is(ncut+1:end), 'MC_HighestCondNumberMoments', 1, [], IdentifDirectoryName, 0.1,'MC Highest Condition Number Model Moments'); + mcf_analysis(params, is(1:ncut), is(ncut+1:end), options_mcf, options_); % [proba, dproba] = stab_map_1(idemoments.Mco', is(1:ncut), is(ncut+1:end), 'HighestCondNumberMoments_vs_Mco', 1, [], IdentifDirectoryName); % for j=1:nparam, % % ibeh=find(idemoments.Mco(j,:)<0.9); diff --git a/matlab/prior_posterior_statistics.m b/matlab/prior_posterior_statistics.m index 4908d6b64..a2f43343e 100644 --- a/matlab/prior_posterior_statistics.m +++ b/matlab/prior_posterior_statistics.m @@ -14,11 +14,11 @@ function prior_posterior_statistics(type,dataset,dataset_info) % % SPECIAL REQUIREMENTS % none - +% % PARALLEL CONTEXT -% See the comments random_walk_metropolis_hastings.m funtion. - - +% See the comments in the random_walk_metropolis_hastings.m funtion. +% +% % Copyright (C) 2005-2013 Dynare Team % % This file is part of Dynare. diff --git a/matlab/prior_posterior_statistics_core.m b/matlab/prior_posterior_statistics_core.m index ef8328c35..26b793c08 100644 --- a/matlab/prior_posterior_statistics_core.m +++ b/matlab/prior_posterior_statistics_core.m @@ -273,6 +273,8 @@ for b=fpar:B if irun(5) > MAX_nruns || b == B stock = stock_param(1:irun(5)-1,:); + stock_logpo = stock_logpo(1:irun(5)-1); + stock_ys = stock_ys(1:irun(5)-1,:); ifil(5) = ifil(5) + 1; save([DirectoryName '/' M_.fname '_param' int2str(ifil(5)) '.mat'],'stock','stock_logpo','stock_ys'); if RemoteFlag==1, diff --git a/matlab/random_walk_metropolis_hastings.m b/matlab/random_walk_metropolis_hastings.m index c2a49e7a2..2092922ac 100644 --- a/matlab/random_walk_metropolis_hastings.m +++ b/matlab/random_walk_metropolis_hastings.m @@ -1,14 +1,17 @@ function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) -%function record=random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,options_,M_,estim_params_,bayestopt_,oo_) -% Random walk Metropolis-Hastings algorithm. +% function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bounds,dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,oo_) +% Random Walk Metropolis-Hastings algorithm. % % INPUTS % o TargetFun [char] string specifying the name of the objective % function (posterior kernel). +% o ProposalFun [char] string specifying the name of the proposal +% density % o xparam1 [double] (p*1) vector of parameters to be estimated (initial values). % o vv [double] (p*p) matrix, posterior covariance matrix (at the mode). % o mh_bounds [double] (p*2) matrix defining lower and upper bounds for the parameters. % o dataset_ data structure +% o dataset_info dataset info structure % o options_ options structure % o M_ model structure % o estim_params_ estimated parameters structure @@ -16,27 +19,27 @@ function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bou % o oo_ outputs structure % % ALGORITHM -% Metropolis-Hastings. +% Random-Walk Metropolis-Hastings. % % SPECIAL REQUIREMENTS % None. % % PARALLEL CONTEXT % The most computationally intensive part of this function may be executed -% in parallel. The code sutable to be executed in -% parallel on multi core or cluster machine (in general a 'for' cycle), -% is removed from this function and placed in random_walk_metropolis_hastings_core.m funtion. -% Then the DYNARE parallel package contain a set of pairs matlab functions that can be executed in -% parallel and called name_function.m and name_function_core.m. -% In addition in parallel package we have second set of functions used -% to manage the parallel computation. +% in parallel. The code suitable to be executed in +% parallel on multi core or cluster machine (in general a 'for' cycle) +% has been removed from this function and been placed in the random_walk_metropolis_hastings_core.m funtion. +% +% The DYNARE parallel packages comprise a i) set of pairs of Matlab functions that can be executed in +% parallel and called name_function.m and name_function_core.m and ii) a second set of functions used +% to manage the parallel computations. % -% This function was the first function to be parallelized, later other +% This function was the first function to be parallelized. Later, other % functions have been parallelized using the same methodology. % Then the comments write here can be used for all the other pairs of -% parallel functions and also for management funtions. +% parallel functions and also for management functions. -% Copyright (C) 2006-2013 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -54,7 +57,7 @@ function random_walk_metropolis_hastings(TargetFun,ProposalFun,xparam1,vv,mh_bou % along with Dynare. If not, see . -% In Metropolis, we set penalty to Inf to as to reject all parameter sets triggering error in target density computation +% In Metropolis, we set penalty to Inf so as to reject all parameter sets triggering an error during target density computation global objective_function_penalty_base objective_function_penalty_base = Inf; @@ -73,16 +76,16 @@ load_last_mh_history_file(MetropolisFolder, ModelName); % First run in serial mode, and then comment the follow line. % save('recordSerial.mat','-struct', 'record'); -% For parllel runs after serial runs with the abobe line active. +% For parallel runs after serial runs with the abobe line active. % TempRecord=load('recordSerial.mat'); % record.Seeds=TempRecord.Seeds; % Snapshot of the current state of computing. It necessary for the parallel -% execution (i.e. to execute in a corretct way portion of code remotely or -% on many core). The mandatory variables for local/remote parallel -% computing are stored in localVars struct. +% execution (i.e. to execute in a corretct way a portion of code remotely or +% on many cores). The mandatory variables for local/remote parallel +% computing are stored in the localVars struct. localVars = struct('TargetFun', TargetFun, ... 'ProposalFun', ProposalFun, ... @@ -110,9 +113,8 @@ localVars = struct('TargetFun', TargetFun, ... 'varargin',[]); -% The user don't want to use parallel computing, or want to compute a -% single chain. In this cases Random walk Metropolis-Hastings algorithm is -% computed sequentially. +% User doesn't want to use parallel computing, or wants to compute a +% single chain compute Random walk Metropolis-Hastings algorithm sequentially. if isnumeric(options_.parallel) || (nblck-fblck)==0, fout = random_walk_metropolis_hastings_core(localVars, fblck, nblck, 0); @@ -152,6 +154,7 @@ NewFile = fout(1).NewFile; update_last_mh_history_file(MetropolisFolder, ModelName, record); +% Provide diagnostic output skipline() disp(['Estimation::mcmc: Number of mh files: ' int2str(NewFile(1)) ' per block.']) disp(['Estimation::mcmc: Total number of generated files: ' int2str(NewFile(1)*nblck) '.']) diff --git a/matlab/random_walk_metropolis_hastings_core.m b/matlab/random_walk_metropolis_hastings_core.m index 90c89e871..2c26de0e5 100644 --- a/matlab/random_walk_metropolis_hastings_core.m +++ b/matlab/random_walk_metropolis_hastings_core.m @@ -1,25 +1,25 @@ function myoutput = random_walk_metropolis_hastings_core(myinputs,fblck,nblck,whoiam, ThisMatlab) -% PARALLEL CONTEXT -% This function contain the most computationally intensive portion of code in -% random_walk_metropolis_hastings (the 'for xxx = fblck:nblck' loop). The branches in 'for' -% cycle and are completely independent than suitable to be executed in parallel way. +% function myoutput = random_walk_metropolis_hastings_core(myinputs,fblck,nblck,whoiam, ThisMatlab) +% Contains the most computationally intensive portion of code in +% random_walk_metropolis_hastings (the 'for xxx = fblck:nblck' loop). The branches in that 'for' +% cycle are completely independent to be suitable for parallel execution. % % INPUTS % o myimput [struc] The mandatory variables for local/remote % parallel computing obtained from random_walk_metropolis_hastings.m % function. % o fblck and nblck [integer] The Metropolis-Hastings chains. -% o whoiam [integer] In concurrent programming a modality to refer to the differents thread running in parallel is needed. +% o whoiam [integer] In concurrent programming a modality to refer to the different threads running in parallel is needed. % The integer whoaim is the integer that % allows us to distinguish between them. Then it is the index number of this CPU among all CPUs in the % cluster. % o ThisMatlab [integer] Allows us to distinguish between the -% 'main' matlab, the slave matlab worker, local matlab, remote matlab, +% 'main' Matlab, the slave Matlab worker, local Matlab, remote Matlab, % ... Then it is the index number of this slave machine in the cluster. % OUTPUTS % o myoutput [struc] -% If executed without parallel is the original output of 'for b = -% fblck:nblck' otherwise a portion of it computed on a specific core or +% If executed without parallel, this is the original output of 'for b = +% fblck:nblck'. Otherwise, it's a portion of it computed on a specific core or % remote machine. In this case: % record; % irun; @@ -31,23 +31,12 @@ function myoutput = random_walk_metropolis_hastings_core(myinputs,fblck,nblck,wh % % SPECIAL REQUIREMENTS. % None. - +% % PARALLEL CONTEXT -% The most computationally intensive part of this function may be executed -% in parallel. The code sutable to be executed in parallel on multi core or cluster machine, -% is removed from this function and placed in random_walk_metropolis_hastings_core.m funtion. -% Then the DYNARE parallel package contain a set of pairs matlab functios that can be executed in -% parallel and called name_function.m and name_function_core.m. -% In addition in the parallel package we have second set of functions used -% to manage the parallel computation. -% -% This function was the first function to be parallelized, later other -% functions have been parallelized using the same methodology. -% Then the comments write here can be used for all the other pairs of -% parallel functions and also for management funtions. +% See the comments in the random_walk_metropolis_hastings.m funtion. -% Copyright (C) 2006-2013 Dynare Team +% Copyright (C) 2006-2015 Dynare Team % % This file is part of Dynare. % @@ -74,11 +63,9 @@ end TargetFun=myinputs.TargetFun; ProposalFun=myinputs.ProposalFun; xparam1=myinputs.xparam1; -vv=myinputs.vv; mh_bounds=myinputs.mh_bounds; -ix2=myinputs.ix2; -ilogpo2=myinputs.ilogpo2; -ModelName=myinputs.ModelName; +last_draw=myinputs.ix2; +last_posterior=myinputs.ilogpo2; fline=myinputs.fline; npar=myinputs.npar; nruns=myinputs.nruns; @@ -94,11 +81,9 @@ estim_params_ = myinputs.estim_params_; options_ = myinputs.options_; M_ = myinputs.M_; oo_ = myinputs.oo_; -varargin=myinputs.varargin; % Necessary only for remote computing! if whoiam - Parallel=myinputs.Parallel; % initialize persistent variables in priordens() priordens(xparam1,bayestopt_.pshape,bayestopt_.p6,bayestopt_.p7, bayestopt_.p3,bayestopt_.p4,1); end @@ -116,53 +101,51 @@ elseif strcmpi(ProposalFun,'rand_multivariate_student') end % -% NOW i run the (nblck-fblck+1) metropolis-hastings chains +% Now I run the (nblck-fblck+1) Metropolis-Hastings chains % proposal_covariance_Cholesky_decomposition = d*diag(bayestopt_.jscale); -jloop=0; +block_iter=0; -JSUM = 0; -for b = fblck:nblck, - jloop=jloop+1; +for curr_block = fblck:nblck, + block_iter=block_iter+1; try - % This will not work if the master uses a random generator not + % This will not work if the master uses a random number generator not % available in the slave (different Matlab version or - % Matlab/Octave cluster). Therefor the trap. + % Matlab/Octave cluster). Therefore the trap. % - % This set the random generator type (the seed is useless but - % needed by the function) + % Set the random number generator type (the seed is useless but needed by the function) set_dynare_seed(options_.DynareRandomStreams.algo, options_.DynareRandomStreams.seed); - % This set the state - set_dynare_random_generator_state(record.InitialSeeds(b).Unifor, record.InitialSeeds(b).Normal); + % Set the state of the RNG + set_dynare_random_generator_state(record.InitialSeeds(curr_block).Unifor, record.InitialSeeds(curr_block).Normal); catch - % If the state set by master is incompatible with the slave, we - % only reseed - set_dynare_seed(options_.DynareRandomStreams.seed+b); + % If the state set by master is incompatible with the slave, we only reseed + set_dynare_seed(options_.DynareRandomStreams.seed+curr_block); end - if (options_.load_mh_file~=0) && (fline(b)>1) && OpenOldFile(b) - load([BaseName '_mh' int2str(NewFile(b)) '_blck' int2str(b) '.mat']) - x2 = [x2;zeros(InitSizeArray(b)-fline(b)+1,npar)]; - logpo2 = [logpo2;zeros(InitSizeArray(b)-fline(b)+1,1)]; - OpenOldFile(b) = 0; + if (options_.load_mh_file~=0) && (fline(curr_block)>1) && OpenOldFile(curr_block) %load previous draws and likelihood + load([BaseName '_mh' int2str(NewFile(curr_block)) '_blck' int2str(curr_block) '.mat']) + x2 = [x2;zeros(InitSizeArray(curr_block)-fline(curr_block)+1,npar)]; + logpo2 = [logpo2;zeros(InitSizeArray(curr_block)-fline(curr_block)+1,1)]; + OpenOldFile(curr_block) = 0; else - x2 = zeros(InitSizeArray(b),npar); - logpo2 = zeros(InitSizeArray(b),1); + x2 = zeros(InitSizeArray(curr_block),npar); + logpo2 = zeros(InitSizeArray(curr_block),1); end + %Prepare waiting bars if whoiam - prc0=(b-fblck)/(nblck-fblck+1)*(isoctave || options_.console_mode); - hh = dyn_waitbar({prc0,whoiam,options_.parallel(ThisMatlab)},['MH (' int2str(b) '/' int2str(options_.mh_nblck) ')...']); + prc0=(curr_block-fblck)/(nblck-fblck+1)*(isoctave || options_.console_mode); + hh = dyn_waitbar({prc0,whoiam,options_.parallel(ThisMatlab)},['MH (' int2str(curr_block) '/' int2str(options_.mh_nblck) ')...']); else - hh = dyn_waitbar(0,['Metropolis-Hastings (' int2str(b) '/' int2str(options_.mh_nblck) ')...']); + hh = dyn_waitbar(0,['Metropolis-Hastings (' int2str(curr_block) '/' int2str(options_.mh_nblck) ')...']); set(hh,'Name','Metropolis-Hastings'); end - isux = 0; - jsux = 0; - irun = fline(b); - j = 1; - while j <= nruns(b) - par = feval(ProposalFun, ix2(b,:), proposal_covariance_Cholesky_decomposition, n); + accepted_draws_this_chain = 0; + accepted_draws_this_file = 0; + draw_index_current_file = fline(curr_block); %get location of first draw in current block + draw_iter = 1; + while draw_iter <= nruns(curr_block) + par = feval(ProposalFun, last_draw(curr_block,:), proposal_covariance_Cholesky_decomposition, n); if all( par(:) > mh_bounds.lb ) && all( par(:) < mh_bounds.ub ) try logpost = - feval(TargetFun, par(:),dataset_,dataset_info,options_,M_,estim_params_,bayestopt_,mh_bounds,oo_); @@ -172,29 +155,29 @@ for b = fblck:nblck, else logpost = -inf; end - if (logpost > -inf) && (log(rand) < logpost-ilogpo2(b)) - x2(irun,:) = par; - ix2(b,:) = par; - logpo2(irun) = logpost; - ilogpo2(b) = logpost; - isux = isux + 1; - jsux = jsux + 1; + if (logpost > -inf) && (log(rand) < logpost-last_posterior(curr_block)) + x2(draw_index_current_file,:) = par; + last_draw(curr_block,:) = par; + logpo2(draw_index_current_file) = logpost; + last_posterior(curr_block) = logpost; + accepted_draws_this_chain = accepted_draws_this_chain + 1; + accepted_draws_this_file = accepted_draws_this_file + 1; else - x2(irun,:) = ix2(b,:); - logpo2(irun) = ilogpo2(b); + x2(draw_index_current_file,:) = last_draw(curr_block,:); + logpo2(draw_index_current_file) = last_posterior(curr_block); end - prtfrc = j/nruns(b); - if (mod(j, 3)==0 && ~whoiam) || (mod(j,50)==0 && whoiam) - dyn_waitbar(prtfrc,hh,[ 'MH (' int2str(b) '/' int2str(options_.mh_nblck) ') ' sprintf('Current acceptance ratio %4.3f', isux/j)]); + prtfrc = draw_iter/nruns(curr_block); + if (mod(draw_iter, 3)==0 && ~whoiam) || (mod(draw_iter,50)==0 && whoiam) + dyn_waitbar(prtfrc,hh,[ 'MH (' int2str(curr_block) '/' int2str(options_.mh_nblck) ') ' sprintf('Current acceptance ratio %4.3f', accepted_draws_this_chain/draw_iter)]); end - if (irun == InitSizeArray(b)) || (j == nruns(b)) % Now I save the simulations - save([BaseName '_mh' int2str(NewFile(b)) '_blck' int2str(b) '.mat'],'x2','logpo2'); + if (draw_index_current_file == InitSizeArray(curr_block)) || (draw_iter == nruns(curr_block)) % Now I save the simulations, either because the current file is full or the chain is done + save([BaseName '_mh' int2str(NewFile(curr_block)) '_blck' int2str(curr_block) '.mat'],'x2','logpo2'); fidlog = fopen([MetropolisFolder '/metropolis.log'],'a'); fprintf(fidlog,['\n']); - fprintf(fidlog,['%% Mh' int2str(NewFile(b)) 'Blck' int2str(b) ' (' datestr(now,0) ')\n']); + fprintf(fidlog,['%% Mh' int2str(NewFile(curr_block)) 'Blck' int2str(curr_block) ' (' datestr(now,0) ')\n']); fprintf(fidlog,' \n'); fprintf(fidlog,[' Number of simulations.: ' int2str(length(logpo2)) '\n']); - fprintf(fidlog,[' Acceptance ratio......: ' num2str(jsux/length(logpo2)) '\n']); + fprintf(fidlog,[' Acceptance ratio......: ' num2str(accepted_draws_this_file/length(logpo2)) '\n']); fprintf(fidlog,[' Posterior mean........:\n']); for i=1:length(x2(1,:)) fprintf(fidlog,[' params:' int2str(i) ': ' num2str(mean(x2(:,i))) '\n']); @@ -212,32 +195,32 @@ for b = fblck:nblck, fprintf(fidlog,[' log2po:' num2str(max(logpo2)) '\n']); fprintf(fidlog,' \n'); fclose(fidlog); - jsux = 0; - if j == nruns(b) % I record the last draw... - record.LastParameters(b,:) = x2(end,:); - record.LastLogPost(b) = logpo2(end); + accepted_draws_this_file = 0; + if draw_iter == nruns(curr_block) % I record the last draw... + record.LastParameters(curr_block,:) = x2(end,:); + record.LastLogPost(curr_block) = logpo2(end); end - % size of next file in chain b - InitSizeArray(b) = min(nruns(b)-j,MAX_nruns); + % size of next file in chain curr_block + InitSizeArray(curr_block) = min(nruns(curr_block)-draw_iter,MAX_nruns); % initialization of next file if necessary - if InitSizeArray(b) - x2 = zeros(InitSizeArray(b),npar); - logpo2 = zeros(InitSizeArray(b),1); - NewFile(b) = NewFile(b) + 1; - irun = 0; + if InitSizeArray(curr_block) + x2 = zeros(InitSizeArray(curr_block),npar); + logpo2 = zeros(InitSizeArray(curr_block),1); + NewFile(curr_block) = NewFile(curr_block) + 1; + draw_index_current_file = 0; end end - j=j+1; - irun = irun + 1; + draw_iter=draw_iter+1; + draw_index_current_file = draw_index_current_file + 1; end% End of the simulations for one mh-block. - record.AcceptanceRatio(b) = isux/j; + record.AcceptanceRatio(curr_block) = accepted_draws_this_chain/draw_iter; dyn_waitbar_close(hh); - [record.LastSeeds(b).Unifor, record.LastSeeds(b).Normal] = get_dynare_random_generator_state(); - OutputFileName(jloop,:) = {[MetropolisFolder,filesep], [ModelName '_mh*_blck' int2str(b) '.mat']}; + [record.LastSeeds(curr_block).Unifor, record.LastSeeds(curr_block).Normal] = get_dynare_random_generator_state(); + OutputFileName(block_iter,:) = {[MetropolisFolder,filesep], [ModelName '_mh*_blck' int2str(curr_block) '.mat']}; end% End of the loop over the mh-blocks. myoutput.record = record; -myoutput.irun = irun; +myoutput.irun = draw_index_current_file; myoutput.NewFile = NewFile; myoutput.OutputFileName = OutputFileName; \ No newline at end of file diff --git a/matlab/trace_plot.m b/matlab/trace_plot.m index 71fa7e742..bc7322737 100644 --- a/matlab/trace_plot.m +++ b/matlab/trace_plot.m @@ -1,13 +1,14 @@ function trace_plot(options_,M_,estim_params_,type,blck,name1,name2) -% This function build trace plot for the metropolis hastings draws. -% +% This function builds trace plot for the Metropolis-Hastings draws. % % INPUTS % % options_ [structure] Dynare structure. % M_ [structure] Dynare structure (related to model definition). % estim_params_ [structure] Dynare structure (related to estimation). -% type [string] 'DeepParameter', 'MeasurementError' (for measurement equation error) or 'StructuralShock' (for structural shock). +% type [string] 'DeepParameter', 'MeasurementError' (for measurement equation error), +% 'StructuralShock' (for structural shock) +% or 'PosteriorDensity (for posterior density)' % blck [integer] Number of the mh chain. % name1 [string] Object name. % name2 [string] Object name. @@ -17,7 +18,7 @@ function trace_plot(options_,M_,estim_params_,type,blck,name1,name2) % % SPECIAL REQUIREMENTS -% Copyright (C) 2003-2013 Dynare Team +% Copyright (C) 2003-2015 Dynare Team % % This file is part of Dynare. % @@ -35,10 +36,15 @@ function trace_plot(options_,M_,estim_params_,type,blck,name1,name2) % along with Dynare. If not, see . % Cet the column index: -if nargin<7 - column = name2index(options_, M_, estim_params_, type, name1); +if strcmpi(type,'PosteriorDensity') + column=0; + name1=''; else - column = name2index(options_, M_, estim_params_, type, name1, name2); + if nargin<7 + column = name2index(options_, M_, estim_params_, type, name1); + else + column = name2index(options_, M_, estim_params_, type, name1, name2); + end end if isempty(column) @@ -75,6 +81,8 @@ elseif strcmpi(type,'MeasurementError') else TYPE = 'the correlation between measurement errors '; end +elseif strcmpi(type,'PosteriorDensity') + TYPE='the posterior density'; end if nargin<7 @@ -111,9 +119,15 @@ legend({'MCMC draw';[num2str(N) ' period moving average']},'Location','NorthWest if ~exist(M_.fname, 'dir') mkdir('.',M_.fname); end -if ~exist([M_.fname filesep 'graphs']) +if ~exist([M_.fname filesep 'graphs'],'dir') mkdir(M_.fname,'graphs'); end -plot_name=get_the_name(column,0,M_,estim_params_,options_); + +%get name for plot +if strcmpi(type,'PosteriorDensity') + plot_name='Posterior'; +else + plot_name=get_the_name(column,0,M_,estim_params_,options_); +end dyn_saveas(hh,[M_.fname, filesep, 'graphs', filesep, 'TracePlot_' plot_name],options_) diff --git a/matlab/utilities/general/delete_stale_file.m b/matlab/utilities/general/delete_stale_file.m new file mode 100644 index 000000000..8ac8b7996 --- /dev/null +++ b/matlab/utilities/general/delete_stale_file.m @@ -0,0 +1,26 @@ +function delete_stale_file(fname) +% function delete_old_files(fname) +% Checks for presence of files and deletes them if necessary + +% Copyright (C) 2015 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 . + +Files_info = dir(fname); +if length(Files_info)>0 + delete(fname) +end + diff --git a/matlab/utilities/general/dyn_mex.m b/matlab/utilities/general/dyn_mex.m new file mode 100644 index 000000000..fe6b0555d --- /dev/null +++ b/matlab/utilities/general/dyn_mex.m @@ -0,0 +1,110 @@ +function dyn_mex(win_compiler,basename,force) + +% Compile Dynare model dlls when model option use_dll is used +% if C file is fresher than mex file +% +% INPUTS +% o win_compiler str compiler used under Windows (unused under Linux or OSX): +% 'msvc' (MS Visual C) +% 'cygwin' +% o basename str filenames base +% o force bool recompile if 1 +% +% OUTPUTS +% none +% + + +% Copyright (C) 2015 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 . + +Dc = dir([basename '_dynamic.c']); +Dmex = dir([basename '_dynamic.' mexext]); + +% compile only if date of C file is greater than date of mex file +% and force is not True +if ~isempty(Dmex) + if (Dmex.datenum > Dc.datenum) && ~force + disp('Mex files are newer than the source: not recompiled') + return + end +end + +if ~exist('OCTAVE_VERSION') + % Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail + if ispc + if msvc + % MATLAB/Windows + Microsoft Visual C++ + eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Dynamic" ' basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O LINKFLAGS="$LINKFLAGS /export:Dynamic" ' basename '_static.c ' basename '_static_mex.c']) + elseif cygwin + % MATLAB/Windows + Cygwin g++ + eval(['mex -O PRELINK_CMDS1="echo EXPORTS > mex.def & echo ' ... + 'mexFunction >> mex.def & echo Dynamic >> mex.def" ' ... + basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O PRELINK_CMDS1="echo EXPORTS > mex.def & echo ' ... + 'mexFunction >> mex.def & echo Dynamic >> mex.def" ' ... + basename '_static.c ' basename '_static_mex.c']) + else + error(['When using the USE_DLL option, you must give either ' ... + '''cygwin'' or ''msvc'' option to the ''dynare'' command']) + end + elseif isunix + % MATLAB/Linux + if matlab_ver_less_than('8.3') + eval(['mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' ' ... + basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' ' ... + basename '_static.c ' basename '_static_mex.c']) + else + eval(['mex -O LINKEXPORT='''' ' basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O LINKEXPORT='''' ' basename '_static.c ' basename '_static_mex.c']) + end + elseif ismac + % MATLAB/MacOS + if matlab_ver_less_than('8.3') + if matlab_ver_less_than('8.1') + eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ... + 'error -arch $ARCHS -Wl,-syslibroot,$SDKROOT ' ... + '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ... + basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ... + 'error -arch $ARCHS -Wl,-syslibroot,$SDKROOT ' ... + '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ... + basename '_static.c ' basename '_static_mex.c']) + else + eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ... + 'error -arch $ARCHS -Wl,-syslibroot,$MW_SDKROOT ' ... + '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ... + basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined ' ... + 'error -arch $ARCHS -Wl,-syslibroot,$MW_SDKROOT ' ... + '-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET -bundle'' ' ... + basename '_static.c ' basename '_static_mex.c']) + end + else + eval(['mex -O LINKEXPORT='''' ' basename '_dynamic.c ' ... + basename '_dynamic_mex.c']) + eval(['mex -O LINKEXPORT='''' ' basename '_static.c ' basename ... + '_static_mex.c']) + end + end +else + % Octave + eval(['mex ' basename '_dynamic.c ' basename '_dynamic_mex.c']) + eval(['mex ' basename '_static.c ' basename '_static_mex.c']) +end diff --git a/matlab/variance_decomposition_mc_analysis.m b/matlab/variance_decomposition_mc_analysis.m index b4f3f570d..798b28afe 100644 --- a/matlab/variance_decomposition_mc_analysis.m +++ b/matlab/variance_decomposition_mc_analysis.m @@ -1,6 +1,28 @@ function oo_ = variance_decomposition_mc_analysis(NumberOfSimulations,type,dname,fname,exonames,exo,vartan,var,mh_conf_sig,oo_) +% function oo_ = variance_decomposition_mc_analysis(NumberOfSimulations,type,dname,fname,exonames,exo,vartan,var,mh_conf_sig,oo_) % This function analyses the (posterior or prior) distribution of the -% endogenous variance decomposition. +% endogenous variables' variance decomposition. +% +% INPUTS +% NumberOfSimulations [integer] scalar, number of simulations. +% type [string] 'prior' or 'posterior' +% dname [string] directory name where to save +% fname [string] name of the mod-file +% exonames [string] (n_exo*char_length) character array with names of exogenous variables +% exo [string] name of current exogenous +% variable +% vartan [string] (n_endo*char_length) character array with name +% of endogenous variables +% var [integer] index of the current +% endogenous variable +% mh_conf_sig [double] 2 by 1 vector with upper +% and lower bound of HPD intervals +% oo_ [structure] Dynare structure where the results are saved. +% +% OUTPUTS +% oo_ [structure] Dynare structure where the results are saved. + + % Copyright (C) 2008-2013 Dynare Team % diff --git a/matlab/ver_greater_than.m b/matlab/ver_greater_than.m new file mode 100644 index 000000000..91e26f56b --- /dev/null +++ b/matlab/ver_greater_than.m @@ -0,0 +1,63 @@ +function tf = ver_greater_than(ver1, ver2) +%function tf = ver_greater_than(ver1, ver2) +% ver1 > ver2 ? 1 : 0; +% +% INPUTS +% ver1 [string] software version number +% ver2 [string] software version number +% +% OUTPUTS +% tf [bool] true if ver1 > ver2 +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2015 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 . + +tf = true; +ver1 = strsplit(ver1, {'.', '-'}); +ver2 = strsplit(ver2, {'.', '-'}); + +maj_ver1 = str2double(ver1{1}); +maj_ver2 = str2double(ver2{1}); +if maj_ver1 > maj_ver2 + return; +end + +min_ver1 = str2double(ver1{2}); +min_ver2 = str2double(ver2{2}); +if (maj_ver1 == maj_ver2) && (min_ver1 > min_ver2) + return; +end + +ismaster1 = isnan(str2double(ver1{3})); +ismaster2 = isnan(str2double(ver2{3})); +if (maj_ver1 == maj_ver2) && (min_ver1 == min_ver2) && (ismaster1 && ~ismaster2) + return; +end + +if ~ismaster1 && ~ismaster2 + rev_ver1 = str2double(ver1{3}); + rev_ver2 = str2double(ver2{3}); + if (maj_ver1 == maj_ver2) && (min_ver1 == min_ver2) && (rev_ver1 > rev_ver2) + return; + end +end + +tf = false; +end \ No newline at end of file diff --git a/matlab/ver_greater_than_equal.m b/matlab/ver_greater_than_equal.m new file mode 100644 index 000000000..84c54040a --- /dev/null +++ b/matlab/ver_greater_than_equal.m @@ -0,0 +1,33 @@ +function tf = ver_greater_than_equal(ver1, ver2) +%function tf = ver_greater_than_equal(ver1, ver2) +% ver1 >= ver2 ? 1 : 0; +% +% INPUTS +% ver1 [string] software version number +% ver2 [string] software version number +% +% OUTPUTS +% tf [bool] true if ver1 > ver2 +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2015 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 . + +tf = ver_greater_than(ver1, ver2) || strcmp(ver1, ver2); +end \ No newline at end of file diff --git a/matlab/ver_less_than.m b/matlab/ver_less_than.m new file mode 100644 index 000000000..7ad2d6425 --- /dev/null +++ b/matlab/ver_less_than.m @@ -0,0 +1,63 @@ +function tf = ver_less_than(ver1, ver2) +%function tf = ver_less_than(ver1, ver2) +% ver1 < ver2 ? 1 : 0; +% +% INPUTS +% ver1 [string] software version number +% ver2 [string] software version number +% +% OUTPUTS +% tf [bool] true if ver1 < ver2 +% +% SPECIAL REQUIREMENTS +% none + +% Copyright (C) 2015 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 . + +tf = true; +ver1 = strsplit(ver1, {'.', '-'}); +ver2 = strsplit(ver2, {'.', '-'}); + +maj_ver1 = str2double(ver1{1}); +maj_ver2 = str2double(ver2{1}); +if maj_ver1 < maj_ver2 + return; +end + +min_ver1 = str2double(ver1{2}); +min_ver2 = str2double(ver2{2}); +if (maj_ver1 == maj_ver2) && (min_ver1 < min_ver2) + return; +end + +ismaster1 = isnan(str2double(ver1{3})); +ismaster2 = isnan(str2double(ver2{3})); +if (maj_ver1 == maj_ver2) && (min_ver1 == min_ver2) && (~ismaster1 && ismaster2) + return; +end + +if ~ismaster1 && ~ismaster2 + rev_ver1 = str2double(ver1{3}); + rev_ver2 = str2double(ver2{3}); + if (maj_ver1 == maj_ver2) && (min_ver1 == min_ver2) && (rev_ver1 < rev_ver2) + return; + end +end + +tf = false; +end \ No newline at end of file diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index 8805ceb1c..9e767fad4 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -261,8 +261,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -280,8 +278,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -299,8 +295,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -318,8 +312,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -2801,89 +2793,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de typedef pair > index_KF; vector v_index_KF; - - /* DO 170, J = 1, N - TEMP1 = ALPHA*A( J, J ) - DO 110, I = 1, M - C( I, J ) = TEMP1*B( I, J ) - 11 110 CONTINUE - DO 140, K = 1, J - 1 - TEMP1 = ALPHA*A( K, J ) - DO 130, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 13 130 CONTINUE - 14 140 CONTINUE - DO 160, K = J + 1, N - TEMP1 = ALPHA*A( J, K ) - DO 150, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 15 150 CONTINUE - 16 160 CONTINUE - 17 170 CONTINUE - for(int j = 0; j < n; j++) - { - double temp1 = P_t_t1[j + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] = tmp1 * T[i + j * n]; - for (int k = 0; k < j - 1; k++) - { - temp1 = P_t_t1[k + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - for (int k = j + 1; k < n; k++) - { - temp1 = P_t_t1[j + k * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - }*/ for (int i = 0; i < n; i++) //int i = 0; for (int j = n_obs; j < n; j++) @@ -2902,7 +2811,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de for (vector::iterator it = v_index_KF.begin(); it != v_index_KF.end(); it++) KF_index_file.write(reinterpret_cast(&(*it)), sizeof(index_KF)); - //typedef pair, pair > index_KF_2; vector v_index_KF_2; int n_n_obs = n * n_obs; for (int i = 0; i < n; i++) @@ -4322,5 +4230,117 @@ DynamicModel::dynamicOnlyEquationsNbr() const return eqs.size(); } +#ifndef PRIVATE_BUFFER_SIZE +#define PRIVATE_BUFFER_SIZE 1024 +#endif +bool +DynamicModel::isChecksumMatching(const string &basename) const +{ + boost::crc_32_type result; + std::stringstream buffer; + + // Write equation tags + for (size_t i = 0; i < equation_tags.size(); i++) + buffer << " " << equation_tags[i].first + 1 + << equation_tags[i].second.first + << equation_tags[i].second.second; + + ExprNodeOutputType buffer_type = oCDynamicModel; + + for (int eq = 0; eq < (int) equations.size(); eq++) + { + BinaryOpNode *eq_node = equations[eq]; + expr_t lhs = eq_node->get_arg1(); + expr_t rhs = eq_node->get_arg2(); + + // Test if the right hand side of the equation is empty. + double vrhs = 1.0; + try + { + vrhs = rhs->eval(eval_context_t()); + } + catch (ExprNode::EvalException &e) + { + } + + if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; + { + buffer << "lhs ="; + lhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + + buffer << "rhs ="; + rhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + + buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) + << RIGHT_ARRAY_SUBSCRIPT(buffer_type) + << "= lhs-rhs;" << endl; + } + else // The right hand side of the equation is empty ==> residual=lhs; + { + buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) + << RIGHT_ARRAY_SUBSCRIPT(buffer_type) + << " = "; + lhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + } + } + + char private_buffer[PRIVATE_BUFFER_SIZE]; + while(buffer) + { + buffer.get(private_buffer,PRIVATE_BUFFER_SIZE); + result.process_bytes(private_buffer,strlen(private_buffer)); + } + + bool basename_dir_exists = false; +#ifdef _WIN32 + int r = mkdir(basename.c_str()); +#else + int r = mkdir(basename.c_str(), 0777); +#endif + if (r < 0) + if (errno != EEXIST) + { + perror("ERROR"); + exit(EXIT_FAILURE); + } + else + basename_dir_exists = true; + + // check whether basename directory exist. If not, create it. + // If it does, read old checksum if it exist + fstream checksum_file; + string filename = basename + "/checksum"; + unsigned int old_checksum = 0; + // read old checksum if it exists + if (basename_dir_exists) + { + checksum_file.open(filename.c_str(), ios::in | ios::binary); + if (checksum_file.is_open()) + { + checksum_file >> old_checksum; + checksum_file.close(); + } + } + // write new checksum file if none or different from old checksum + if (old_checksum != result.checksum()) + { + checksum_file.open(filename.c_str(), ios::out | ios::binary); + if (!checksum_file.is_open()) + { + cerr << "ERROR: Can't open file " << filename << endl; + exit(EXIT_FAILURE); + } + checksum_file << result.checksum(); + checksum_file.close(); + return false; + } + + return true; +} diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index d87093e77..835f09b70 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -24,6 +24,7 @@ using namespace std; #define ZERO_BAND 1e-8 #include +#include #include "StaticModel.hh" @@ -482,6 +483,8 @@ public: void writeSecondDerivativesC_csr(const string &basename, bool cuda) const; //! Writes C file containing third order derivatives of model evaluated at steady state (compressed sparse column) void writeThirdDerivativesC_csr(const string &basename, bool cuda) const; + + bool isChecksumMatching(const string &basename) const; }; //! Classes to re-order derivatives for various sparse storage formats diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy index 6c76d4161..bd9300e1f 100644 --- a/preprocessor/DynareBison.yy +++ b/preprocessor/DynareBison.yy @@ -82,17 +82,17 @@ class ParsingDriver; #define yylex driver.lexer->lex } -%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION -%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION -%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA +%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE +%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB TARB_NEW_BLOCK_PROBABILITY +%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER +%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA TARB_OPTIM %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN %token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED %token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF CYCLE_REDUCTION LOGARITHMIC_REDUCTION %token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED %token DATAFILE FILE SERIES DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR -%token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME +%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME %token FLOAT_NUMBER DATES %token DEFAULT FIXED_POINT OPT_ALGO %token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN @@ -1094,6 +1094,7 @@ stoch_simul_primary_options : o_dr_algo | o_dr_logarithmic_reduction_tol | o_dr_logarithmic_reduction_maxiter | o_irf_plot_threshold + | o_dr_display_tol ; stoch_simul_options : stoch_simul_primary_options @@ -1712,6 +1713,12 @@ estimation_options : o_datafile | o_filter_algorithm | o_proposal_approximation | o_distribution_approximation + | o_dirname + | o_huge_number + | o_use_tarb + | o_tarb_mode_compute + | o_tarb_new_block_probability + | o_tarb_optim ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -1724,6 +1731,16 @@ optim_options : list_optim_option | optim_options COMMA list_optim_option; ; +list_tarb_optim_option : QUOTED_STRING COMMA QUOTED_STRING + { driver.tarb_optim_options_string($1, $3); } + | QUOTED_STRING COMMA signed_number + { driver.tarb_optim_options_num($1, $3); } + ; + +tarb_optim_options : list_tarb_optim_option + | tarb_optim_options COMMA list_tarb_optim_option; + ; + varobs : VAROBS { driver.check_varobs(); } varobs_list ';'; varobs_list : varobs_list symbol @@ -1768,6 +1785,7 @@ osr_options : stoch_simul_primary_options | o_osr_tolf | o_opt_algo | o_optim + | o_huge_number ; osr : OSR ';' @@ -2546,6 +2564,8 @@ o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.optio o_file : FILE EQUAL filename { driver.option_str("file", $3); }; o_series : SERIES EQUAL symbol { driver.option_str("series", $3); }; o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); }; +o_dirname : DIRNAME EQUAL filename { driver.option_str("dirname", $3); }; +o_huge_number : HUGE_NUMBER EQUAL non_negative_number { driver.option_num("huge_number", $3); }; o_nobs : NOBS EQUAL vec_int { driver.option_vec_int("nobs", $3); } | NOBS EQUAL vec_int_number @@ -2612,6 +2632,7 @@ o_posterior_max_subsample_draws : POSTERIOR_MAX_SUBSAMPLE_DRAWS EQUAL INT_NUMBER o_mh_drop : MH_DROP EQUAL non_negative_number { driver.option_num("mh_drop", $3); }; o_mh_jscale : MH_JSCALE EQUAL non_negative_number { driver.option_num("mh_jscale", $3); }; o_optim : OPTIM EQUAL '(' optim_options ')'; +o_tarb_optim : TARB_OPTIM EQUAL '(' tarb_optim_options ')'; o_mh_init_scale : MH_INIT_SCALE EQUAL non_negative_number { driver.option_num("mh_init_scale", $3); }; o_mode_file : MODE_FILE EQUAL filename { driver.option_str("mode_file", $3); }; o_mode_compute : MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("mode_compute", $3); }; @@ -2866,7 +2887,9 @@ o_equations : EQUATIONS EQUAL vec_int | EQUATIONS EQUAL vec_int_number { driver.option_vec_int("ms.equations",$3); } ; - +o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); }; +o_tarb_mode_compute : TARB_MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("TaRB.mode_compute", $3); }; +o_tarb_new_block_probability : TARB_NEW_BLOCK_PROBABILITY EQUAL non_negative_number {driver.option_num("TaRB.new_block_probability",$3); }; o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; @@ -2964,6 +2987,7 @@ o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN { driver.option_str("MCMC_jumping_covariance", $3); } ; o_irf_plot_threshold : IRF_PLOT_THRESHOLD EQUAL non_negative_number { driver.option_num("impulse_responses.plot_threshold", $3); }; +o_dr_display_tol : DR_DISPLAY_TOL EQUAL non_negative_number { driver.option_num("dr_display_tol", $3); }; o_consider_all_endogenous : CONSIDER_ALL_ENDOGENOUS { driver.option_str("endo_vars_for_moment_computations_in_estimation", "all_endogenous_variables"); }; o_consider_only_observed : CONSIDER_ONLY_OBSERVED { driver.option_str("endo_vars_for_moment_computations_in_estimation", "only_observed_variables"); }; o_no_homotopy : NO_HOMOTOPY { driver.option_num("no_homotopy", "1"); }; diff --git a/preprocessor/DynareFlex.ll b/preprocessor/DynareFlex.ll index 0e7a31c16..5466487d3 100644 --- a/preprocessor/DynareFlex.ll +++ b/preprocessor/DynareFlex.ll @@ -236,6 +236,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");} file {return token::FILE;} datafile {return token::DATAFILE;} +dirname {return token::DIRNAME;} nobs {return token::NOBS;} last_obs {return token::LAST_OBS;} first_obs {return token::FIRST_OBS;} @@ -566,6 +567,12 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 period {return token::PERIOD;} outfile {return token::OUTFILE;} outvars {return token::OUTVARS;} +huge_number {return token::HUGE_NUMBER;} +dr_display_tol {return token::DR_DISPLAY_TOL;} +use_tarb {return token::USE_TARB;} +tarb_mode_compute {return token::TARB_MODE_COMPUTE;} +tarb_new_block_probability {return token::TARB_NEW_BLOCK_PROBABILITY;} +tarb_optim {return token::TARB_OPTIM;} [\$][^$]*[\$] { strtok(yytext+1, "$"); diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc index 19d773b8b..9320a4afd 100644 --- a/preprocessor/DynareMain.cc +++ b/preprocessor/DynareMain.cc @@ -38,7 +38,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType lang + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType lang #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -49,7 +49,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] " - << " [-D[=]] [nostrict] [output=dynamic|first|second|third] [language=C|C++]" + << " [-D[=]] [nostrict] [fast] [output=dynamic|first|second|third] [language=C|C++]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -97,6 +97,7 @@ main(int argc, char **argv) bool parallel_slave_open_mode = false; bool parallel_test = false; bool nostrict = false; + bool check_model_changes = false; map defines; FileOutputType output_mode = none; LanguageOutputType language = matlab; @@ -165,6 +166,8 @@ main(int argc, char **argv) parallel_test = true; else if (!strcmp(argv[arg], "nostrict")) nostrict = true; + else if (!strcmp(argv[arg], "fast")) + check_model_changes = true; else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8)) { parallel = true; @@ -285,7 +288,7 @@ main(int argc, char **argv) // Do the rest main2(macro_output, basename, debug, clear_all, clear_global, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, - parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, language + parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, check_model_changes, output_mode, language #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/preprocessor/DynareMain2.cc b/preprocessor/DynareMain2.cc index 376dd20a9..fe1c69427 100644 --- a/preprocessor/DynareMain2.cc +++ b/preprocessor/DynareMain2.cc @@ -27,7 +27,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType language + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType language #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -60,11 +60,12 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear if (output_mode != none) mod_file->writeExternalFiles(basename, output_mode, language); else - mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, nointeractive, config_file + mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, + nointeractive, config_file, check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) - , cygwin, msvc + , cygwin, msvc #endif - ); + ); delete mod_file; diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 66cd230e0..a828765d2 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -308,6 +308,12 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << datatree.num_constants.get(id); } +bool +NumConstNode::containsExternalFunction() const +{ + return false; +} + double NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) { @@ -577,6 +583,12 @@ VariableNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +VariableNode::containsExternalFunction() const +{ + return false; +} + void VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1726,6 +1738,12 @@ UnaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, te arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +UnaryOpNode::containsExternalFunction() const +{ + return arg->containsExternalFunction(); +} + void UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -2904,6 +2922,13 @@ BinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t } } +bool +BinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction(); +} + void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -3990,6 +4015,14 @@ TrinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, } } +bool +TrinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction() + || arg3->containsExternalFunction(); +} + void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -4333,15 +4366,6 @@ AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_ar { } -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : - AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) -{ - // Add myself to the external function map - datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; -} - void AbstractExternalFunctionNode::prepareForDerivation() { @@ -4372,20 +4396,6 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id) return composeDerivatives(dargs); } -expr_t -ExternalFunctionNode::composeDerivatives(const vector &dargs) -{ - vector dNodes; - for (int i = 0; i < (int) dargs.size(); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); - - expr_t theDeriv = datatree.Zero; - for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) - theDeriv = datatree.AddPlus(theDeriv, *it); - return theDeriv; -} - expr_t AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) { @@ -4397,76 +4407,6 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &reference_count, - temporary_terms_t &temporary_terms, - bool is_matlab) const -{ - temporary_terms.insert(const_cast(this)); -} - -void -AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - if (it != arguments.begin()) - output << ","; - - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - } -} - -void -AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, const string &ending) const -{ - output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; - int i = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } -} - -void -ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile - || output_type == oCSteadyStateFile || IS_LATEX(output_type)) - { - string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id) - : datatree.symbol_table.getName(symb_id); - output << name << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - if (IS_C(output_type)) - output << "*"; - output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms); -} - unsigned int AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -4480,184 +4420,6 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC return (arguments.size()); } -void -ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - - if (!lhs_rhs) - { - FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms)); - fldtef.write(CompileCode, instruction_number); - } - else - { - FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms)); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - if (IS_C(output_type)) - { - stringstream ending; - ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms); - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 3;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << ", " - << "*TEFDD_" << indx << ";" << endl; - else if (symb_id == first_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 2;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << "; " << endl; - else - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEF_" << indx << ";" << endl; - - output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl; - output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl; - writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << datatree.symbol_table.getName(symb_id) << "\");" << endl; - - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl - << "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl - << "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl; - else if (symb_id == first_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl; - else - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = "; - else if (symb_id == first_deriv_symb_id) - output << "[TEF_" << indx << " TEFD_"<< indx << "] = "; - else - output << "TEF_" << indx << " = "; - - output << datatree.symbol_table.getName(symb_id) << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } - } -} - -void -ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - unsigned int nb_output_arguments = 0; - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - nb_output_arguments = 3; - else if (symb_id == first_deriv_symb_id) - nb_output_arguments = 2; - else - nb_output_arguments = 1; - unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx); - switch (nb_output_arguments) - { - case 1: - fcall.set_function_type(ExternalFunctionWithoutDerivative); - break; - case 2: - fcall.set_function_type(ExternalFunctionWithFirstDerivative); - break; - case 3: - fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative); - break; - } - fcall.write(CompileCode, instruction_number); - FSTPTEF_ fstptef(indx); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - temporary_terms.insert(this2); - first_occurence[this2] = make_pair(Curr_block, equation); - v_temporary_terms[Curr_block][equation].insert(this2); -} - void AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { @@ -4686,56 +4448,6 @@ AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const thr throw EvalExternalFunctionException(); } -pair -AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - vector > V_arguments; - vector V_expr_t; - bool present = false; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); - present = present || V_arguments[V_arguments.size()-1].first; - V_expr_t.push_back(V_arguments[V_arguments.size()-1].second); - } - if (!present) - return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t))); - else - return (make_pair(1, (expr_t) NULL)); -} - -expr_t -ExternalFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddExternalFunction(symb_id, static_arguments); -} - -expr_t -ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); - return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments); -} - -expr_t -ExternalFunctionNode::cloneDynamicReindex(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamicReindex(dynamic_datatree, orig_symbol_table)); - return dynamic_datatree.AddExternalFunction(dynamic_datatree.symbol_table.getID(orig_symbol_table.getName(symb_id)), - dynamic_arguments); -} - int AbstractExternalFunctionNode::maxEndoLead() const { @@ -4858,12 +4570,6 @@ AbstractExternalFunctionNode::differentiateForwardVars(const vector &sub return buildSimilarExternalFunctionNode(arguments_subst, datatree); } -expr_t -ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddExternalFunction(symb_id, alt_args); -} - bool AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const { @@ -4936,10 +4642,342 @@ AbstractExternalFunctionNode::isInStaticForm() const for (vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) if (!(*it)->isInStaticForm()) return false; - return true; } +pair +AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const +{ + vector > V_arguments; + vector V_expr_t; + bool present = false; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); + present = present || V_arguments[V_arguments.size()-1].first; + V_expr_t.push_back(V_arguments[V_arguments.size()-1].second); + } + if (!present) + return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t))); + else + return (make_pair(1, (expr_t) NULL)); +} + +void +AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + if (it != arguments.begin()) + output << ","; + + (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); + } +} + +void +AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms, const string &ending) const +{ + output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; + int i = 0; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars + (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); + output << ");" << endl; + } +} + +bool +AbstractExternalFunctionNode::containsExternalFunction() const +{ + return true; +} + +ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, + int symb_id_arg, + const vector &arguments_arg) : + AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) +{ + // Add myself to the external function map + datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; +} + +expr_t +ExternalFunctionNode::composeDerivatives(const vector &dargs) +{ + vector dNodes; + for (int i = 0; i < (int) dargs.size(); i++) + dNodes.push_back(datatree.AddTimes(dargs.at(i), + datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); + + expr_t theDeriv = datatree.Zero; + for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) + theDeriv = datatree.AddPlus(theDeriv, *it); + return theDeriv; +} + +void +ExternalFunctionNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + bool is_matlab) const +{ + temporary_terms.insert(const_cast(this)); +} + +void +ExternalFunctionNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const +{ + expr_t this2 = const_cast(this); + temporary_terms.insert(this2); + first_occurence[this2] = make_pair(Curr_block, equation); + v_temporary_terms[Curr_block][equation].insert(this2); +} + +void +ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (dynamic) + { + map_idx_t::const_iterator ii = map_idx.find(idx); + FLDT_ fldt(ii->second); + fldt.write(CompileCode, instruction_number); + } + else + { + map_idx_t::const_iterator ii = map_idx.find(idx); + FLDST_ fldst(ii->second); + fldst.write(CompileCode, instruction_number); + } + return; + } + + if (!lhs_rhs) + { + FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms)); + fldtef.write(CompileCode, instruction_number); + } + else + { + FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms)); + fstptef.write(CompileCode, instruction_number); + } +} + +void +ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); + assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); + + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, + map_idx, dynamic, steady_dynamic, tef_terms); + + if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) + { + tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); + int indx = getIndxInTefTerms(symb_id, tef_terms); + int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); + assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); + + unsigned int nb_output_arguments = 0; + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + nb_output_arguments = 3; + else if (symb_id == first_deriv_symb_id) + nb_output_arguments = 2; + else + nb_output_arguments = 1; + unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, + map_idx, dynamic, steady_dynamic, tef_terms); + + FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx); + switch (nb_output_arguments) + { + case 1: + fcall.set_function_type(ExternalFunctionWithoutDerivative); + break; + case 2: + fcall.set_function_type(ExternalFunctionWithFirstDerivative); + break; + case 3: + fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative); + break; + } + fcall.write(CompileCode, instruction_number); + FSTPTEF_ fstptef(indx); + fstptef.write(CompileCode, instruction_number); + } +} + +void +ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile + || output_type == oCSteadyStateFile || IS_LATEX(output_type)) + { + string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id) + : datatree.symbol_table.getName(symb_id); + output << name << "("; + writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); + output << ")"; + return; + } + + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } + + if (IS_C(output_type)) + output << "*"; + output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms); +} + +void +ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); + assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); + + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); + + if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) + { + tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); + int indx = getIndxInTefTerms(symb_id, tef_terms); + int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); + assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); + + if (IS_C(output_type)) + { + stringstream ending; + ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms); + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "int nlhs" << ending.str() << " = 3;" << endl + << "double *TEF_" << indx << ", " + << "*TEFD_" << indx << ", " + << "*TEFDD_" << indx << ";" << endl; + else if (symb_id == first_deriv_symb_id) + output << "int nlhs" << ending.str() << " = 2;" << endl + << "double *TEF_" << indx << ", " + << "*TEFD_" << indx << "; " << endl; + else + output << "int nlhs" << ending.str() << " = 1;" << endl + << "double *TEF_" << indx << ";" << endl; + + output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl; + output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl; + writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); + + output << "mexCallMATLAB(" + << "nlhs" << ending.str() << ", " + << "plhs" << ending.str() << ", " + << "nrhs" << ending.str() << ", " + << "prhs" << ending.str() << ", \"" + << datatree.symbol_table.getName(symb_id) << "\");" << endl; + + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl + << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl + << "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl + << "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl; + else if (symb_id == first_deriv_symb_id) + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl + << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl; + else + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; + } + else + { + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = "; + else if (symb_id == first_deriv_symb_id) + output << "[TEF_" << indx << " TEFD_"<< indx << "] = "; + else + output << "TEF_" << indx << " = "; + + output << datatree.symbol_table.getName(symb_id) << "("; + writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); + output << ");" << endl; + } + } +} + +expr_t +ExternalFunctionNode::toStatic(DataTree &static_datatree) const +{ + vector static_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + static_arguments.push_back((*it)->toStatic(static_datatree)); + return static_datatree.AddExternalFunction(symb_id, static_arguments); +} + +expr_t +ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const +{ + vector dynamic_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); + return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments); +} + +expr_t +ExternalFunctionNode::cloneDynamicReindex(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table) const +{ + vector dynamic_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + dynamic_arguments.push_back((*it)->cloneDynamicReindex(dynamic_datatree, orig_symbol_table)); + return dynamic_datatree.AddExternalFunction(dynamic_datatree.symbol_table.getID(orig_symbol_table.getName(symb_id)), + dynamic_arguments); +} + +expr_t +ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const +{ + return alt_datatree.AddExternalFunction(symb_id, alt_args); +} + FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, const vector &arguments_arg, diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index b6c7b9b93..bef4a4157 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -187,6 +187,9 @@ public: */ virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; + //! returns true if the expr node contains an external function + virtual bool containsExternalFunction() const = 0; + //! Writes output of node (with no temporary terms and with "outside model" output type) void writeOutput(ostream &output) const; @@ -444,6 +447,7 @@ public: }; virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -490,6 +494,7 @@ public: VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg); virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, @@ -557,6 +562,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -636,6 +642,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -731,6 +738,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -803,6 +811,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const = 0; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index 8824d84bc..0592c6208 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -490,55 +490,55 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) // Compute static model and its derivatives dynamic_model.toStatic(static_model); if (!no_static) - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - static_model.set_cutoff_to_zero(); + { + if (mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + static_model.set_cutoff_to_zero(); - const bool static_hessian = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - const bool paramsDerivatives = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, - false, paramsDerivatives, block, byte_code); - } + const bool static_hessian = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + const bool paramsDerivatives = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, + false, paramsDerivatives, block, byte_code); + } // Set things to compute for dynamic model if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present - || mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - { - if (mod_file_struct.perfect_foresight_solver_present) - dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - else - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - dynamic_model.set_cutoff_to_zero(); - if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) - { - cerr << "ERROR: Incorrect order option..." << endl; - exit(EXIT_FAILURE); - } - bool hessian = mod_file_struct.order_option >= 2 - || mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation - || output == second - || output == third; - bool thirdDerivatives = mod_file_struct.order_option == 3 - || mod_file_struct.estimation_analytic_derivation - || output == third; - bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - } - } - else // No computing task requested, compute derivatives up to 2nd order by default - dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + || mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + { + if (mod_file_struct.perfect_foresight_solver_present) + dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + else + { + if (mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + dynamic_model.set_cutoff_to_zero(); + if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) + { + cerr << "ERROR: Incorrect order option..." << endl; + exit(EXIT_FAILURE); + } + bool hessian = mod_file_struct.order_option >= 2 + || mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation + || output == second + || output == third; + bool thirdDerivatives = mod_file_struct.order_option == 3 + || mod_file_struct.estimation_analytic_derivation + || output == third; + bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; + dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + } + } + else // No computing task requested, compute derivatives up to 2nd order by default + dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); } for (vector::iterator it = statements.begin(); @@ -547,7 +547,8 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) } void -ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file +ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, + bool nointeractive, const ConfigFile &config_file, bool check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -595,6 +596,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl << "options_ = [];" << endl << "M_.fname = '" << basename << "';" << endl + << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl << "%" << endl << "% Some global variables initialization" << endl << "%" << endl; @@ -613,7 +617,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo if (nointeractive) mOutputFile << "options_.nointeractive = 1;" << endl; - cout << "Processing outputs ..."; + cout << "Processing outputs ..." << endl; symbol_table.writeOutput(mOutputFile); @@ -667,18 +671,25 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl << "end" << endl; - // Erase possible remnants of previous runs - unlink((basename + "_dynamic.m").c_str()); - unlink((basename + "_dynamic.cod").c_str()); - unlink((basename + "_dynamic.bin").c_str()); + bool hasModelChanged = !dynamic_model.isChecksumMatching(basename); + if (!check_model_changes) + hasModelChanged = true; + + if (hasModelChanged) + { + // Erase possible remnants of previous runs + unlink((basename + "_dynamic.m").c_str()); + unlink((basename + "_dynamic.cod").c_str()); + unlink((basename + "_dynamic.bin").c_str()); - unlink((basename + "_static.m").c_str()); - unlink((basename + "_static.cod").c_str()); - unlink((basename + "_static.bin").c_str()); - - unlink((basename + "_steadystate2.m").c_str()); - unlink((basename + "_set_auxiliary_variables.m").c_str()); + unlink((basename + "_static.m").c_str()); + unlink((basename + "_static.cod").c_str()); + unlink((basename + "_static.bin").c_str()); + unlink((basename + "_steadystate2.m").c_str()); + unlink((basename + "_set_auxiliary_variables.m").c_str()); + } + if (!use_dll) { mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl; @@ -713,55 +724,22 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo #endif // Compile the dynamic MEX file for use_dll option + // When check_model_changes is true, don't force compile if MEX is fresher than source if (use_dll) { - mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl; - // Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail #if defined(_WIN32) || defined(__CYGWIN32__) if (msvc) // MATLAB/Windows + Microsoft Visual C++ - mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Static\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('msvc', '" << basename << "', " << !check_model_changes << ")" << endl; else if (cygwin) // MATLAB/Windows + Cygwin g++ - mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Static >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl; else mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl; #else -# ifdef __linux__ - // MATLAB/Linux - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# else // MacOS - // MATLAB/MacOS - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " if matlab_ver_less_than('8.1')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " end" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# endif + // other configurations + mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl; #endif - mOutputFile << "else" << endl // Octave - << " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl - << " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl - << "end" << endl; } // Add path for block option with M-files @@ -842,22 +820,24 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo mOutputFile.close(); - // Create static and dynamic files - if (dynamic_model.equation_number() > 0) + if (hasModelChanged) { - if (!no_static) - { - static_model.writeStaticFile(basename, block, byte_code, use_dll); - static_model.writeParamsDerivativesFile(basename); - } + // Create static and dynamic files + if (dynamic_model.equation_number() > 0) + { + if (!no_static) + { + static_model.writeStaticFile(basename, block, byte_code, use_dll); + static_model.writeParamsDerivativesFile(basename); + } - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); - dynamic_model.writeParamsDerivativesFile(basename); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeParamsDerivativesFile(basename); + } + + // Create steady state file + steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); } - - // Create steady state file - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); - + cout << "done" << endl; } - diff --git a/preprocessor/ModFile.hh b/preprocessor/ModFile.hh index 722ea5341..bf3636685 100644 --- a/preprocessor/ModFile.hh +++ b/preprocessor/ModFile.hh @@ -24,6 +24,8 @@ using namespace std; #include #include +#include +#include #include "SymbolTable.hh" #include "NumericalConstants.hh" @@ -37,6 +39,11 @@ using namespace std; #include "WarningConsolidation.hh" #include "ExtendedPreprocessorTypes.hh" +// for checksum computation +#ifndef PRIVATE_BUFFER_SIZE +#define PRIVATE_BUFFER_SIZE 1024 +#endif + //! The abstract representation of a "mod" file class ModFile { @@ -138,7 +145,8 @@ public: \param cygwin Should the MEX command of use_dll be adapted for Cygwin? \param msvc Should the MEX command of use_dll be adapted for MSVC? */ - void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file + void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, + bool console, bool nograph, bool nointeractive, const ConfigFile &config_file, bool check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -153,6 +161,8 @@ public: //! Writes Cpp output files only => No further Matlab processing void writeCCOutputFiles(const string &basename) const; void writeModelCC(const string &basename) const; + + void computeChecksum(); }; #endif // ! MOD_FILE_HH diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 67c4be456..ba541ec81 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -1630,6 +1630,34 @@ ParsingDriver::optim_options_num(string *name, string *value) delete value; } +void +ParsingDriver::tarb_optim_options_helper(const string &name) +{ + if (options_list.string_options.find("TaRB.optim_opt") == options_list.string_options.end()) + options_list.string_options["TaRB.optim_opt"] = ""; + else + options_list.string_options["TaRB.optim_opt"] += ","; + options_list.string_options["TaRB.optim_opt"] += "''" + name + "'',"; +} + +void +ParsingDriver::tarb_optim_options_string(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += "''" + *value + "''"; + delete name; + delete value; +} + +void +ParsingDriver::tarb_optim_options_num(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += *value; + delete name; + delete value; +} + void ParsingDriver::check_varobs() { diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index d4ebc05dc..dd93276c0 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -98,6 +98,7 @@ private: //! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name void optim_options_helper(const string &name); + void tarb_optim_options_helper(const string &name); //! Stores temporary symbol table SymbolList symbol_list; @@ -443,6 +444,10 @@ public: void optim_options_string(string *name, string *value); //! Adds an optimization option (numeric value) void optim_options_num(string *name, string *value); + //! Adds a TaRB optimization option (string value) + void tarb_optim_options_string(string *name, string *value); + //! Adds a TaRB optimization option (numeric value) + void tarb_optim_options_num(string *name, string *value); //! Check that no observed variable has yet be defined void check_varobs(); //! Add a new observed variable diff --git a/preprocessor/StaticModel.cc b/preprocessor/StaticModel.cc index 09fb9261b..045e63364 100644 --- a/preprocessor/StaticModel.cc +++ b/preprocessor/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 Dynare Team + * Copyright (C) 2003-2015 Dynare Team * * This file is part of Dynare. * @@ -1927,9 +1927,16 @@ void StaticModel::writeAuxVarRecursiveDefinitions(const string &basename) const << "% from model file (.mod)" << endl << endl; + deriv_node_temp_terms_t tef_terms; + temporary_terms_t temporary_terms; + for (int i = 0; i < (int) aux_equations.size(); i++) + if (dynamic_cast(aux_equations[i])->containsExternalFunction()) + dynamic_cast(aux_equations[i])->writeExternalFunctionOutput(output, oMatlabStaticModel, + temporary_terms, tef_terms); + for (int i = 0; i < (int) aux_equations.size(); i++) { - dynamic_cast(aux_equations[i])->writeOutput(output, oMatlabStaticModel); + dynamic_cast(aux_equations[i])->writeOutput(output, oMatlabStaticModel, temporary_terms, tef_terms); output << ";" << endl; } } diff --git a/tests/Makefile.am b/tests/Makefile.am index 14e46b716..97d9cb434 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,10 @@ MODFILES = \ estimation/fs2000_MCMC_jumping_covariance.mod \ estimation/fs2000_initialize_from_calib.mod \ estimation/fs2000_calibrated_covariance.mod \ + estimation/MH_recover/fs2000_recover.mod \ + estimation/t_proposal/fs2000_student.mod \ gsa/ls2003.mod \ + gsa/ls2003a.mod \ ramst.mod \ ramst_a.mod \ ramst_static_tag.mod \ @@ -89,15 +92,11 @@ MODFILES = \ fs2000/fs2000.mod \ fs2000/fs2000a.mod \ fs2000/fs2000c.mod \ - fs2000/fs2000d.mod \ - fs2000/fs2000e.mod \ - fs2000/fs2000_cmaes.mod \ fs2000/fs2000_calib.mod \ fs2000/fs2000_calib_dseries.mod \ fs2000/fs2000_analytic_derivation.mod \ fs2000/fs2000_missing_data.mod \ fs2000/fs2000_sd.mod \ - fs2000/fs2000_mode_compute_8.mod \ fs2000/fs2000_dseries_a.mod \ fs2000/fs2000_dseries_b.mod \ homotopy/homotopy1_test.mod \ @@ -136,6 +135,7 @@ MODFILES = \ conditional_forecasts/fs2000_est.mod \ recursive/ls2003.mod \ recursive/ls2003_bayesian.mod \ + recursive/ls2003_bayesian_xls.mod \ ms-sbvar/test_exclusions.mod \ ms-sbvar/test_exclusions_nc.mod \ ms-sbvar/test_lower_cholesky.mod \ @@ -183,6 +183,7 @@ MODFILES = \ deterministic_simulations/rbc_det_exo_lag_2a.mod \ deterministic_simulations/rbc_det_exo_lag_2b.mod \ deterministic_simulations/rbc_det_exo_lag_2c.mod \ + deterministic_simulations/sim_several_leads_lags.mod \ walsh.mod \ measurement_errors/fs2000_corr_me_ml_mcmc/fs2000_corr_ME.mod \ trend_var/fs2000_nonstationary.mod \ @@ -205,6 +206,21 @@ MODFILES = \ smoother2histval/fs2000_simul.mod \ smoother2histval/fs2000_smooth.mod \ smoother2histval/fs2000_smooth_stoch_simul.mod \ + optimizers/fs2000_2.mod \ + optimizers/fs2000_3.mod \ + optimizers/fs2000_4.mod \ + optimizers/fs2000_4_with_optim.mod \ + optimizers/fs2000_5.mod \ + optimizers/fs2000_6.mod \ + optimizers/fs2000_7.mod \ + optimizers/fs2000_8.mod \ + optimizers/fs2000_8_with_optim.mod \ + optimizers/fs2000_9.mod \ + optimizers/fs2000_10.mod \ + optimizers/fs2000_101.mod \ + optimizers/fs2000_102.mod \ + optimizers/fs2000_w.mod \ + differentiate_forward_vars/RBC_differentiate_forward.mod \ reporting/example1.mod XFAIL_MODFILES = ramst_xfail.mod \ @@ -394,7 +410,9 @@ EXTRA_DIST = \ loglinear/results_exp.mat \ smoother2histval/fsdat_simul.m \ optimal_policy/Ramsey/find_c.m \ - optimal_policy/Ramsey/oo_ramsey_policy_initval.mat + optimal_policy/Ramsey/oo_ramsey_policy_initval.mat \ + optimizers/optimizer_function_wrapper.m \ + optimizers/fs2000.common.inc TARGETS = @@ -419,30 +437,56 @@ check-octave: $(O_XFAIL_TRS_FILES) $(O_TRS_FILES) @echo 'Octave Tests Done' %.m.trs %.m.log: %.mod - DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ - $(MATLAB)/bin/matlab -nosplash -nodisplay -logfile $*.m.log -r run_test_matlab + @echo "`tput bold``tput setaf 3`MATLAB: $(PWD)/$*... `tput sgr0`" + @DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ + $(MATLAB)/bin/matlab -nosplash -nodisplay -r run_test_matlab > $*.m.log 2> /dev/null + @if grep -q ":test-result: PASS" $*.m.trs; then \ + echo "`tput bold``tput setaf 2`MATLAB: $(PWD)/$* PASSED!`tput sgr0`" ; \ + else \ + echo "`tput bold``tput setaf 1`MATLAB: $(PWD)/$* FAILED!`tput sgr0`" ; \ + fi + +%.m.drs %.m.log: %.m.trs + @cat $*.m.log %.m.trs %.m.log : %.m - DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" \ - $(MATLAB)/bin/matlab -nosplash -nodisplay -logfile $*.m.log -r $* + @echo "`tput bold``tput setaf 3`MATLAB: $(PWD)/$*... `tput sgr0`" + @DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" \ + $(MATLAB)/bin/matlab -nosplash -nodisplay -r $* > $*.m.log 2> /dev/null + @echo "`tput bold``tput setaf 3`MATLAB: $(PWD)/$* Done!`tput sgr0`" %.o.trs %.o.log: %.mod - DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ + @echo "`tput bold``tput setaf 3`OCTAVE: $(PWD)/$*... `tput sgr0`" + @DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ $(OCTAVE) --no-init-file --silent --no-history run_test_octave.m > $*.o.log 2>&1 + @if grep -q ":test-result: PASS" $*.o.trs; then \ + echo "`tput bold``tput setaf 2`OCTAVE: $(PWD)/$* PASSED!`tput sgr0`" ; \ + else \ + echo "`tput bold``tput setaf 1`OCTAVE: $(PWD)/$* FAILED!`tput sgr0`" ; \ + fi + +%.o.drs %.o.log: %.mod %.o.trs + @cat $*.o.log %.o.trs %.o.log : %.m - DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" \ + @echo "`tput bold``tput setaf 3`OCTAVE: $(PWD)/$*... `tput sgr0`" + @DYNARE_VERSION="$(PACKAGE_VERSION)" TOP_TEST_DIR="$(PWD)" \ $(OCTAVE) --no-init-file --silent --no-history $< > $*.o.log 2>&1 + @echo "`tput bold``tput setaf 3`OCTAVE: $(PWD)/$* Done!`tput sgr0`" %.m.tls : %.m - TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ - $(MATLAB)/bin/matlab -nosplash -nodisplay -r run_m_script - touch $*.m.tls + @echo "`tput bold``tput setaf 3`MATLAB: $(PWD)/$*... `tput sgr0`" + @TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ + $(MATLAB)/bin/matlab -nosplash -nodisplay -r run_m_script 2> /dev/null + @touch $*.m.tls + @echo "`tput bold`MATLAB`tput setaf 3`: $(PWD)/$* Done!`tput sgr0`" %.o.tls : %.m - TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ + @echo "`tput bold``tput setaf 3`OCTAVE: $(PWD)/$*... `tput sgr0`" + @TOP_TEST_DIR="$(PWD)" FILESTEM="$*" \ $(OCTAVE) --no-init-file --silent --no-history run_o_script.m 2>&1 - + @touch $*.o.tls + @echo "`tput bold``tput setaf 3`OCTAVE: $(PWD)/$* Done!`tput sgr0`" clean-local: rm -f $(M_TRS_FILES) \ diff --git a/tests/deterministic_simulations/sim_several_leads_lags.mod b/tests/deterministic_simulations/sim_several_leads_lags.mod new file mode 100644 index 000000000..058315bd3 --- /dev/null +++ b/tests/deterministic_simulations/sim_several_leads_lags.mod @@ -0,0 +1,35 @@ +var c k z_forward z_backward; +varexo x z_shock; + +parameters alph gam delt bet aa; +alph=0.5; +gam=0.5; +delt=0.02; +bet=0.05; +aa=0.5; + +model; +c + k - aa*x*k(-1)^alph - (1-delt)*k(-1); // Resource constraint +c^(-gam) - (1+bet)^(-1)*(aa*alph*x(+1)*k^(alph-1) + 1 - delt)*c(+1)^(-gam); // Euler equation +z_backward=0.1*1+0.3*z_backward(-1)+0.3*z_backward(-2)+0.3*z_backward(-3)+(x(-4)-1); +z_forward=0.1*1+0.45*z_forward(+1)+0.45*z_forward(+2)+(x(+4)-1); +end; + +initval; +c = 1.2; +k = 12; +x = 1; +end; + +histval; +x(-1)=1.30; +x(-2)=1.30; +end; + +shocks; +var x; +periods 2; +values 0.9; +end; + +simul(periods=200,maxit=100); \ No newline at end of file diff --git a/tests/differentiate_forward_vars/RBC_differentiate_forward.mod b/tests/differentiate_forward_vars/RBC_differentiate_forward.mod new file mode 100644 index 000000000..f95c85404 --- /dev/null +++ b/tests/differentiate_forward_vars/RBC_differentiate_forward.mod @@ -0,0 +1,92 @@ +/* +* This model shows how to use the differentiate_forward_vars option to simulate +* perfect foresight models when the steady state is unknown +* or when the model is very persistent. In this file, we consider an RBC model +* with a CES technology and very persistent productivity shock. We set the +* autoregressive parameter of this exogenous productivity to 0.999, so that +* in period 400 the level of productivity, after an initial one percent shock, +* is still 0.67\% above its steady state level. +* +* Written by Stéphane Adjemian. For more information, see +* http://gitlab.ithaca.fr/Dynare/differentiate-forward-variables +*/ +var Capital, Output, Labour, Consumption, Efficiency, efficiency, ExpectedTerm; + +varexo EfficiencyInnovation; + +parameters beta, theta, tau, alpha, psi, delta, rho, effstar, sigma; + +/* +** Calibration +*/ + +beta = 0.990; +theta = 0.357; +tau = 30.000; +alpha = 0.450; +psi = -1.000; // So that the elasticity of substitution between inputs is 1/(1-psi)=1/10 +delta = 0.020; +rho = 0.999; +effstar = 1.000; +sigma = 0.010; + +model(differentiate_forward_vars); + + // Eq. n°1: + efficiency = rho*efficiency(-1) + sigma*EfficiencyInnovation; + + // Eq. n°2: + Efficiency = effstar*exp(efficiency); + + // Eq. n°3: + Output = Efficiency*(alpha*(Capital(-1)^psi)+(1-alpha)*(Labour^psi))^(1/psi); + + // Eq. n°4: + Consumption + Capital - Output - (1-delta)*Capital(-1); + + // Eq. n°5: + ((1-theta)/theta)*(Consumption/(1-Labour)) - (1-alpha)*(Output/Labour)^(1-psi); + + // Eq. n°6: + (((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption - ExpectedTerm(1); + + // Eq. n°7: + ExpectedTerm = beta*((((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption)*(alpha*((Output/Capital(-1))^(1-psi))+1-delta); + +end; + +steady_state_model; + + efficiency = 0; + Efficiency = effstar; + + // Compute some steady state ratios. + Output_per_unit_of_Capital=((1/beta-1+delta)/alpha)^(1/(1-psi)); + Consumption_per_unit_of_Capital=Output_per_unit_of_Capital-delta; + Labour_per_unit_of_Capital=(((Output_per_unit_of_Capital/Efficiency)^psi-alpha)/(1-alpha))^(1/psi); + Output_per_unit_of_Labour=Output_per_unit_of_Capital/Labour_per_unit_of_Capital; + Consumption_per_unit_of_Labour=Consumption_per_unit_of_Capital/Labour_per_unit_of_Capital; + + // Compute steady state share of capital. + ShareOfCapital=alpha/(alpha+(1-alpha)*Labour_per_unit_of_Capital^psi); + + // Compute steady state of the endogenous variables. + Labour=1/(1+Consumption_per_unit_of_Labour/((1-alpha)*theta/(1-theta)*Output_per_unit_of_Labour^(1-psi))); + Consumption = Consumption_per_unit_of_Labour*Labour; + Capital = Labour/Labour_per_unit_of_Capital; + Output = Output_per_unit_of_Capital*Capital; + ExpectedTerm = beta*((((Consumption^theta)*((1-Labour)^(1-theta)))^(1-tau))/Consumption)*(alpha*((Output/Capital)^(1-psi))+1-delta); + +end; + + +shocks; +var EfficiencyInnovation; +periods 1; +values 1; +end; + +steady; +check; + +simul(periods=500); diff --git a/tests/estimation/MH_recover/fs2000_recover.mod b/tests/estimation/MH_recover/fs2000_recover.mod new file mode 100644 index 000000000..bfb7b68d0 --- /dev/null +++ b/tests/estimation/MH_recover/fs2000_recover.mod @@ -0,0 +1,139 @@ +/* + * This file replicates the estimation of the cash in advance model described + * Frank Schorfheide (2000): "Loss function-based evaluation of DSGE models", + * Journal of Applied Econometrics, 15(6), 645-670. + * + * The data are in file "fsdat_simul.m", and have been artificially generated. + * They are therefore different from the original dataset used by Schorfheide. + * + * The equations are taken from J. Nason and T. Cogley (1994): "Testing the + * implications of long-run neutrality for monetary business cycle models", + * Journal of Applied Econometrics, 9, S37-S70. + * Note that there is an initial minus sign missing in equation (A1), p. S63. + * + * This implementation was written by Michel Juillard. Please note that the + * following copyright notice only applies to this Dynare implementation of the + * model. + */ + +/* + * Copyright (C) 2004-2010 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 . + */ + +var m P c e W R k d n l gy_obs gp_obs y dA; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +dA = exp(gam+e_a); +log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; +-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; +W = l/n; +-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; +R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; +1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; +c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); +P*c = m; +m-1+d = l; +e = exp(e_a); +y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); +gy_obs = dA*y/y(-1); +gp_obs = (P/P(-1))*m(-1)/dA; +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady_state_model; + dA = exp(gam); + gst = 1/dA; + m = mst; + khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); + xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); + nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); + n = xist/(nust+xist); + P = xist + nust; + k = khst*n; + + l = psi*mst*n/( (1-psi)*(1-n) ); + c = mst/P; + d = l - mst + 1; + y = k^alp*n^(1-alp)*gst^alp; + R = mst/bet; + W = l/n; + ist = y-c; + q = 1 - d; + + e = 1; + + gp_obs = m/dA; + gy_obs = dA; +end; + +steady; + +check; + +estimated_params; +alp, beta_pdf, 0.356, 0.02; +bet, beta_pdf, 0.993, 0.002; +gam, normal_pdf, 0.0085, 0.003; +mst, normal_pdf, 1.0002, 0.007; +rho, beta_pdf, 0.129, 0.223; +psi, beta_pdf, 0.65, 0.05; +del, beta_pdf, 0.01, 0.005; +stderr e_a, inv_gamma_pdf, 0.035449, inf; +stderr e_m, inv_gamma_pdf, 0.008862, inf; +end; + +varobs gp_obs gy_obs; + +options_.MaxNumberOfBytes=2000*11*8/4; +estimation(order=1, datafile='../fsdat_simul',nobs=192, loglinear, mh_replic=2000, mh_nblocks=2, mh_jscale=0.8); +copyfile([M_.dname filesep 'metropolis' filesep 'fs2000_recover_mh1_blck1.mat'],'fs2000_mh1_blck1.mat') +copyfile([M_.dname filesep 'metropolis' filesep 'fs2000_recover_mh3_blck2.mat'],'fs2000_mh3_blck2.mat') +delete([M_.dname filesep 'metropolis' filesep 'fs2000_recover_mh4_blck2.mat']) + +estimation(order=1, datafile='../fsdat_simul',mode_compute=0,mode_file=fs2000_recover_mode, nobs=192, loglinear, mh_replic=2000, mh_nblocks=2, mh_jscale=0.8,mh_recover); + +%check first unaffected chain +temp1=load('fs2000_mh1_blck1.mat'); +temp2=load([M_.dname filesep 'Metropolis' filesep 'fs2000_recover_mh1_blck1.mat']); + +if max(max(temp1.x2-temp2.x2))>1e-10 + error('Draws of unaffected chain are not the same') +end + +%check second, affected chain with last unaffected file +temp1=load('fs2000_mh3_blck2.mat'); +temp2=load([M_.dname filesep 'Metropolis' filesep 'fs2000_recover_mh3_blck2.mat']); + +if max(max(temp1.x2-temp2.x2))>1e-10 + error('Draws of affected chain''s unaffected files are not the same') +end diff --git a/tests/estimation/t_proposal/fs2000_student.mod b/tests/estimation/t_proposal/fs2000_student.mod new file mode 100644 index 000000000..47c90a403 --- /dev/null +++ b/tests/estimation/t_proposal/fs2000_student.mod @@ -0,0 +1,120 @@ +/* + * This file replicates the estimation of the cash in advance model described + * Frank Schorfheide (2000): "Loss function-based evaluation of DSGE models", + * Journal of Applied Econometrics, 15(6), 645-670. + * + * The data are in file "fsdat_simul.m", and have been artificially generated. + * They are therefore different from the original dataset used by Schorfheide. + * + * The equations are taken from J. Nason and T. Cogley (1994): "Testing the + * implications of long-run neutrality for monetary business cycle models", + * Journal of Applied Econometrics, 9, S37-S70. + * Note that there is an initial minus sign missing in equation (A1), p. S63. + * + * This implementation was written by Michel Juillard. Please note that the + * following copyright notice only applies to this Dynare implementation of the + * model. + */ + +/* + * Copyright (C) 2004-2010 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 . + */ + +var m P c e W R k d n l gy_obs gp_obs y dA; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +dA = exp(gam+e_a); +log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; +-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; +W = l/n; +-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; +R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; +1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; +c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); +P*c = m; +m-1+d = l; +e = exp(e_a); +y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); +gy_obs = dA*y/y(-1); +gp_obs = (P/P(-1))*m(-1)/dA; +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady_state_model; + dA = exp(gam); + gst = 1/dA; + m = mst; + khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); + xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); + nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); + n = xist/(nust+xist); + P = xist + nust; + k = khst*n; + + l = psi*mst*n/( (1-psi)*(1-n) ); + c = mst/P; + d = l - mst + 1; + y = k^alp*n^(1-alp)*gst^alp; + R = mst/bet; + W = l/n; + ist = y-c; + q = 1 - d; + + e = 1; + + gp_obs = m/dA; + gy_obs = dA; +end; + +steady; + +check; + +estimated_params; +alp, beta_pdf, 0.356, 0.02; +bet, beta_pdf, 0.993, 0.002; +gam, normal_pdf, 0.0085, 0.003; +mst, normal_pdf, 1.0002, 0.007; +rho, beta_pdf, 0.129, 0.223; +psi, beta_pdf, 0.65, 0.05; +del, beta_pdf, 0.01, 0.005; +stderr e_a, inv_gamma_pdf, 0.035449, inf; +stderr e_m, inv_gamma_pdf, 0.008862, inf; +end; + +varobs gp_obs gy_obs; + +options_.proposal_distribution='rand_multivariate_student'; +options_.student_degrees_of_freedom=5; + +estimation(order=1, datafile='../fsdat_simul',nobs=192, loglinear, mh_replic=2002, mh_nblocks=2, mh_jscale=0.8,mode_compute=4); diff --git a/tests/fs2000/fs2000_cmaes.mod b/tests/fs2000/fs2000_cmaes.mod deleted file mode 100644 index 5ef75a76b..000000000 --- a/tests/fs2000/fs2000_cmaes.mod +++ /dev/null @@ -1,75 +0,0 @@ -// See fs2000.mod in the examples/ directory for details on the model - -var m P c e W R k d n l gy_obs gp_obs y dA; -varexo e_a e_m; - -parameters alp bet gam mst rho psi del; - -alp = 0.33; -bet = 0.99; -gam = 0.003; -mst = 1.011; -rho = 0.7; -psi = 0.787; -del = 0.02; - -model; -dA = exp(gam+e_a); -log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; --P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -W = l/n; --(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; -1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; -c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); -P*c = m; -m-1+d = l; -e = exp(e_a); -y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); -gy_obs = dA*y/y(-1); -gp_obs = (P/P(-1))*m(-1)/dA; -end; - -initval; -k = 6; -m = mst; -P = 2.25; -c = 0.45; -e = 1; -W = 4; -R = 1.02; -d = 0.85; -n = 0.19; -l = 0.86; -y = 0.6; -gy_obs = exp(gam); -gp_obs = exp(-gam); -dA = exp(gam); -end; - -shocks; -var e_a; stderr 0.014; -var e_m; stderr 0.005; -end; - -steady; - -check; - -estimated_params; -alp, beta_pdf, 0.356, 0.02; -bet, beta_pdf, 0.993, 0.002; -gam, normal_pdf, 0.0085, 0.003; -mst, normal_pdf, 1.0002, 0.007; -rho, beta_pdf, 0.129, 0.223; -psi, beta_pdf, 0.65, 0.05; -del, beta_pdf, 0.01, 0.005; -stderr e_a, inv_gamma_pdf, 0.035449, inf; -stderr e_m, inv_gamma_pdf, 0.008862, inf; -end; - -varobs gp_obs gy_obs; - -options_.solve_tolf = 1e-12; - -estimation(order=1,datafile=fsdat_simul,nobs=192,loglinear,mode_compute=9,mh_replic=0); diff --git a/tests/fs2000/fs2000_mode_compute_8.mod b/tests/fs2000/fs2000_mode_compute_8.mod deleted file mode 100644 index 4f39e10bf..000000000 --- a/tests/fs2000/fs2000_mode_compute_8.mod +++ /dev/null @@ -1,82 +0,0 @@ -// See fs2000.mod in the examples/ directory for details on the model - -var m P c e W R k d n l gy_obs gp_obs y dA; -varexo e_a e_m; - -parameters alp bet gam mst rho psi del; - -alp = 0.33; -bet = 0.99; -gam = 0.003; -mst = 1.011; -rho = 0.7; -psi = 0.787; -del = 0.02; - -model; -dA = exp(gam+e_a); -log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; --P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -W = l/n; --(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; -1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; -c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); -P*c = m; -m-1+d = l; -e = exp(e_a); -y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); -gy_obs = dA*y/y(-1); -gp_obs = (P/P(-1))*m(-1)/dA; -end; - -initval; -k = 6; -m = mst; -P = 2.25; -c = 0.45; -e = 1; -W = 4; -R = 1.02; -d = 0.85; -n = 0.19; -l = 0.86; -y = 0.6; -gy_obs = exp(gam); -gp_obs = exp(-gam); -dA = exp(gam); -end; - -shocks; -var e_a; stderr 0.014; -var e_m; stderr 0.005; -end; - -steady; - -check; - -estimated_params; -alp, beta_pdf, 0.356, 0.02; -bet, beta_pdf, 0.993, 0.002; -gam, normal_pdf, 0.0085, 0.003; -mst, normal_pdf, 1.0002, 0.007; -rho, beta_pdf, 0.129, 0.223; -psi, beta_pdf, 0.65, 0.05; -del, beta_pdf, 0.01, 0.005; -stderr e_a, inv_gamma_pdf, 0.035449, inf; -stderr e_m, inv_gamma_pdf, 0.008862, inf; -end; - -varobs gp_obs gy_obs; - -options_.solve_tolf = 1e-12; - -estimation(order=1,datafile=fsdat_simul,nobs=192,mode_compute=8,loglinear,mh_replic=0,optim=( -'MaxIter',5000, -'TolFun',1e-4, -'TolX',1e-4, -'MaxFunEvals',5000, -'MaxFunEvalFactor',500, -'InitialSimplexSize',0.05 -)); diff --git a/tests/fs2000/fs2000d.mod b/tests/fs2000/fs2000d.mod deleted file mode 100644 index 04f122805..000000000 --- a/tests/fs2000/fs2000d.mod +++ /dev/null @@ -1,75 +0,0 @@ -// See fs2000.mod in the examples/ directory for details on the model - -var m P c e W R k d n l gy_obs gp_obs y dA; -varexo e_a e_m; - -parameters alp bet gam mst rho psi del; - -alp = 0.33; -bet = 0.99; -gam = 0.003; -mst = 1.011; -rho = 0.7; -psi = 0.787; -del = 0.02; - -model; -dA = exp(gam+e_a); -log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; --P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -W = l/n; --(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; -1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; -c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); -P*c = m; -m-1+d = l; -e = exp(e_a); -y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); -gy_obs = dA*y/y(-1); -gp_obs = (P/P(-1))*m(-1)/dA; -end; - -initval; -k = 6; -m = mst; -P = 2.25; -c = 0.45; -e = 1; -W = 4; -R = 1.02; -d = 0.85; -n = 0.19; -l = 0.86; -y = 0.6; -gy_obs = exp(gam); -gp_obs = exp(-gam); -dA = exp(gam); -end; - -shocks; -var e_a; stderr 0.014; -var e_m; stderr 0.005; -end; - -steady; - -check; - -estimated_params; -alp, beta_pdf, 0.356, 0.02; -bet, beta_pdf, 0.993, 0.002; -gam, normal_pdf, 0.0085, 0.003; -mst, normal_pdf, 1.0002, 0.007; -rho, beta_pdf, 0.129, 0.223; -psi, beta_pdf, 0.65, 0.05; -del, beta_pdf, 0.01, 0.005; -stderr e_a, inv_gamma_pdf, 0.035449, inf; -stderr e_m, inv_gamma_pdf, 0.008862, inf; -end; - -varobs gp_obs gy_obs; - -options_.solve_tolf = 1e-12; - -estimation(order=1,datafile=fsdat_simul,nobs=192,mode_compute=5,loglinear,mh_replic=0); diff --git a/tests/fs2000/fs2000e.mod b/tests/fs2000/fs2000e.mod deleted file mode 100644 index 83416a791..000000000 --- a/tests/fs2000/fs2000e.mod +++ /dev/null @@ -1,75 +0,0 @@ -// See fs2000.mod in the examples/ directory for details on the model - -var m P c e W R k d n l gy_obs gp_obs y dA; -varexo e_a e_m; - -parameters alp bet gam mst rho psi del; - -alp = 0.33; -bet = 0.99; -gam = 0.003; -mst = 1.011; -rho = 0.7; -psi = 0.787; -del = 0.02; - -model; -dA = exp(gam+e_a); -log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; --P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; -W = l/n; --(psi/(1-psi))*(c*P/(1-n))+l/n = 0; -R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; -1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; -c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); -P*c = m; -m-1+d = l; -e = exp(e_a); -y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); -gy_obs = dA*y/y(-1); -gp_obs = (P/P(-1))*m(-1)/dA; -end; - -initval; -k = 6; -m = mst; -P = 2.25; -c = 0.45; -e = 1; -W = 4; -R = 1.02; -d = 0.85; -n = 0.19; -l = 0.86; -y = 0.6; -gy_obs = exp(gam); -gp_obs = exp(-gam); -dA = exp(gam); -end; - -shocks; -var e_a; stderr 0.014; -var e_m; stderr 0.005; -end; - -steady; - -check; - -estimated_params; -alp, beta_pdf, 0.356, 0.02; -bet, beta_pdf, 0.993, 0.002; -gam, normal_pdf, 0.0085, 0.003; -mst, normal_pdf, 1.0002, 0.007; -rho, beta_pdf, 0.129, 0.223; -psi, beta_pdf, 0.65, 0.05; -del, beta_pdf, 0.01, 0.005; -stderr e_a, inv_gamma_pdf, 0.035449, inf; -stderr e_m, inv_gamma_pdf, 0.008862, inf; -end; - -varobs gp_obs gy_obs; - -options_.solve_tolf = 1e-12; - -estimation(order=1,datafile=fsdat_simul,nobs=192,optim=('NumgradEpsilon',1e-6,'NumgradAlgorithm',3,'MaxIter',100,'InitialInverseHessian','eye(9)*.0001'),loglinear,mh_replic=0); diff --git a/tests/gsa/ls2003a.mod b/tests/gsa/ls2003a.mod index fcbd9b75c..19d5f88ba 100644 --- a/tests/gsa/ls2003a.mod +++ b/tests/gsa/ls2003a.mod @@ -54,11 +54,18 @@ rho_q ,beta_pdf,0.4,0.2; rho_A ,beta_pdf,0.5,0.2; rho_ys ,beta_pdf,0.8,0.1; rho_pies,beta_pdf,0.7,0.15; -stderr e_R,inv_gamma_pdf,1.2533,0.6551; -stderr e_q,inv_gamma_pdf,2.5066,1.3103; -stderr e_A,inv_gamma_pdf,1.2533,0.6551; -stderr e_ys,inv_gamma_pdf,1.2533,0.6551; -stderr e_pies,inv_gamma_pdf,1.88,0.9827; +/* +stderr e_R,inv_gamma_pdf,(1.2533),(0.6551); +stderr e_q,inv_gamma_pdf,(2.5066),(1.3103); +stderr e_A,inv_gamma_pdf,(1.2533),(0.6551); +stderr e_ys,inv_gamma_pdf,(1.2533),(0.6551); +stderr e_pies,inv_gamma_pdf,(1.88),(0.9827); +*/ +stderr e_R,inv_gamma_pdf,(1.2533/3),(0.6551/10); +stderr e_q,inv_gamma_pdf,(2.5066/3),(1.3103/10); +stderr e_A,inv_gamma_pdf,(1.2533/3),(0.6551/10); +stderr e_ys,inv_gamma_pdf,(1.2533/3),(0.6551/10); +stderr e_pies,inv_gamma_pdf,(1.88/3),(0.9827/10); end; // endogenous prior restrictions @@ -83,12 +90,21 @@ end; moment_calibration; //y_obs,y_obs, [0.8 1.1]; //[unconditional variance] y_obs,y_obs(-(1:4)), +; //[first year acf] -@#for ilag in 0:1 -y_obs,R_obs(-@{ilag}), -; //[ccf] +//y_obs,pie_obs(-4:4), -; //[ccf] +@#for ilag in -2:2 +y_obs,R_obs(@{ilag}), -; //[ccf] +@#endfor +@#for ilag in -4:4 +y_obs,pie_obs(@{ilag}), -; //[ccf] @#endfor end; -dynare_sensitivity(prior_range=0); +if isoctave() + dynare_sensitivity(prior_range=0, nodisplay, graph_format=(eps)); +else + dynare_sensitivity(prior_range=0, nodisplay, graph_format=(fig)); +end + /* estimation(datafile='data_ca1.m',first_obs=8,nobs=79,mh_nblocks=2, mode_file = ls2003a_mode, prefilter=1,mh_jscale=0.5,mh_replic=5000, mode_compute=0, mh_drop=0.6, bayesian_irf); diff --git a/tests/optimizers/fs2000.common.inc b/tests/optimizers/fs2000.common.inc new file mode 100644 index 000000000..b0762753f --- /dev/null +++ b/tests/optimizers/fs2000.common.inc @@ -0,0 +1,133 @@ +/* + * This file replicates the estimation of the cash in advance model described + * Frank Schorfheide (2000): "Loss function-based evaluation of DSGE models", + * Journal of Applied Econometrics, 15(6), 645-670. + * + * The data are in file "fs2000/fsdat_simul.m", and have been artificially generated. + * They are therefore different from the original dataset used by Schorfheide. + * + * The equations are taken from J. Nason and T. Cogley (1994): "Testing the + * implications of long-run neutrality for monetary business cycle models", + * Journal of Applied Econometrics, 9, S37-S70. + * Note that there is an initial minus sign missing in equation (A1), p. S63. + * + * This implementation was written by Michel Juillard. Please note that the + * following copyright notice only applies to this Dynare implementation of the + * model. + */ + +/* + * Copyright (C) 2004-2010 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 . + */ + +var m P c e W R k d n l gy_obs gp_obs y dA; +varexo e_a e_m; + +parameters alp bet gam mst rho psi del; + +alp = 0.33; +bet = 0.99; +gam = 0.003; +mst = 1.011; +rho = 0.7; +psi = 0.787; +del = 0.02; + +model; +dA = exp(gam+e_a); +log(m) = (1-rho)*log(mst) + rho*log(m(-1))+e_m; +-P/(c(+1)*P(+1)*m)+bet*P(+1)*(alp*exp(-alp*(gam+log(e(+1))))*k^(alp-1)*n(+1)^(1-alp)+(1-del)*exp(-(gam+log(e(+1)))))/(c(+2)*P(+2)*m(+1))=0; +W = l/n; +-(psi/(1-psi))*(c*P/(1-n))+l/n = 0; +R = P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(-alp)/W; +1/(c*P)-bet*P*(1-alp)*exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)/(m*l*c(+1)*P(+1)) = 0; +c+k = exp(-alp*(gam+e_a))*k(-1)^alp*n^(1-alp)+(1-del)*exp(-(gam+e_a))*k(-1); +P*c = m; +m-1+d = l; +e = exp(e_a); +y = k(-1)^alp*n^(1-alp)*exp(-alp*(gam+e_a)); +gy_obs = dA*y/y(-1); +gp_obs = (P/P(-1))*m(-1)/dA; +end; + +initval; +k = 6; +m = mst; +P = 2.25; +c = 0.45; +e = 1; +W = 4; +R = 1.02; +d = 0.85; +n = 0.19; +l = 0.86; +y = 0.6; +gy_obs = exp(gam); +gp_obs = exp(-gam); +dA = exp(gam); +end; + +shocks; +var e_a; stderr 0.014; +var e_m; stderr 0.005; +end; + +steady_state_model; + dA = exp(gam); + gst = 1/dA; + m = mst; + khst = ( (1-gst*bet*(1-del)) / (alp*gst^alp*bet) )^(1/(alp-1)); + xist = ( ((khst*gst)^alp - (1-gst*(1-del))*khst)/mst )^(-1); + nust = psi*mst^2/( (1-alp)*(1-psi)*bet*gst^alp*khst^alp ); + n = xist/(nust+xist); + P = xist + nust; + k = khst*n; + + l = psi*mst*n/( (1-psi)*(1-n) ); + c = mst/P; + d = l - mst + 1; + y = k^alp*n^(1-alp)*gst^alp; + R = mst/bet; + W = l/n; + ist = y-c; + q = 1 - d; + + e = 1; + + gp_obs = m/dA; + gy_obs = dA; +end; + +steady; + +check; + +estimated_params; +alp, beta_pdf, 0.356, 0.02; +bet, beta_pdf, 0.993, 0.002; +gam, normal_pdf, 0.0085, 0.003; +mst, normal_pdf, 1.0002, 0.007; +rho, beta_pdf, 0.129, 0.223; +psi, beta_pdf, 0.65, 0.05; +del, beta_pdf, 0.01, 0.005; +stderr e_a, inv_gamma_pdf, 0.035449, inf; +stderr e_m, inv_gamma_pdf, 0.008862, inf; +end; + +varobs gp_obs gy_obs; +options_.plot_priors=0; diff --git a/tests/optimizers/fs2000_1.mod b/tests/optimizers/fs2000_1.mod new file mode 100644 index 000000000..fe3704835 --- /dev/null +++ b/tests/optimizers/fs2000_1.mod @@ -0,0 +1,5 @@ +@#include "fs2000.common.inc" + +if ~isoctave() && exist('fmincon','file') + estimation(mode_compute=1,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); +end diff --git a/tests/optimizers/fs2000_10.mod b/tests/optimizers/fs2000_10.mod new file mode 100644 index 000000000..d46ef9d85 --- /dev/null +++ b/tests/optimizers/fs2000_10.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=10,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_101.mod b/tests/optimizers/fs2000_101.mod new file mode 100644 index 000000000..d301ecd18 --- /dev/null +++ b/tests/optimizers/fs2000_101.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=101,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_102.mod b/tests/optimizers/fs2000_102.mod new file mode 100644 index 000000000..e43dcb254 --- /dev/null +++ b/tests/optimizers/fs2000_102.mod @@ -0,0 +1,5 @@ +@#include "fs2000.common.inc" + +if ~isoctave() && exist('simulannealbnd','file') + estimation(mode_compute=102,mode_file=fs2000_mode,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0, mh_nblocks=2, mh_jscale=0.8); +end diff --git a/tests/optimizers/fs2000_2.mod b/tests/optimizers/fs2000_2.mod new file mode 100644 index 000000000..bfd38c7c4 --- /dev/null +++ b/tests/optimizers/fs2000_2.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=2,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_3.mod b/tests/optimizers/fs2000_3.mod new file mode 100644 index 000000000..5efc98d2a --- /dev/null +++ b/tests/optimizers/fs2000_3.mod @@ -0,0 +1,5 @@ +@#include "fs2000.common.inc" + +if exist('fminunc','file') + estimation(mode_compute=3,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); +end diff --git a/tests/optimizers/fs2000_4.mod b/tests/optimizers/fs2000_4.mod new file mode 100644 index 000000000..c500afa7f --- /dev/null +++ b/tests/optimizers/fs2000_4.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=4,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_4_with_optim.mod b/tests/optimizers/fs2000_4_with_optim.mod new file mode 100644 index 000000000..ecb4254ed --- /dev/null +++ b/tests/optimizers/fs2000_4_with_optim.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=4,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0,optim=('NumgradEpsilon',1e-6,'NumgradAlgorithm',3,'MaxIter',100,'InitialInverseHessian','eye(9)*.0001')); \ No newline at end of file diff --git a/tests/optimizers/fs2000_5.mod b/tests/optimizers/fs2000_5.mod new file mode 100644 index 000000000..16fdd957e --- /dev/null +++ b/tests/optimizers/fs2000_5.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=5,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_6.mod b/tests/optimizers/fs2000_6.mod new file mode 100644 index 000000000..7bd0673a7 --- /dev/null +++ b/tests/optimizers/fs2000_6.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=6,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_7.mod b/tests/optimizers/fs2000_7.mod new file mode 100644 index 000000000..3a58b5fa2 --- /dev/null +++ b/tests/optimizers/fs2000_7.mod @@ -0,0 +1,5 @@ +@#include "fs2000.common.inc" + +if exist('fminsearch','file') + estimation(mode_compute=7,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); +end diff --git a/tests/optimizers/fs2000_8.mod b/tests/optimizers/fs2000_8.mod new file mode 100644 index 000000000..f7415df12 --- /dev/null +++ b/tests/optimizers/fs2000_8.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=8,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_8_with_optim.mod b/tests/optimizers/fs2000_8_with_optim.mod new file mode 100644 index 000000000..c166d7047 --- /dev/null +++ b/tests/optimizers/fs2000_8_with_optim.mod @@ -0,0 +1,11 @@ +@#include "fs2000.common.inc" + +options_.solve_tolf = 1e-12; +estimation(mode_compute=8,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0,optim=( +'MaxIter',5000, +'TolFun',1e-4, +'TolX',1e-4, +'MaxFunEvals',5000, +'MaxFunEvalFactor',500, +'InitialSimplexSize',0.05 +)); diff --git a/tests/optimizers/fs2000_9.mod b/tests/optimizers/fs2000_9.mod new file mode 100644 index 000000000..96d75bf96 --- /dev/null +++ b/tests/optimizers/fs2000_9.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=9,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/fs2000_w.mod b/tests/optimizers/fs2000_w.mod new file mode 100644 index 000000000..73f6bdc62 --- /dev/null +++ b/tests/optimizers/fs2000_w.mod @@ -0,0 +1,3 @@ +@#include "fs2000.common.inc" + +estimation(mode_compute=optimizer_function_wrapper,order=1, datafile='../fs2000/fsdat_simul', nobs=192, mh_replic=0); diff --git a/tests/optimizers/optimizer_function_wrapper.m b/tests/optimizers/optimizer_function_wrapper.m new file mode 100644 index 000000000..a7992bab3 --- /dev/null +++ b/tests/optimizers/optimizer_function_wrapper.m @@ -0,0 +1,16 @@ +function [opt_par_values,fval,exitflag]=optimizer_function_wrapper(objective_function_handle,start_par_value,varargin) +% function [opt_par_values,fval,exitflag]=optimizer_function_wrapper(objective_function_handle,start_par_value,varargin) +% Demonstrates how to invoke external optimizer for mode_computation + +%set options of optimizer +H0 = 1e-4*eye(length(start_par_value),length(start_par_value)); +nit=1000; +crit = 1e-7; +numgrad = 2; +epsilon = 1e-6; +analytic_grad=[]; + +%call optimizer +[fval,opt_par_values,grad,hessian_mat,itct,fcount,exitflag] = ... + csminwel1(objective_function_handle, start_par_value, H0, analytic_grad, crit, nit, numgrad, epsilon, varargin{:}); +end \ No newline at end of file diff --git a/tests/pi2004/ireland.mod b/tests/pi2004/ireland.mod index ea17baad3..4c6552bde 100644 --- a/tests/pi2004/ireland.mod +++ b/tests/pi2004/ireland.mod @@ -87,4 +87,4 @@ oy (log(eta)); oc (log(eta)); end; -estimation(datafile=idata,mode_compute=1,nograph); \ No newline at end of file +estimation(datafile=idata,mode_compute=1,nograph,dirname='MYDIR/mysubdir'); \ No newline at end of file diff --git a/tests/recursive/ls2003_bayesian_xls.mod b/tests/recursive/ls2003_bayesian_xls.mod new file mode 100644 index 000000000..c0b048a60 --- /dev/null +++ b/tests/recursive/ls2003_bayesian_xls.mod @@ -0,0 +1,72 @@ +if ~isoctave() && ~matlab_ver_less_than('8.4') + websave('data_ca1_xls.xlsx','http://www.dynare.org/Datasets/data_ca1_xls.xlsx') +else + urlwrite('http://www.dynare.org/Datasets/data_ca1_xls.xlsx','data_ca1_xls.xlsx') +end + +var y y_s R pie dq pie_s de A y_obs pie_obs R_obs; +varexo e_R e_q e_ys e_pies e_A; + +parameters psi1 psi2 psi3 rho_R tau alpha rr k rho_q rho_A rho_ys rho_pies; + +psi1 = 1.54; +psi2 = 0.25; +psi3 = 0.25; +rho_R = 0.5; +alpha = 0.3; +rr = 2.51; +k = 0.5; +tau = 0.5; +rho_q = 0.4; +rho_A = 0.2; +rho_ys = 0.9; +rho_pies = 0.7; + + +model(linear); +y = y(+1) - (tau +alpha*(2-alpha)*(1-tau))*(R-pie(+1))-alpha*(tau +alpha*(2-alpha)*(1-tau))*dq(+1) + alpha*(2-alpha)*((1-tau)/tau)*(y_s-y_s(+1))-A(+1); +pie = exp(-rr/400)*pie(+1)+alpha*exp(-rr/400)*dq(+1)-alpha*dq+(k/(tau+alpha*(2-alpha)*(1-tau)))*y+alpha*(2-alpha)*(1-tau)/(tau*(tau+alpha*(2-alpha)*(1-tau)))*y_s; +pie = de+(1-alpha)*dq+pie_s; +R = rho_R*R(-1)+(1-rho_R)*(psi1*pie+psi2*(y+alpha*(2-alpha)*((1-tau)/tau)*y_s)+psi3*de)+e_R; +dq = rho_q*dq(-1)+e_q; +y_s = rho_ys*y_s(-1)+e_ys; +pie_s = rho_pies*pie_s(-1)+e_pies; +A = rho_A*A(-1)+e_A; +y_obs = y-y(-1)+A; +pie_obs = 4*pie; +R_obs = 4*R; +end; + +shocks; +var e_R = 1.25^2; +var e_q = 2.5^2; +var e_A = 1.89; +var e_ys = 1.89; +var e_pies = 1.89; +end; + +varobs y_obs R_obs pie_obs dq de; + +estimated_params; +psi1 , gamma_pdf,1.5,0.5; +psi2 , gamma_pdf,0.25,0.125; +psi3 , gamma_pdf,0.25,0.125; +rho_R ,beta_pdf,0.5,0.2; +alpha ,beta_pdf,0.3,0.1; +rr ,gamma_pdf,2.5,1; +k , gamma_pdf,0.5,0.25; +tau ,gamma_pdf,0.5,0.2; +rho_q ,beta_pdf,0.4,0.2; +rho_A ,beta_pdf,0.5,0.2; +rho_ys ,beta_pdf,0.8,0.1; +rho_pies,beta_pdf,0.7,0.15; +stderr e_R,inv_gamma_pdf,1.2533,0.6551; +stderr e_q,inv_gamma_pdf,2.5066,1.3103; +stderr e_A,inv_gamma_pdf,1.2533,0.6551; +stderr e_ys,inv_gamma_pdf,1.2533,0.6551; +stderr e_pies,inv_gamma_pdf,1.88,0.9827; +end; + +estimation(datafile=data_ca1_xls,first_obs=8,nobs=[76 79],mh_nblocks=1,prefilter=1,mh_jscale=0.5,mh_replic=2000,forecast=8) y_obs R_obs pie_obs dq de; + +delete('data_ca1_xls.xlsx') diff --git a/tests/reporting/runDynareReport.m b/tests/reporting/runDynareReport.m index c1c48311f..61057946b 100644 --- a/tests/reporting/runDynareReport.m +++ b/tests/reporting/runDynareReport.m @@ -257,26 +257,46 @@ rep = rep.addSeries('graphHline', 460, ... 'graphLineColor', 'red', ... 'graphLineWidth', 1.5); +a=dseries([1:200]', '1984q1'); +b=a; +c=a; +d=a; +b(dates('2012q2'):dates('2015q2'))=b(dates('2012q2'):dates('2015q2'))+2; +c(dates('2012q2'):dates('2015q2'))=c(dates('2012q2'):dates('2015q2'))+4; +d(dates('2012q2'):dates('2015q2'))=d(dates('2012q2'):dates('2015q2'))+6; rep = rep.addGraph('title', 'Equilibrium World Real Food Price', ... 'xrange', prange, ... 'shade', srange, ... 'showLegend', true, ... 'xTickLabelRotation', 0); -rep = rep.addSeries('data', db_q{'LRPFOOD_BAR_WORLD'}, ... +rep = rep.addSeries('data', a, ... 'graphLineColor', 'blue', ... 'graphLineWidth', 1.5, ... 'graphLegendName', 'baseline', ... 'graphMiscTikzAddPlotOptions', 'mark=halfcircle*,color=red'); -rep = rep.addSeries('data', dc_q{'LRPFOOD_BAR_WORLD'}, ... +rep = rep.addSeries('data', b, ... 'graphLineColor', 'blue', ... 'graphLineStyle', 'dashed', ... 'graphLineWidth', 1.5, ... 'graphLegendName', 'control', ... - 'graphMiscTikzAddPlotOptions', 'mark=halfcircle*,mark options={rotate=90,scale=3}'); + 'graphMiscTikzAddPlotOptions', 'mark=halfcircle*,mark options={rotate=90,scale=3}', ... + 'graphFanShadeColor', 'red', 'graphFanShadeOpacity', 40); +rep = rep.addSeries('data', c, ... + 'graphLineColor', 'blue', ... + 'graphLineStyle', 'dashed', ... + 'graphLineWidth', 1.5, ... + 'graphLegendName', 'control', .... + 'graphFanShadeColor', 'red', 'graphFanShadeOpacity', 30); +rep = rep.addSeries('data', d, ... + 'graphLineColor', 'blue', ... + 'graphLineStyle', 'dashed', ... + 'graphLineWidth', 1.5, ... + 'graphLegendName', 'control', ... + 'graphFanShadeColor', 'red', 'graphFanShadeOpacity', 20); %% Write & Compile Report rep.write(); rep.compile(); toc -end \ No newline at end of file +end