function [A,B,C,D,mean0,cov0,stateType,deflatedYield] = Example_DieboldLi(param,Yield,maturity)
%EXAMPLE_DIEBOLDLI Parameter-to-matrix map for Diebold-Li yields-only model
%
% Syntax:
%
%   [A,B,C,D,mean0,cov0,stateType,deflatedYield] = ...
%                                 Example_DieboldLi(param,Yield,maturity)
%
% Note:
%
%   To create an ssm model object that implicitly maps Diebold-Li model parameters 
%   to SSM coefficients, parameterize the function as an anonymous function
%   that accepts a single column vector of estimated parameters:
%
%   f = @(param) Example_DieboldLi(param,Yield,maturity)
%
%   Example_DieboldLi supports the Diebold-Li example
%   Demo_DieboldLiModel; the function can change in a future release without
%   notice.
%
% Description:
%
%   For observation vector y(t) and state vector x(t), create a state-space 
%   model (SSM) of the form:
%
%   State equation:       x(t) = A * x(t-1) + B * u(t)
%   Observation equation: y(t) = C * x(t)   + D * e(t)
%
%   where u(t) and e(t) are uncorrelated, unit-variance white noise vector
%   processes.  In the example, the 3-by-1 state vector represents the
%   three Diebold-Li model factors, and A is the 3-by-3 state transition
%   matrix.  The dimension of the observed yield vector, y(t), is
%   determined by the number of maturities included in the time series of
%   yield curves.
%
%   This function imposes constraints on the covariance matrices of the
%   noise processes such that the full covariance matrix of u(t) is
%   Q = B*B' and the diagonal covariance matrix of e(t) is H = D*D'.  This
%   mapping function also accounts for the means of the three factors
%   (states, x(t)) and deflates the input observed yields y(t) to estimate
%   the factor offsets.
%

% Copyright 2021 The MathWorks, Inc.

%
% Initialize some basic dimensions of the model.
%

numFactors    = 3;              % number of factors in the Diebold-Li "yields-only" model
numMaturities = size(Yield,2);  % number of maturities (columns) in yield data 

%
% Unpack the decay rate parameter stored in the last element of the input
% parameter vector and use it to parameterize the C matrix of the observation 
% equation.  Note that when viewed as a regression model, the C matrix of 
% the observation equation may also be interpreted as a matrix of predictors, 
% and would typically be denoted as "X".
%

lambda = param(end);  % decay rate parameter is stored in the last element
C = [ones(size(maturity)) (1 - exp(-lambda*maturity))./(lambda*maturity) ...
    ((1 - exp(-lambda*maturity))./(lambda*maturity) - exp(-lambda*maturity))];

%
% Unpack the input parameter column vector and create the model parameter
% matrices A, B, and D.  Note that the C matrix has already been parameterized 
% as a function of the estimated decay rate parameter.
%

A    = zeros(numFactors);        % pre-allocate square matrix A
A(:) = param(1:numFactors^2);    % pack parameters into A columnwise 

numelB = numFactors*(numFactors+1)/2;
mask = tril(true(numFactors));
B = zeros(numFactors); 
B(mask) = param((numFactors^2 + 1):(numFactors^2 + numelB));

iOffset = numel(A) + numelB;     % last parameter index of the B matrix
D = diag(param((iOffset + 1):(iOffset + numMaturities)));

%
% Compute the intercepts (factor means) and deflate the input yields.
%

intercept = C * param((iOffset + numMaturities + 1):(end - 1));
deflatedYield = bsxfun(@minus, Yield, intercept');

%
% Initialize some placeholders not used in this example, but needed to allow
% for the deflated yield data.
%

mean0     = [];
cov0      = [];
stateType = [];
end
