diff --git a/contrib/ms-sbvar/switch_dw b/contrib/ms-sbvar/switch_dw
index ed0942d17..29c446f7f 160000
--- a/contrib/ms-sbvar/switch_dw
+++ b/contrib/ms-sbvar/switch_dw
@@ -1 +1 @@
-Subproject commit ed0942d17510fcc561e45d16c0e7a59f5646e597
+Subproject commit 29c446f7fe8a773860ebee347662c4ae2494c5e9
diff --git a/doc/dynare.texi b/doc/dynare.texi
index 3ce0fb5f8..6ebe67ba0 100644
--- a/doc/dynare.texi
+++ b/doc/dynare.texi
@@ -8240,7 +8240,7 @@ command. Default: @code{`!'}
@end table
@end defmethod
-@defmethod Report addGraph data, figname, showGrid, showLegend, showLegendBox, legendLocation, legendOrientation, legendFontSize, seriesToUse, shade, shadeColor, shadeOpacity, title, xlabel, ylabel, xrange, yrange, showZeroline
+@defmethod Report addGraph data, figname, graphSize, showGrid, showLegend, showLegendBox, legendLocation, legendOrientation, legendFontSize, seriesToUse, shade, shadeColor, shadeOpacity, title, xlabel, ylabel, xrange, xTickLabels, yrange, showZeroline
Adds a @code{Graph} to a @code{Section}.
@optionshead
@table @code
@@ -8253,6 +8253,12 @@ The @code{dynSeries} that provides the data for the graph. Default:
The name to use when saving this figure. Default: @code{[tempname
`.tex']}
+@item graphSize, @code{NUMERICAL_VECTOR}
+The width and height to be passed to the third and fourth elements of
+the array passed to the @code{`Position'} option of Matlab's
+@code{figure} command, passed as a vector of size @math{2}. Default:
+Matlab sets width and height
+
@item showGrid, @code{BOOLEAN}
Whether or not to display the minor grid on the graph. Default:
@code{true}
@@ -8303,6 +8309,10 @@ The y-axis label. Default: @code{none}
@item xrange, @code{dynDates}
The boundary on the x-axis to display in the graph. Default: all
+@item xTickLabels, @code{CELL_ARRAY_STRINGS}
+The labels to use for the xticks in the graph. Default: the dates of
+the @code{dynSeries}
+
@item yrange, @code{NUMERICAL_VECTOR}
The boundary on the y-axis to display in the graph, represented as a
@code{NUMERICAL_VECTOR} of size @math{2}, with the first entry less
@@ -8349,7 +8359,7 @@ Whether or not to show vertical lines separating the columns. Default: @code{fal
@end defmethod
@anchor{addSeries}
-@defmethod Report addSeries data, graphLineColor, graphLineStyle, graphLineWidth, graphMarker, graphMarkerEdgeColor, graphMarkerFaceColor, graphMarkerSize, tableShowMarkers, tableAlignRight, tableNegColor, tablePosColor
+@defmethod Report addSeries data, graphLineColor, graphLineStyle, graphLineWidth, graphMarker, graphMarkerEdgeColor, graphMarkerFaceColor, graphMarkerSize, tableShowMarkers, tableAlignRight, tableNegColor, tablePosColor, zerotol
Adds a @code{Series} to a @code{Graph} or a @code{Table}.
@optionshead
@table @code
@@ -8403,6 +8413,11 @@ zero. Default: @code{`red'}
The color to use when marking Table data that is greater than
zero. Default: @code{`blue'}
+@item zerotol, @code{DOUBLE}
+The zero tolerance. Anything smaller than @code{zerotol} and larger
+than @code{-zerotol} will be set to zero before being
+graphed. Default: @math{1e-6}
+
@end table
@end defmethod
diff --git a/matlab/@dynDates/subsref.m b/matlab/@dynDates/subsref.m
index b1ac3a4b0..65cc3c354 100644
--- a/matlab/@dynDates/subsref.m
+++ b/matlab/@dynDates/subsref.m
@@ -72,7 +72,7 @@ switch S(1).type
if isint(S(1).subs{1}) && S(1).subs{1}>0 && S(1).subs{1}<=A.ndat
B = dynDate(A.time(S(1).subs{1},:),A.freq);
else
- error(['dynDates::subsref: the index have to be a positive integer less than or equal to ' int2str(A.ndat) '!'])
+ error(['dynDates::subsref: the index has to be a positive integer less than or equal to ' int2str(A.ndat) '!'])
end
else
if isvector(S(1).subs{1}) && all(isint(S(1).subs{1})) && all(S(1).subs{1}>0) && all(S(1).subs{1}<=A.ndat)
@@ -81,7 +81,7 @@ switch S(1).type
B.time = A.time(S(1).subs{1},:);
B.ndat = length(S(1).subs{1});
else
- error(['dynDates::subsref: indices have to be a vector of positive integers less than or equal to ' int2str(A.ndat) '!'])
+ error(['dynDates::subsref: indices has to be a vector of positive integers less than or equal to ' int2str(A.ndat) '!'])
end
end
otherwise
diff --git a/matlab/@dynSeries/minus.m b/matlab/@dynSeries/minus.m
index 3154a9f32..52bb647a8 100644
--- a/matlab/@dynSeries/minus.m
+++ b/matlab/@dynSeries/minus.m
@@ -40,6 +40,41 @@ function A = minus(B,C)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see .
+if isnumeric(B) && isreal(B) && isequal(length(B),1) && isa(C,'dynSeries')
+ keyboard
+ A = dynSeries();
+ A.freq = C.freq;
+ A.init = C.init;
+ A.time = C.time;
+ A.nobs = C.nobs;
+ A.vobs = C.vobs;
+ A.name = cell(A.vobs,1);
+ A.tex = cell(A.vobs,1);
+ for i=1:A.vobs
+ A.name(i) = {['minus(' num2str(B) ',' C.name{i} ')']};
+ A.tex(i) = {['(' num2str(B) '-' C.tex{i} ')']};
+ end
+ A.data = bsxfun(@minus, B, C.data);
+ return;
+end
+
+if isnumeric(C) && isreal(C) && isequal(length(C),1) && isa(B,'dynSeries')
+ A = dynSeries();
+ A.freq = B.freq;
+ A.init = B.init;
+ A.time = B.time;
+ A.nobs = B.nobs;
+ A.vobs = B.vobs;
+ A.name = cell(A.vobs,1);
+ A.tex = cell(A.vobs,1);
+ for i=1:A.vobs
+ A.name(i) = {['minus(' B.name{i} ',' num2str(C) ')']};
+ A.tex(i) = {['(' B.tex{i} '-' num2str(C) ')']};
+ end
+ A.data = bsxfun(@minus, B.data, C);
+ return;
+end
+
if ~isequal(B.vobs,C.vobs) && ~(isequal(B.vobs,1) || isequal(C.vobs,1))
error(['dynSeries::minus: Cannot substract ' inputname(1) ' and ' inputname(2) ' (wrong number of variables)!'])
else
diff --git a/matlab/@dynSeries/plus.m b/matlab/@dynSeries/plus.m
index 165039fc0..9ab3e58e7 100644
--- a/matlab/@dynSeries/plus.m
+++ b/matlab/@dynSeries/plus.m
@@ -40,6 +40,36 @@ function A = plus(B,C)
% You should have received a copy of the GNU General Public License
% along with Dynare. If not, see .
+if isscalar(B)
+ assert(isa(C, 'dynSeries'));
+ b(1:size(C)) = B;
+ BB = dynSeries(b, C.time(1));
+ BB.freq = C.freq;
+ BB.time = C.time;
+ BB.nobs = C.nobs;
+ BB.vobs = C.vobs;
+ BB.name = cell(BB.vobs,1);
+ BB.tex = cell(BB.vobs,1);
+ BB.name(1) = {num2str(B)};
+ A = BB + C;
+ return;
+end
+
+if isscalar(C)
+ assert(isa(B, 'dynSeries'));
+ c(1:size(C)) = C;
+ CC = dynSeries(C, B.time(1));
+ CC.freq = B.freq;
+ CC.time = B.time;
+ CC.nobs = B.nobs;
+ CC.vobs = B.vobs;
+ CC.name = cell(CC.vobs,1);
+ CC.tex = cell(CC.vobs,1);
+ CC.name(1) = {num2str(C)};
+ A = B + CC;
+ return;
+end
+
if ~isequal(B.vobs,C.vobs) && ~(isequal(B.vobs,1) || isequal(C.vobs,1))
error(['dynSeries::plus: Cannot add ' inputname(1) ' and ' inputname(2) ' (wrong number of variables)!'])
else
diff --git a/matlab/dynare_solve.m b/matlab/dynare_solve.m
index 613b01112..744a4734e 100644
--- a/matlab/dynare_solve.m
+++ b/matlab/dynare_solve.m
@@ -48,10 +48,10 @@ if jacobian_flag
fprintf('\nSTEADY: The Jacobian contains Inf or NaN. The problem arises from: \n\n')
for ii=1:length(infrow)
if infcol(ii)<=M.orig_endo_nbr
- fprintf('STEADY: Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n',infrow(ii),M.endo_names(infcol(ii),:),M.endo_names(infcol(ii),:),x(infcol(ii)))
+ fprintf('STEADY: Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n',infrow(ii),deblank(M.endo_names(infcol(ii),:)),deblank(M.endo_names(infcol(ii),:)),x(infcol(ii)))
else %auxiliary vars
orig_var_index=M.aux_vars(1,infcol(ii)-M.orig_endo_nbr).orig_index;
- fprintf('STEADY: Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n',infrow(ii),M.endo_names(orig_var_index,:),M.endo_names(orig_var_index,:),x(infcol(ii)))
+ fprintf('STEADY: Derivative of Equation %d with respect to Variable %s (initial value of %s: %g) \n',infrow(ii),deblank(M.endo_names(orig_var_index,:)),deblank(M.endo_names(orig_var_index,:)),x(infcol(ii)))
end
end
fprintf('\nSTEADY: The problem most often occurs, because a variable with\n')
diff --git a/matlab/lnsrch1.m b/matlab/lnsrch1.m
index ef63f44d5..80af34462 100644
--- a/matlab/lnsrch1.m
+++ b/matlab/lnsrch1.m
@@ -50,6 +50,24 @@ x = xold;
nn = length(j2);
summ = sqrt(sum(p.*p)) ;
if ~isfinite(summ)
+ eq_number_string=[];
+ for ii=1:length(j1)-1
+ eq_number_string=[eq_number_string, num2str(j1(ii)), ', '];
+ end
+ eq_number_string=[eq_number_string, num2str(j1(end))];
+ var_string=[];
+ Model=evalin('base','M_');
+ for ii=1:length(j2)-1
+ var_string=[var_string, deblank(Model.endo_names(j2(ii),:)), ', '];
+ end
+ var_string=[var_string, deblank(Model.endo_names(j2(end),:))];
+ fprintf('\nAn infinite element was encountered when trying to solve equation(s) %s \n',eq_number_string)
+ fprintf('with respect to the variable(s): %s.\n',var_string)
+ fprintf('The values of the endogenous variables when the problem was encountered were:\n')
+ for ii=1:length(xold)
+ fprintf('%-s % 8.4g \n',Model.endo_names(ii,:),xold(ii));
+ end
+ skipline();
error(['Some element of Newton direction isn''t finite. Jacobian maybe' ...
' singular or there is a problem with initial values'])
end
diff --git a/matlab/reports/@graph/createGraph.m b/matlab/reports/@graph/createGraph.m
index 69e73c4f1..48f1c3771 100755
--- a/matlab/reports/@graph/createGraph.m
+++ b/matlab/reports/@graph/createGraph.m
@@ -38,7 +38,11 @@ if ~o.seriesElements.numSeriesElements()
return;
end
-h = figure('visible','off');
+if isempty(o.graphSize)
+ h = figure('visible','off');
+else
+ h = figure('visible','off','position',[1, 1, o.graphSize(1), o.graphSize(2)]);
+end
hold on;
box on;
if o.showGrid
@@ -94,15 +98,19 @@ if ~isempty(o.shade)
set(gca, 'children', children);
end
-xticks = get(gca, 'XTick');
-xTickLabels = cell(1, length(xticks));
-for i=1:length(xticks)
- if xticks(i) >= x(1) && ...
- xticks(i) <= x(end)
- xTickLabels{i} = xlabels{xticks(i)};
- else
- xTickLabels{i} = '';
+if isempty(o.xTickLabels)
+ xticks = get(gca, 'XTick');
+ xTickLabels = cell(1, length(xticks));
+ for i=1:length(xticks)
+ if xticks(i) >= x(1) && ...
+ xticks(i) <= x(end)
+ xTickLabels{i} = xlabels{xticks(i)};
+ else
+ xTickLabels{i} = '';
+ end
end
+else
+ xTickLabels = o.xTickLabels;
end
set(gca, 'XTickLabel', xTickLabels);
diff --git a/matlab/reports/@graph/graph.m b/matlab/reports/@graph/graph.m
index a92003b12..72273c7f9 100644
--- a/matlab/reports/@graph/graph.m
+++ b/matlab/reports/@graph/graph.m
@@ -59,6 +59,9 @@ o.legendFontSize = 8;
o.showZeroline = false;
+o.graphSize = [];
+o.xTickLabels = {};
+
if nargin == 1
assert(isa(varargin{1}, 'graph'),['@graph.graph: with one arg you ' ...
'must pass a graph object']);
@@ -127,6 +130,11 @@ assert(isempty(o.data) || isa(o.data, 'dynSeries'), ['@graph.graph: data must '
assert(isempty(o.seriesToUse) || iscellstr(o.seriesToUse), ['@graph.graph: ' ...
'series to use must be a cell array of string(s)']);
+assert(isempty(o.graphSize) || ((isfloat(o.graphSize) && length(o.graphSize) == 2)),...
+ ['@graph.graph: graphSize is specified as an array with two float ' ...
+ 'entries, [width height]']);
+assert(iscellstr(o.xTickLabels), ...
+ '@graph.graph: xTickLabels must be a cell array of strings');
% using o.seriesToUse, create series objects and put them in o.seriesElements
if ~isempty(o.data)
if isempty(o.seriesToUse)
diff --git a/matlab/reports/@series/getLine.m b/matlab/reports/@series/getLine.m
index c1f61c61c..829bf8222 100644
--- a/matlab/reports/@series/getLine.m
+++ b/matlab/reports/@series/getLine.m
@@ -60,6 +60,9 @@ assert(~(strcmp(o.graphLineStyle, 'none') && isempty(o.graphMarker)), ['@series.
% Validate xrange
assert(isempty(xrange) || isa(xrange, 'dynDates'));
+% Zero tolerance
+assert(isfloat(o.zerotol), '@series.write: zerotol must be a float');
+
%%
if isempty(xrange) || xrange == o.data.time
ds = o.data;
@@ -67,8 +70,18 @@ else
ds = o.data(xrange);
end
-opt = {'XData', 1:length(ds.data)};
-opt = {opt{:}, 'YData', ds.data};
+% if graphing data that is within zerotol, set to zero, create series and
+% get line:
+thedata = ds.data;
+stz = bsxfun(@and, ...
+ bsxfun(@lt, thedata, o.zerotol), ...
+ bsxfun(@gt, thedata, -o.zerotol));
+if any(stz)
+ thedata(stz) = 0;
+end
+
+opt = {'XData', 1:length(thedata)};
+opt = {opt{:}, 'YData', thedata};
opt = {opt{:}, 'Color', o.graphLineColor};
opt = {opt{:}, 'LineStyle', o.graphLineStyle};
diff --git a/matlab/reports/@series/series.m b/matlab/reports/@series/series.m
index cf6f2db9a..6493dced7 100644
--- a/matlab/reports/@series/series.m
+++ b/matlab/reports/@series/series.m
@@ -51,6 +51,8 @@ o.tableMarkerLimit = 1e-4;
o.tableAlignRight = false;
+o.zerotol = 1e-6;
+
if nargin == 1
assert(isa(varargin{1}, 'series'),['@series.series: with one arg you ' ...
'must pass a series object']);
diff --git a/matlab/simul.m b/matlab/simul.m
index 007a0d77b..c9fb8f896 100644
--- a/matlab/simul.m
+++ b/matlab/simul.m
@@ -79,6 +79,22 @@ end
options_.scalv= 1 ;
+if options_.debug
+ model_static = str2func([M_.fname,'_static']);
+ for ii=1:size(oo_.exo_simul,1)
+ [residual(:,ii)] = model_static(oo_.steady_state, oo_.exo_simul(ii,:),M_.params);
+ end
+ problematic_periods=find(any(isinf(residual)) | any(isnan(residual)))-M_.maximum_endo_lag;
+ if ~isempty(problematic_periods)
+ period_string=num2str(problematic_periods(1));
+ for ii=2:length(problematic_periods)
+ period_string=[period_string, ', ', num2str(problematic_periods(ii))];
+ end
+ fprintf('\n\nWARNING: Value for the exogenous variable(s) in period(s) %s inconsistent with the static model.\n',period_string);
+ fprintf('WARNING: Check for division by 0.\n')
+ end
+end
+
if(options_.block)
if(options_.bytecode)
[info, oo_.endo_simul] = bytecode('dynamic');