setClassUnion("matrixORnumeric", c("matrix", "numeric"))
#' Check the validity of mhspec
#'
#' This function checks the validity of mhspec.
#' For one dimensional case, if one of the parameter is not matrix, then all parameters should not be matrix.
#' If one of the parameter is atomic, then all parameters should be atomic.
#' If all parameters are matrix, then the nrow should be equal.
#' The number of columns of MU matrix should be one.
#' ALPHA, BETA, ETA matrices should be sqaure matrices.
#' The dimension of the model is less than 10.
#'
#' @param object S4-class of mhspec
#' @export
valid_mhspec <- function(object) {
if(!is.matrix(object@MU) | !is.matrix(object@ALPHA) | !is.matrix(object@BETA) | (!is.null(object@ETA) & !is.matrix(object@ETA))){
# If one of the parameter is not matrix, then all parameters should not be matrix.
if(!(!is.matrix(object@MU) & !is.matrix(object@ALPHA) & !is.matrix(object@BETA) & (!is.null(object@ETA) & !is.matrix(object@ETA)))){
methods::show(object)
return("If one of the parameter is not matrix, then all parameters should not be matrix.")
}
# If one of the parameter is atomic, then all parameters should be atomic.
len_mu <- length(object@MU)
len_alpha <- length(object@ALPHA)
len_beta <- length(object@BETA)
if (!is.null(object@ETA))
len_eta <- length(object@ETA)
else
len_eta <- len_mu
if (max(c(len_mu, len_alpha, len_beta, len_eta)) != 1 ){
methods::show(object)
return("If one of the parameter is atomic, then all parameters should be atomic.")
}
} else{
# If all parameters are matrix, then the nrow should be equal.
dim_mu <- nrow(object@MU)
dim_alpha <- nrow(object@ALPHA)
dim_beta <- nrow(object@BETA)
if (!is.null(object@ETA))
dim_eta <- nrow(object@ETA)
else
dim_eta <- dim_mu
if (dim_mu > 9)
return("The dimension of the model is too large.")
if( max(c(dim_mu, dim_alpha, dim_beta, dim_eta)) != min(c(dim_mu, dim_alpha, dim_beta, dim_eta)) ){
methods::show(object)
return("The number of rows of parameter matrix should be equal.")
}
if ( ncol(object@MU) > 1 ){
methods::show(object)
return("The number of columns of MU matrix should be one.")
}
if ( ncol(object@ALPHA) != nrow(object@ALPHA) ){
methods::show(object)
return("ALPHA matrix should be n by n matrix.")
}
if ( ncol(object@BETA) != nrow(object@BETA) ){
methods::show(object)
return("BETA matrix should be n by n matrix.")
}
if ( !is.null(object@ETA) )
if (ncol(object@ETA) != nrow(object@ETA) ){
methods::show(object)
return("ETA matrix should be n by n matrix.")
}
}
return(TRUE)
}
#' An S4 class to represent a marked Hawkes model
#'
#' This class represents a specification of a marked Hawkes model with exponential kernel.
#' The intensity of the ground process is defined by:
#' \deqn{\lambda(t) = \mu + \int \alpha / \beta (1 + (k - 1) \eta) exp( -\beta (t-u)) d N(t)}
#'
#' @slot MU numeric value or matrix. Shoud be a matrix for two or larger dimensional model.
#' @slot ALPHA numeric value or matrix. Shoud be a matrix for two or larger dimensional model.
#' @slot BETA numeric value or matrix. Shoud be a matrix for two or larger dimensional model.
#' @slot ETA numeric value or matrix. Shoud be a matrix for two or larger dimensional model.
#' @slot mark a function that generate a random number with specific distribution.
#' @slot impact a function that describe the mark impact
#'
#' @examples
#' MU2 <- matrix(c(0.2), nrow = 2)
#' ALPHA2 <- matrix(c(0.75, 0.92, 0.92, 0.75), nrow = 2, byrow=TRUE)
#' BETA2 <- matrix(c(2.25, 2.25, 2.25, 2.25), nrow = 2, byrow=TRUE)
#' ETA2 <- matrix(c(0.19, 0.19, 0.19, 0.19), nrow = 2, byrow=TRUE)
#' mark2 <- function(n,...) rgeom(n, 0.65) + 1
#' mhspec2 <- new("mhspec", MU=MU2, ALPHA=ALPHA2, BETA=BETA2, ETA=ETA2, mark = mark2)
#'
#' @export
setClass(
"mhspec",
slots = list(
MU = "matrixORnumeric",
ALPHA = "matrixORnumeric",
BETA = "matrixORnumeric",
ETA = "matrixORnumeric",
mark = "function"
#impact = "function"
),
validity = valid_mhspec
)
#' @export
setMethod(
"initialize",
"mhspec",
function(.Object, MU, ALPHA, BETA, ETA=NULL, mark=NULL, impact=NULL, stability_check=FALSE){
# If mark is not provided, then mark is constant 1.
if (is.null(mark)) mark <- function(n,...) rep(1,n)
# If ETA is not provided, then ETA = 0 or zero matrix with the same dimension of BETA
if (is.null(ETA)) {
if (length(MU) == 1){
ETA <- 0
} else {
ETA <- matrix(rep(0, length(BETA)), nrow = length(MU))
}
}
.Object@MU <- MU
.Object@ALPHA <- ALPHA
.Object@BETA <- BETA
.Object@ETA <- ETA
# check the number of arguments
if(length(formals(mark)) == 1){
.Object@mark <- function(n, ...) mark(n)
} else {
.Object@mark <- mark
}
# Check spectral radius
if ( stability_check==TRUE && max(abs(eigen(ALPHA/BETA)$values)) >= 1)
warning("This model does not satisfy the stability condition.")
methods::callNextMethod()
.Object
}
)
#' @export
setMethod(
"show",
"mhspec",
function(object){
dimens <- length(object@MU)
cat(paste0(toString(dimens), "-variate (marked) Hawkes model with linear impact function.\n"))
cat("The intensity process is defined by\n")
cat("LAMBDA(t) = MU + int ALPHA / BETA * (1 + (k - 1) * ETA) * exp(-BETA * (t - u)) d N(u)\n" )
cat("\n")
cat("Parameters: \n")
cat("MU: \n")
print(object@MU)
cat("ALPHA: \n")
print(object@ALPHA)
cat("BETA: \n")
print(object@BETA)
cat("ETA: \n")
print(object@ETA)
cat("Mark distribution: \n")
print(object@mark)
#if(!is.null(impact)){
# cat("Impact function: \n")
# print(object@impact)
#}
cat("------------------------------------------\n")
}
)
#' Unique coefficient matrix
#'
#' @export
name_unique_coef_mtrx <- function(M, notation){
reference <- character(length(M))
if (ncol(M) == 1){
k <- 1
for (i in 1:nrow(M)){
if (reference[k] == "")
reference[which(M == M[i])] <- paste0(notation, toString(i))
k <- k + 1
}
} else {
k <- 1
for (i in 1:nrow(M)){
for (j in 1:ncol(M)) {
if (reference[k] == "")
reference[which( t(M) == M[i,j])] <- paste0(notation, toString(i), toString(j))
k <- k + 1
}
}
}
reference
}
#' Extract the Hawkes model coefficients
#'
#' @export
setMethod(
"coef",
"mhspec",
function(object, uniqueness = FALSE){
dimens <- length(object@MU)
coeff <- numeric()
name <- character()
if (uniqueness == FALSE | dimens == 1){
#MU
name <- c(name, sapply(seq(1, dimens), function(x) paste0("mu", x)) )
#ALPHA
for (i in 1:dimens){
for (j in 1:dimens){
name <- c(name, paste0("alpha", i, j))
}
}
#BETA
for (i in 1:dimens){
for (j in 1:dimens){
name <- c(name, paste0("beta", i, j))
}
}
#ETA
for (i in 1:dimens){
for (j in 1:dimens){
name <- c(name, paste0("eta", i, j))
}
}
coeff <- c(as.vector(object@MU), as.vector(t(object@ALPHA)), as.vector(t(object@BETA)), as.vector(t(object@ETA)))
} else {
#MU
unique_mus <- unique(as.vector(object@MU))
name <- c(name, unique(name_unique_coef_mtrx(object@MU, "mu")))
#ALPHA
unique_alphas <- unique(as.vector(t(object@ALPHA)))
name <- c(name, unique(name_unique_coef_mtrx(object@ALPHA, "alpha")))
#BETA
unique_betas <- unique(as.vector(t(object@BETA)))
name <- c(name, unique(name_unique_coef_mtrx(object@BETA, "beta")))
#ETA
unique_etas <- unique(as.vector(t(object@ETA)))
name <- c(name, unique(name_unique_coef_mtrx(object@ETA, "eta")))
coeff <- c(unique_mus, unique_alphas, unique_betas, unique_etas)
}
names(coeff) <- name
coeff
}
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.