statespace_model#
The abstract model with parameters, the Fortran counterpart of statsmodels’
MLEModel, and the standard parameter transforms.
A model extends ssm_model_t. Its constructor sets up rep (data,
fixed matrices, initialization) and k_params; it implements
update(params): write the constrained parameters into the system matrices;start_params(): constrained starting values;
and may override transform_params (unconstrained to constrained),
untransform_params and param_names. The optimizer works on
unconstrained values; update always receives constrained ones.
Example#
The local level model (example/nile_mle.f90):
module nile_local_level_model
use statespace
implicit none
private
public :: local_level_t, local_level
!> y_t = alpha_t + eps_t, alpha_t+1 = alpha_t + eta_t,
!> params = [sigma2_eps, sigma2_eta].
type, extends(ssm_model_t) :: local_level_t
contains
procedure :: update
procedure :: start_params
procedure :: transform_params
procedure :: untransform_params
procedure :: param_names
end type local_level_t
contains
function local_level(y) result(model)
real(dp), intent(in) :: y(:, :)
type(local_level_t) :: model
model%k_params = 2
model%rep = ssm_rep(y, m=1, r=1)
model%rep%Z = 1.0_dp
model%rep%T = 1.0_dp
call model%rep%initialize_diffuse()
end function local_level
subroutine update(self, params)
class(local_level_t), intent(inout) :: self
real(dp), intent(in) :: params(:)
self%rep%H(1, 1, 1) = params(1)
self%rep%Q(1, 1, 1) = params(2)
end subroutine update
function start_params(self) result(params)
class(local_level_t), intent(in) :: self
real(dp), allocatable :: params(:)
real(dp) :: v
associate (y => self%rep%y(1, :))
v = sum((y - sum(y) / size(y))**2) / size(y)
end associate
params = [v / 2, v / 2]
end function start_params
function transform_params(self, unconstrained) result(constrained)
class(local_level_t), intent(in) :: self
real(dp), intent(in) :: unconstrained(:)
real(dp), allocatable :: constrained(:)
constrained = constrain_positive(unconstrained)
end function transform_params
function untransform_params(self, constrained) result(unconstrained)
class(local_level_t), intent(in) :: self
real(dp), intent(in) :: constrained(:)
real(dp), allocatable :: unconstrained(:)
unconstrained = unconstrain_positive(constrained)
end function untransform_params
function param_names(self) result(names)
class(local_level_t), intent(in) :: self
character(len=32), allocatable :: names(:)
names = [character(len=32) :: "sigma2.irregular", "sigma2.level"]
end function param_names
end module nile_local_level_model
ssm_model_t#
type, abstract :: ssm_model_t
type(ssm_rep_t) :: rep
integer :: k_params = 0
logical :: concentrate_scale = .false.
real(dp) :: scale = 1.0_dp
contains
procedure(update_iface), deferred :: update
procedure(start_params_iface), deferred :: start_params
procedure :: transform_params, untransform_params, param_names
procedure :: loglike, rep_at, filter, smooth
end type
concentrate_scaleH, Q and \(P_*\) set by
updateare relative to a scale \(\sigma^2\), which is concentrated out of the likelihood (DK §2.10.2) and is not a parameter.scaleholds its estimate at the last evaluation.
Deferred procedures:
subroutine update(self, params)
class(ssm_model_t), intent(inout) :: self
real(dp), intent(in) :: params(:)
function start_params(self) result(params)
class(ssm_model_t), intent(in) :: self
real(dp), allocatable :: params(:)
Overridable procedures, with defaults:
function transform_params(self, unconstrained) result(constrained) ! identity
function untransform_params(self, constrained) result(unconstrained) ! identity
function param_names(self) result(names) ! "param1", ...; character(32)
Evaluation at given parameters (constrained unless
transformed = .false.):
function loglike(self, params, info, transformed) result(llf)
subroutine rep_at(self, params, rep, info, transformed)
subroutine filter(self, params, fres, info, transformed)
subroutine smooth(self, params, fres, sres, info, transformed)
loglike calls update and returns the log likelihood, concentrated
when concentrate_scale is set. rep_at returns the representation at
params on the data’s scale (H, Q and \(P_*\) multiplied by the
estimated scale); filter and smooth run on it.
Transforms#
elemental real(dp) function constrain_positive(x) ! exp(2 x)
elemental real(dp) function unconstrain_positive(x) ! log(x) / 2
pure function constrain_stationary(unconstrained) result(phi)
pure function unconstrain_stationary(phi) result(unconstrained)
constrain_positive\(\sigma^2 = \exp(2\psi)\) for variances (DK §7.3.2).
constrain_stationaryCoefficients \(\phi\) of a stationary AR polynomial \(1 - \phi_1 L - \dots - \phi_p L^p\) (Monahan 1984): the partial autocorrelations are \(x / \sqrt{1 + x^2}\), DK’s bounded transform with a = 1. The negated result gives invertible MA coefficients. Matches statsmodels’
constrain_stationary_univariateto 1e-14.