dynare/matlab/@dprior/dprior.m

214 lines
7.3 KiB
Matlab

classdef dprior < handle
% Copyright © 2023 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 <https://www.gnu.org/licenses/>.
properties
p1 = []; % Prior mean.
p2 = []; % Prior stddev.
p3 = []; % Lower bound of the prior support.
p4 = []; % Upper bound of the prior support.
p5 = []; % Prior mode.
p6 = []; % Prior first hyperparameter.
p7 = []; % Prior second hyperparameter.
p11 = []; % Prior median
lb = []; % Truncated prior lower bound.
ub = []; % Truncated prior upper bound.
name = {}; % Name of the parameter
iduniform = []; % Index for the uniform priors.
idgaussian = []; % Index for the gaussian priors.
idgamma = []; % Index for the gamma priors.
idbeta = []; % Index for the beta priors.
idinvgamma1 = []; % Index for the inverse gamma type 1 priors.
idinvgamma2 = []; % Index for the inverse gamma type 2 priors.
idweibull = []; % Index for the weibull priors.
isuniform = false;
isgaussian = false;
isgamma = false;
isbeta = false;
isinvgamma1 = false;
isinvgamma2 = false;
isweibull = false;
end
methods
function o = dprior(bayestopt_, PriorTrunc, Uniform)
% Class constructor.
%
% INPUTS
% - bayestopt_ [struct] Informations about the prior distribution, aka bayestopt_.
% - PriorTrunc [double] scalar, probability mass to be excluded, aka options_.prior_trunc
% - Uniform [logical] scalar, produce uniform random deviates on the prior support.
%
% OUTPUTS
% - o [dprior] scalar, prior object.
%
% REQUIREMENTS
% None.
if ~nargin % Empty object
return
end
if isfield(bayestopt_, 'p1'), o.p1 = bayestopt_.p1; end
if isfield(bayestopt_, 'p2'), o.p2 = bayestopt_.p2; end
if isfield(bayestopt_, 'p3'), o.p3 = bayestopt_.p3; end
if isfield(bayestopt_, 'p4'), o.p4 = bayestopt_.p4; end
if isfield(bayestopt_, 'p5'), o.p5 = bayestopt_.p5; end
if isfield(bayestopt_, 'p6'), o.p6 = bayestopt_.p6; end
if isfield(bayestopt_, 'p7'), o.p7 = bayestopt_.p7; end
if isfield(bayestopt_, 'p11'), o.p11 = bayestopt_.p11; end
bounds = prior_bounds(bayestopt_, PriorTrunc);
o.lb = bounds.lb;
o.ub = bounds.ub;
if nargin>2 && Uniform
prior_shape = repmat(5, length(o.p6), 1);
else
prior_shape = bayestopt_.pshape;
end
o.idbeta = find(prior_shape==1);
if ~isempty(o.idbeta)
o.isbeta = true;
end
o.idgamma = find(prior_shape==2);
if ~isempty(o.idgamma)
o.isgamma = true;
end
o.idgaussian = find(prior_shape==3);
if ~isempty(o.idgaussian)
o.isgaussian = true;
end
o.idinvgamma1 = find(prior_shape==4);
if ~isempty(o.idinvgamma1)
o.isinvgamma1 = true;
end
o.iduniform = find(prior_shape==5);
if ~isempty(o.iduniform)
o.isuniform = true;
end
o.idinvgamma2 = find(prior_shape==6);
if ~isempty(o.idinvgamma2)
o.isinvgamma2 = true;
end
o.idweibull = find(prior_shape==8);
if ~isempty(o.idweibull)
o.isweibull = true;
end
end % dprior (constructor)
end % methods
end % classdef --*-- Unit tests --*--
%@test:1
%$ % Fill global structures with required fields...
%$ prior_trunc = 1e-10;
%$ p0 = repmat([1; 2; 3; 4; 5; 6; 8], 2, 1); % Prior shape
%$ p1 = .4*ones(14,1); % Prior mean
%$ p2 = .2*ones(14,1); % Prior std.
%$ p3 = NaN(14,1);
%$ p4 = NaN(14,1);
%$ p5 = NaN(14,1);
%$ p6 = NaN(14,1);
%$ p7 = NaN(14,1);
%$
%$ for i=1:14
%$ switch p0(i)
%$ case 1
%$ % Beta distribution
%$ p3(i) = 0;
%$ p4(i) = 1;
%$ [p6(i), p7(i)] = beta_specification(p1(i), p2(i)^2, p3(i), p4(i));
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 1);
%$ case 2
%$ % Gamma distribution
%$ p3(i) = 0;
%$ p4(i) = Inf;
%$ [p6(i), p7(i)] = gamma_specification(p1(i), p2(i)^2, p3(i), p4(i));
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 2);
%$ case 3
%$ % Normal distribution
%$ p3(i) = -Inf;
%$ p4(i) = Inf;
%$ p6(i) = p1(i);
%$ p7(i) = p2(i);
%$ p5(i) = p1(i);
%$ case 4
%$ % Inverse Gamma (type I) distribution
%$ p3(i) = 0;
%$ p4(i) = Inf;
%$ [p6(i), p7(i)] = inverse_gamma_specification(p1(i), p2(i)^2, p3(i), 1, false);
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 4);
%$ case 5
%$ % Uniform distribution
%$ [p1(i), p2(i), p6(i), p7(i)] = uniform_specification(p1(i), p2(i), p3(i), p4(i));
%$ p3(i) = p6(i);
%$ p4(i) = p7(i);
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 5);
%$ case 6
%$ % Inverse Gamma (type II) distribution
%$ p3(i) = 0;
%$ p4(i) = Inf;
%$ [p6(i), p7(i)] = inverse_gamma_specification(p1(i), p2(i)^2, p3(i), 2, false);
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 6);
%$ case 8
%$ % Weibull distribution
%$ p3(i) = 0;
%$ p4(i) = Inf;
%$ [p6(i), p7(i)] = weibull_specification(p1(i), p2(i)^2, p3(i));
%$ p5(i) = compute_prior_mode([p6(i) p7(i)], 8);
%$ otherwise
%$ error('This density is not implemented!')
%$ end
%$ end
%$
%$ bayestopt_.pshape = p0;
%$ bayestopt_.p1 = p1;
%$ bayestopt_.p2 = p2;
%$ bayestopt_.p3 = p3;
%$ bayestopt_.p4 = p4;
%$ bayestopt_.p5 = p5;
%$ bayestopt_.p6 = p6;
%$ bayestopt_.p7 = p7;
%$
%$ ndraws = 1e5;
%$ m0 = bayestopt_.p1; %zeros(14,1);
%$ v0 = diag(bayestopt_.p2.^2); %zeros(14);
%$
%$ % Call the tested routine
%$ try
%$ % Instantiate dprior object
%$ o = dprior(bayestopt_, prior_trunc, false);
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ T = all(t);
%@eof:1
%@test:2
%$ try
%$ % Instantiate dprior object
%$ o = dprior();
%$ t(1) = true;
%$ catch
%$ t(1) = false;
%$ end
%$
%$ T = all(t);
%@eof:2