Skip to contents

Installation

Install the development package from GitHub:

install.packages("remotes")
remotes::install_github("ksublee/frpp", build_vignettes = FALSE)

The default backend requires emhawkes 1.0.0 or later. The optional state backend uses the public shared-kernel API in GitHub development emhawkes 1.0.1.9000. Install that development version when using state calculations:

remotes::install_github("ksublee/emhawkes", build_vignettes = FALSE)

The default bridge works without that API. State requests report an explicit error when the API is absent. See the shared-kernel contract.

Define a model

A model combines an emhawkes kernel with a residual law. The following law has Gamma shape 2 and rate 2, hence mean 1:

kernel <- methods::new("hspec", mu = 0.3, alpha = 0.2, beta = 1)
law <- residual_law(c(shape = 2, rate = 2),
  dresidual = stats::dgamma, presidual = stats::pgamma,
  qresidual = stats::qgamma, rresidual = stats::rgamma, name = "Gamma(2,2)")
model <- fspec(kernel, law)
model
#> FRPP specification (S4 fspec)
#> Event types: 1
#> Residual law: Gamma(2,2)
#> Residual candidates refreshed after every global event.

The kernel supplies the baseline and exponential state dynamics. The residual law supplies the density, distribution, quantile and random-generation functions. Constructing these objects does not run the residual callbacks.

For simulation, the current implementation requires equal decay rates within each row of the kernel matrix. Numeric marked effects and kernel mappings are supported; more general callbacks use the compatibility backend.

Supply residual functions as needed

Use the same names as emhawkes: dresidual (density), presidual (CDF), qresidual (quantile) and rresidual (generator). All default to NULL. The constructor needs at least a density or generator; each operation then checks only its own requirements before evaluating callbacks or drawing randomness.

Operation Required residual functions
Simulation rresidual
Univariate likelihood and fitting dresidual
Multivariate likelihood and fitting dresidual, presidual
Residual diagnostics with infer = TRUE dresidual, presidual, qresidual

For simulation alone:

simulation_law <- frpp::residual_law(c(rate = 1), rresidual = stats::rexp)
simulation_model <- frpp::fspec(
  methods::new("hspec", mu = 1, alpha = 0, beta = 1), simulation_law)
simulation_path <- frpp::fsim(simulation_model, size = 5, seed = 73,
  lambda_component0 = 0)
simulation_path$inter_arrival
#> [1] 0.00000000 0.75075454 0.24561278 0.07472991 1.48571875

The aliases density, cdf, quantile and rng remain supported without warnings, in that order. You can mix names for different roles, but supplying both non-NULL names for one role is an error. The original six positional arguments retain their order. Saved laws retain their existing internal representation and callback environments/defaults; no conversion is needed.

Simulate and inspect a path

path <- fsim(model, size = 1000, seed = 73, lambda_component0 = 0)
head(data.frame(time = cumsum(path$inter_arrival),
  type = path$type, mark = path$mark))
#>       time type mark
#> 1 0.000000    0    0
#> 2 2.212690    1    1
#> 3 4.776757    1    1
#> 4 5.266585    1    1
#> 5 5.848559    1    1
#> 6 8.591268    1    1

size includes the initial row, so this request generates 999 events. inter_arrival, type and mark start with zero. Event types index rows of the driver, while type_col_map selects kernel columns updated after each event. N and Nc contain event counts and accumulated marks.

lambda_component0 contains initial intensity components excluding the baseline. A scalar expands to every component; a matrix must match the kernel shape. FRPP’s automatic rule selects zero, with a message recommending an explicit state. A Hawkes stationary mean is not assumed for a general residual law.

The standard interface returns the same path:

same_path <- stats::simulate(model, size = 1000, seed = 73,
  lambda_component0 = 0)
stopifnot(identical(path, same_path))

With an explicit seed, the caller’s RNG kind and state are restored, including on errors. With seed = NULL, simulation advances the caller’s RNG normally.

Evaluate the likelihood

logLik(model, path$inter_arrival, path$type, mark = path$mark,
  lambda_component0 = 0)
#> loglikelihood 
#>     -1909.699

Include the initial row when supplying observations. For a univariate model, type may be omitted. Use the same initial components and initial counts used for the observation window.

With infer = TRUE, the result also contains driver states, component histories and residual diagnostics. These driving quantities are not automatically the conditional intensities of a general FRPP.

Continue with Fitting and inference, or see the multivariate examples.

Optional independent simulator

The default simulator remains the compatibility bridge. With current GitHub development emhawkes, choose fsim(model, backend = "state", ...) to use the independent numeric FRPP event loop. It preserves global residual refresh and path/RNG behavior, but is currently slower on larger paths. Event callbacks remain in the bridge. backend = "auto" opts into capability-based selection; see Model and computation for the support contract.