Skip to contents

Creates a function similar to ll_theta() but faster and more memory efficient. The model structure (template) and the data (y) are encoded within the generated closure (a function plus its enclosing environment). The generated function calls compiled C/C++ code (see RcppArmadillo-package) and hence is much faster than calling ll_theta(th, template, y, ...).

Usage

ll_FUN(
  template,
  y,
  which = c("concentrated", "conditional", "kf", "gr_concentrated"),
  skip = 0L,
  tol = 1e-08,
  err = NA_real_
)

Arguments

template

A model template, see model structures.

y

sample, i.e. an \((N,m)\) dimensional matrix, or a "time series" object (i.e. as.matrix(y) should return an \((N,m)\)-dimensional numeric matrix). Missing values (NA, NaN and Inf) are not supported.

which

(string) Determines the type of ll function.

skip

(integer) skip initial observations. If NULL then skip is set to \(0\) for state space models and to \(\max(p,q)\) for ARMA models. This parameter is only used for the cases "concentrated", "conditional" and "gr_concentrated"

tol

(double) tolerance used by ll_kf_cpp().

err

(double) return value for the case "kf", if the computation of the initial state covariance fails.

Value

A function, llfun(th) say, which computes the log-likelihood for given deep parameters th. This function may be used for ML estimation of the model.

Function fn(th)

Examples

# Generate a random model in echelon form model (m = 3)
tmpl = tmpl_stsp_echelon(nu = c(2,1,1))
model = r_model(template = tmpl, bpoles = 1, bzeroes = 1, sd = 0.25)
diag(model$sigma_L) = 1 # scale the diagonal entries of sigma_L
print(model)
#> state space model [3,3] with s = 4 states
#>            s[1]       s[2]        s[3]        s[4]         u[1]        u[2]
#> s[1]  0.0000000  0.0000000  0.00000000  1.00000000 -0.316544336 -0.01618156
#> s[2] -0.1343018  0.0788082 -0.16292945  0.04851508  0.144851363 -0.05508861
#> s[3]  0.1347323 -0.5678526 -0.06054697 -0.33873440  0.340936411 -0.13968850
#> s[4] -0.1475590  0.2271577  0.10033103  0.34843878  0.003707541 -0.02091956
#> x[1]  1.0000000  0.0000000  0.00000000  0.00000000  1.000000000  0.00000000
#> x[2]  0.0000000  1.0000000  0.00000000  0.00000000  0.000000000  1.00000000
#> x[3]  0.0000000  0.0000000  1.00000000  0.00000000  0.000000000  0.00000000
#>             u[3]
#> s[1]  0.33103076
#> s[2] -0.20389659
#> s[3] -0.01847925
#> s[4] -0.17822994
#> x[1]  0.00000000
#> x[2]  0.00000000
#> x[3]  1.00000000
#> Left square root of noise covariance Sigma:
#>              u[1]      u[2] u[3]
#> u[1]  1.000000000 0.0000000    0
#> u[2]  0.319242474 1.0000000    0
#> u[3] -0.006575605 0.2957114    1
# extract the corresponding free/deep parameters
th = extract_theta(model, tmpl)

# generate a sample with 50 observations
y = sim(model, n.obs = 50)$y

# conditional log likelihood
# the following statements return the same ll value!
ll(model, y, 'conditional')
#> [1] -3.834035
ll_theta(th, tmpl, y, 'conditional')
#> [1] -3.834035
fn = ll_FUN(tmpl, y, 'conditional')
fn(th)
#> [1] -3.834035

# concentrated conditional log likelihood
# the following statements return the same ll value!
ll(model, y, 'concentrated')
#> [1] -3.692632
ll_theta(th, tmpl, y, 'concentrated')
#> [1] -3.692632
fn = ll_FUN(tmpl, y, 'concentrated')
fn(th)
#> [1] -3.692632
# for this case, we may also compute the (analytic) gradient
gr = ll_FUN(tmpl, y, 'gr_concentrated')
gr(th)
#>  [1]  0.041822199  0.055770379  0.052686267  0.057284023 -0.010455921
#>  [6] -0.077393993 -0.042746729  0.020181147  0.002563469  0.074772863
#> [11] -0.013562400 -0.093805050  0.407322752  0.128816294  0.029782568
#> [16]  0.152448556  0.179700493  0.249915026  0.088241938  0.348236125
#> [21]  0.023887748 -0.202170018  0.204631962 -0.144663738  0.000000000
#> [26]  0.000000000  0.000000000  0.000000000  0.000000000  0.000000000

# log likelihood (via Kalman filter)
# the following statements return the same ll value!
ll(model, y, 'kf2')
#> [1] -3.839648
ll_theta(th, tmpl, y, 'kf2')
#> [1] -3.839648
ll(model, y, 'kf')
#> [1] -3.839648
ll_theta(th, tmpl, y, 'kf')
#> [1] -3.839648
fn = ll_FUN(tmpl, y, 'kf')
fn(th)
#> [1] -3.839648