R/kernels.R

Defines functions kernelFast.splinekernel kernelFast.tanhkernel kernelFast.vanilla kernelFast.polykernel kernelFast.anovakernel kernelFast.besselkernel kernelFast.laplacekernel kernelFast.rbfkernel kernelFast kernelPol.vanillakernel kernelPol.tanhkernel kernelPol.polykernel kernelPol.splinekernel kernelPol.anovakernel kernelPol.besselkernel kernelPol.laplacekernel kernelPol.rbfkernel kernelPol kernelMult.vanillakernel kernelMult.tanhkernel kernelMult.polykernel kernelMult.splinekernel kernelMult.anovakernel kernelMult.besselkernel kernelMult.laplacekernel kernelMult.rbfkernel kernelMult.character kernelMult kernelMatrix.splinekernel kernelMatrix.tanhkernel kernelMatrix.vanilla kernelMatrix.polykernel kernelMatrix.anovakernel kernelMatrix.besselkernel kernelMatrix.laplacekernel kernelMatrix.rbfkernel kernelMatrix vanilladot polydot tanhdot fourierdot splinedot anovadot besseldot laplacedot rbfdot

Documented in anovadot besseldot laplacedot polydot rbfdot splinedot vanilladot

## S4 object definitions and assigment/accessor functions for the slots.
##
## created  10.09.03 alexandros karatzoglou
## updated  23.08.05


setClass("kernel", representation("function", kpar = "list"))
setClass("kernelMatrix",
         representation("matrix"),
         prototype = structure(.Data = matrix()))

setClassUnion("listI", c("list", "numeric", "vector", "integer", "matrix"))
setClassUnion(
  "output",
  c(
    "matrix",
    "factor",
    "vector",
    "logical",
    "numeric",
    "list",
    "integer",
    "NULL"
  )
)
setClassUnion("input", c("matrix", "list"))
setClassUnion("kfunction", c("function", "character"))
setClassUnion("mpinput", c("matrix", "data.frame", "missing"))
setClassUnion("lpinput", c("list", "missing"))
setClassUnion("kpinput", c("kernelMatrix", "missing"))

if (!isGeneric("kpar")) {
  if (is.function("kpar"))
    fun <- kpar
  else
    fun <- function(object)
      standardGeneric("kpar")
  setGeneric("kpar", fun)
}
setGeneric("kpar<-", function(x, value)
  standardGeneric("kpar<-"))



setGeneric("as.kernelMatrix", function(x, center = FALSE)
  standardGeneric("as.kernelMatrix"))
setMethod("as.kernelMatrix", signature(x = "matrix"),
          function(x, center = FALSE)
          {
            if (center) {
              m <- dim(x)[1]
              x <- t(t(x - colSums(x) / m) -  rowSums(x) / m) + sum(x) / m ^ 2
            }
            
            return(new("kernelMatrix", .Data = x))
          })



## kernel functions
## Functions for computing a kernel value, matrix, matrix-vector
## product and quadratic form
##
## author : alexandros karatzoglou


## Define the kernel objects,
## functions with an additional slot for the kernel parameter list.
## kernel functions take two vector arguments and return a scalar (dot product)


rbfdot <- function(sigma = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      return(exp(sigma * (
        2 * crossprod(x, y) - crossprod(x) - crossprod(y)
      )))
      # sigma/2 or sigma ??
    }
  }
  return(new(
    "rbfkernel",
    .Data = rval,
    kpar = list(sigma = sigma)
  ))
}
setClass(
  "rbfkernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

laplacedot <- function(sigma = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      return(exp(-sigma * sqrt(-(
        round(2 * crossprod(x, y) - crossprod(x) - crossprod(y), 9)
      ))))
    }
  }
  return(new(
    "laplacekernel",
    .Data = rval,
    kpar = list(sigma = sigma)
  ))
}

setClass(
  "laplacekernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

besseldot <- function(sigma = 1,
                      order = 1,
                      degree = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      lim <- 1 / (gamma(order + 1) * 2 ^ (order))
      bkt <-
        sigma * sqrt(-(2 * crossprod(x, y) - crossprod(x) - crossprod(y)))
      if (bkt < 10e-5)
        res <- lim
      else
        res <- besselJ(bkt, order) * (bkt ^ (-order))
      return((res / lim) ^ degree)
    }
  }
  return(new(
    "besselkernel",
    .Data = rval,
    kpar = list(
      sigma = sigma ,
      order = order ,
      degree = degree
    )
  ))
}

setClass(
  "besselkernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

anovadot <- function(sigma = 1, degree = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      
      res <- sum(exp(-sigma * (x - y) ^ 2))
      return((res) ^ degree)
    }
  }
  return(new(
    "anovakernel",
    .Data = rval,
    kpar = list(sigma = sigma , degree = degree)
  ))
}

setClass(
  "anovakernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)


splinedot <- function()
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      minv <- pmin(x, y)
      res <- 1 + x * y * (1 + minv) - ((x + y) / 2) * minv ^ 2 + (minv ^
                                                                    3) / 3
      fres <- prod(res)
      return(fres)
    }
  }
  return(new("splinekernel", .Data = rval, kpar = list()))
}

setClass(
  "splinekernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)



fourierdot <- function(sigma = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must a vector")
    if (is(x, "vector") && is.null(y)) {
      return(1)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      res <- 	(1 - sigma ^ 2) / 2 * (1 - 2 * sigma * cos(x - y) + sigma ^ 2)
      fres <- prod(res)
      return(fres)
    }
  }
  return(new("fourierkernel", .Data = rval, kpar = list()))
}

setClass(
  "fourierkernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list(sigma = 1)
  ),
  contains = c("kernel")
)





tanhdot <- function(scale = 1, offset = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a  vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must be a vector")
    if (is(x, "vector") && is.null(y)) {
      tanh(scale * crossprod(x) + offset)
    }
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      tanh(scale * crossprod(x, y) + offset)
    }
  }
  return(new(
    "tanhkernel",
    .Data = rval,
    kpar = list(scale = scale, offset = offset)
  ))
}
setClass(
  "tanhkernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

setClass(
  "polykernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

polydot <- function(degree = 1,
                    scale = 1,
                    offset = 1)
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must be a vector")
    if (is(x, "vector") && is.null(y)) {
      (scale * crossprod(x) + offset) ^ degree
    }
    
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      (scale * crossprod(x, y) + offset) ^ degree
    }
    
  }
  return(new(
    "polykernel",
    .Data = rval,
    kpar = list(
      degree = degree,
      scale = scale,
      offset = offset
    )
  ))
}

setClass(
  "vanillakernel",
  prototype = structure(
    .Data = function() {
    },
    kpar = list()
  ),
  contains = c("kernel")
)

vanilladot <- function()
{
  rval <- function(x, y = NULL)
  {
    if (!is(x, "vector"))
      stop("x must be a vector")
    if (!is(y, "vector") && !is.null(y))
      stop("y must be a vector")
    if (is(x, "vector") && is.null(y)) {
      crossprod(x)
    }
    
    if (is(x, "vector") && is(y, "vector")) {
      if (!length(x) == length(y))
        stop("number of dimension must be the same on both data points")
      crossprod(x, y)
    }
    
  }
  return(new("vanillakernel", .Data = rval, kpar = list()))
}


setMethod("show", signature(object = "kernel"),
          function(object)
          {
            switch(
              class(object),
              "rbfkernel" = cat(
                paste(
                  "Gaussian Radial Basis kernel function.",
                  "\n",
                  "Hyperparameter :" ,
                  "sigma = ",
                  kpar(object)$sigma,
                  "\n"
                )
              ),
              "laplacekernel" = cat(
                paste(
                  "Laplace kernel function.",
                  "\n",
                  "Hyperparameter :" ,
                  "sigma = ",
                  kpar(object)$sigma,
                  "\n"
                )
              ),
              "besselkernel" = cat(
                paste(
                  "Bessel kernel function.",
                  "\n",
                  "Hyperparameter :" ,
                  "sigma = ",
                  kpar(object)$sigma,
                  "order = ",
                  kpar(object)$order,
                  "degree = ",
                  kpar(object)$degree,
                  "\n"
                )
              ),
              "anovakernel" = cat(
                paste(
                  "Anova RBF kernel function.",
                  "\n",
                  "Hyperparameter :" ,
                  "sigma = ",
                  kpar(object)$sigma,
                  "degree = ",
                  kpar(object)$degree,
                  "\n"
                )
              ),
              "tanhkernel" = cat(
                paste(
                  "Hyperbolic Tangent kernel function.",
                  "\n",
                  "Hyperparameters :",
                  "scale = ",
                  kpar(object)$scale,
                  " offset = ",
                  kpar(object)$offset,
                  "\n"
                )
              ),
              "polykernel" = cat(
                paste(
                  "Polynomial kernel function.",
                  "\n",
                  "Hyperparameters :",
                  "degree = ",
                  kpar(object)$degree,
                  " scale = ",
                  kpar(object)$scale,
                  " offset = ",
                  kpar(object)$offset,
                  "\n"
                )
              ),
              "vanillakernel" = cat(paste(
                "Linear (vanilla) kernel function.", "\n"
              )),
              "splinekernel" = cat(paste("Spline kernel function.", "\n")),
            )
          })

## create accesor function as in "S4 Classses in 15 pages more or less", well..

if (!isGeneric("kpar")) {
  if (is.function(kpar))
    fun <- kpar
  else
    fun <- function(object)
      standardGeneric("kpar")
  setGeneric("kpar", fun)
}

setMethod("kpar", "kernel", function(object)
  object@kpar)




## Functions that return usefull kernel calculations (kernel matrix etc.)

## kernelMatrix function takes two or three arguments

kernelMatrix <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(x, "matrix"))
    stop("x must be a matrix")
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  n <- nrow(x)
  res1 <- matrix(rep(0, n * n), ncol = n)
  if (is.null(y)) {
    for (i in 1:n) {
      for (j in i:n) {
        res1[i, j]  <- kernel(x[i, ], x[j, ])
      }
    }
    res1 <- res1 + t(res1)
    diag(res1) <- diag(res1) / 2
    
    
  }
  if (is(y, "matrix")) {
    m <- dim(y)[1]
    res1 <- matrix(0, dim(x)[1], dim(y)[1])
    for (i in 1:n) {
      for (j in 1:m) {
        res1[i, j] <- kernel(x[i, ], y[j, ])
      }
    }
  }
  
  return(as.kernelMatrix(res1))
}

setGeneric("kernelMatrix", function(kernel, x, y = NULL)
  standardGeneric("kernelMatrix"))



kernelMatrix.rbfkernel <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix") &&
      !is.null(y))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  n <- dim(x)[1]
  dota <- rowSums(x * x) / 2
  if (is(x, "matrix") && is.null(y)) {
    res <- crossprod(t(x))
    for (i in 1:n)
      res[i, ] <- exp(2 * sigma * (res[i, ] - dota - rep(dota[i], n)))
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      res[, i] <- exp(2 * sigma * (res[, i] - dota - rep(dotb[i], n)))
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "rbfkernel"),
          kernelMatrix.rbfkernel)

kernelMatrix.laplacekernel <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix") &&
      !is.null(y))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  n <- dim(x)[1]
  dota <- rowSums(x * x) / 2
  if (is(x, "matrix") && is.null(y)) {
    res <- crossprod(t(x))
    for (i in 1:n)
      res[i, ] <-
        exp(-sigma * sqrt(round(-2 * (
          res[i, ] - dota - rep(dota[i], n)
        ), 9)))
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      res[, i] <-
      exp(-sigma * sqrt(round(-2 * (
        res[, i] - dota - rep(dotb[i], n)
      ), 9)))
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "laplacekernel"),
          kernelMatrix.laplacekernel)

kernelMatrix.besselkernel <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix") &&
      !is.null(y))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  nu = kpar(kernel)$order
  ni = kpar(kernel)$degree
  n <- dim(x)[1]
  lim <- 1 / (gamma(nu + 1) * 2 ^ (nu))
  dota <- rowSums(x * x) / 2
  if (is(x, "matrix") && is.null(y)) {
    res <- crossprod(t(x))
    for (i in 1:n) {
      xx <- sigma * sqrt(round(-2 * (res[i, ] - dota - rep(dota[i], n)), 9))
      res[i, ] <- besselJ(xx, nu) * (xx ^ (-nu))
      res[i, which(xx < 10e-5)] <- lim
    }
    return(as.kernelMatrix((res / lim) ^ ni))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m) {
      xx <- sigma * sqrt(round(-2 * (res[, i] - dota - rep(dotb[i], n)), 9))
      res[, i] <- besselJ(xx, nu) * (xx ^ (-nu))
      res[which(xx < 10e-5), i] <- lim
    }
    return(as.kernelMatrix((res / lim) ^ ni))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "besselkernel"),
          kernelMatrix.besselkernel)


kernelMatrix.anovakernel <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix") &&
      !is.null(y))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  degree = kpar(kernel)$degree
  n <- dim(x)[1]
  if (is(x, "matrix") && is.null(y)) {
    a <- matrix(0,  dim(x)[2], n)
    res <- matrix(0, n , n)
    for (i in 1:n)
    {
      a[rep(TRUE, dim(x)[2]), rep(TRUE, n)] <- x[i, ]
      res[i, ] <- colSums(exp(-sigma * (a - t(x)) ^ 2)) ^ degree
    }
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    
    m <- dim(y)[1]
    b <- matrix(0, dim(x)[2], m)
    res <- matrix(0, dim(x)[1], m)
    for (i in 1:n)
    {
      b[rep(TRUE, dim(x)[2]), rep(TRUE, m)] <- x[i, ]
      res[i, ] <- colSums(exp(-sigma * (b - t(y)) ^ 2)) ^ degree
    }
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "anovakernel"),
          kernelMatrix.anovakernel)


kernelMatrix.polykernel <- function(kernel, x, y = NULL)
{
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  scale = kpar(kernel)$scale
  offset = kpar(kernel)$offset
  degree = kpar(kernel)$degree
  if (is(x, "matrix") && is.null(y))
  {
    res <- (scale * crossprod(t(x)) + offset) ^ degree
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    res <- (scale * crossprod(t(x), t(y)) + offset) ^ degree
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "polykernel"),
          kernelMatrix.polykernel)

kernelMatrix.vanilla <- function(kernel, x, y = NULL)
{
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  if (is(x, "matrix") && is.null(y)) {
    res <- crossprod(t(x))
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    res <- crossprod(t(x), t(y))
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "vanillakernel"),
          kernelMatrix.vanilla)

kernelMatrix.tanhkernel <- function(kernel, x, y = NULL)
{
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  if (is(x, "matrix") && is.null(y)) {
    scale = kpar(kernel)$scale
    offset = kpar(kernel)$offset
    res <- tanh(scale * crossprod(t(x)) + offset)
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    res <- tanh(scale * crossprod(t(x), t(y)) + offset)
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "tanhkernel"),
          kernelMatrix.tanhkernel)


kernelMatrix.splinekernel <- function(kernel, x, y = NULL)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix") &&
      !is.null(y))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  degree = kpar(kernel)$degree
  n <- dim(x)[1]
  if (is(x, "matrix") && is.null(y)) {
    a <- matrix(0,  dim(x)[2], n)
    res <- matrix(0, n , n)
    x <- t(x)
    for (i in 1:n)
    {
      dr <- 	x + x[, i]
      dp <-   x * x[, i]
      dm <-   pmin(x, x[, i])
      res[i, ] <-
        apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
    }
    return(as.kernelMatrix(res))
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    
    m <- dim(y)[1]
    b <- matrix(0, dim(x)[2], m)
    res <- matrix(0, dim(x)[1], m)
    x <- t(x)
    y <- t(y)
    for (i in 1:n)
    {
      dr <- 	y + x[, i]
      dp <-   y * x[, i]
      dm <-   pmin(y, x[, i])
      res[i, ] <-
        apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
    }
    return(as.kernelMatrix(res))
  }
}
setMethod("kernelMatrix",
          signature(kernel = "splinekernel"),
          kernelMatrix.splinekernel)


## kernelMult computes kernel matrix  - vector product
## function computing <x,x'> * z (<x,x'> %*% z)


kernelMult <- function(kernel,
                       x,
                       y = NULL,
                       z,
                       blocksize = 128)
{
  #  if(is.function(kernel)) ker <- deparse(substitute(kernel))
  #      kernel <- do.call(kernel, kpar)
  
  if (!is(x, "matrix"))
    stop("x must be a matrix")
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must ba a matrix or a vector")
  n <- nrow(x)
  
  if (is.null(y))
  {
    ## check if z,x match
    z <- as.matrix(z)
    if (is.null(y) && !dim(z)[1] == n)
      stop("z columns/length do not match x columns")
    
    res1 <- matrix(rep(0, n * n), ncol = n)
    
    for (i in 1:n)
    {
      for (j in i:n)
      {
        res1[j, i] <- kernel(x[i, ], x[j, ])
      }
    }
    res1 <- res1 + t(res1)
    diag(res1) <- diag(res1) / 2
  }
  if (is(y, "matrix"))
  {
    m <- dim(y)[1]
    z <- as.matrix(z)
    
    if (!dim(z)[1] == m)
      stop("z has wrong dimension")
    res1 <- matrix(rep.int(0, m * n), ncol = m)
    for (i in 1:n)
    {
      for (j in 1:m)
      {
        res1[i, j] <- kernel(x[i, ], y[j, ])
      }
    }
  }
  return(res1 %*% z)
}

setGeneric("kernelMult", function(kernel,
                                  x,
                                  y = NULL,
                                  z,
                                  blocksize = 256)
  standardGeneric("kernelMult"))

kernelMult.character <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    return(x %*% z)
  }
setMethod(
  "kernelMult",
  signature(kernel = "character", x = "kernelMatrix"),
  kernelMult.character
)



kernelMult.rbfkernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or a vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    sigma <- kpar(kernel)$sigma
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    dota <- as.matrix(rowSums(x ^ 2))
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      if (nblocks > 0)
      {
        dotab <- rep(1, blocksize) %*% t(dota)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            exp(sigma * (2 * x[lowerl:upperl, ] %*% t(x) - dotab - dota[lowerl:upperl] %*%
                           t(rep.int(1, n)))) %*% z
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        exp(sigma * (
          2 * x[lowerl:n, ] %*% t(x) - rep.int(1, n + 1 - lowerl) %*% t(dota) - dota[lowerl:n] %*%
            t(rep.int(1, n))
        )) %*% z
      
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      dotb <- as.matrix(rowSums(y * y))
      
      if (nblocks > 0)
      {
        dotbb <-  rep(1, blocksize) %*% t(dotb)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            exp(sigma * (2 * x[lowerl:upperl, ] %*% t(y) - dotbb - dota[lowerl:upperl] %*%
                           t(rep.int(1, n2)))) %*% z
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        exp(sigma * (
          2 * x[lowerl:n, ] %*% t(y) - rep.int(1, n + 1 - lowerl) %*% t(dotb) - dota[lowerl:n] %*%
            t(rep.int(1, n2))
        )) %*% z
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "rbfkernel"),
          kernelMult.rbfkernel)


kernelMult.laplacekernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or a vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    sigma <- kpar(kernel)$sigma
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    dota <- as.matrix(rowSums(x ^ 2))
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      if (nblocks > 0)
      {
        dotab <- rep(1, blocksize) %*% t(dota)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            exp(-sigma * sqrt(-round(
              2 * x[lowerl:upperl, ] %*% t(x) - dotab - dota[lowerl:upperl] %*% t(rep.int(1, n)), 9
            ))) %*% z
          lowerl <- upperl + 1
          
        }
      }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        exp(-sigma * sqrt(-round(
          2 * x[lowerl:n, ] %*% t(x) - rep.int(1, n + 1 - lowerl) %*% t(dota) - dota[lowerl:n] %*%
            t(rep.int(1, n)),
          9
        ))) %*% z
      
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      dotb <- as.matrix(rowSums(y * y))
      
      if (nblocks > 0)
      {
        dotbb <-  rep(1, blocksize) %*% t(dotb)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            exp(-sigma * sqrt(-round(
              2 * x[lowerl:upperl, ] %*% t(y) - dotbb - dota[lowerl:upperl] %*% t(rep.int(1, n2)), 9
            ))) %*% z
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        exp(-sigma * sqrt(-round(
          2 * x[lowerl:n, ] %*% t(y) - rep.int(1, n + 1 - lowerl) %*% t(dotb) - dota[lowerl:n] %*%
            t(rep.int(1, n2)),
          9
        ))) %*% z
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "laplacekernel"),
          kernelMult.laplacekernel)



kernelMult.besselkernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    sigma <- kpar(kernel)$sigma
    nu <- kpar(kernel)$order
    ni <- kpar(kernel)$degree
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    lim <- 1 / (gamma(nu + 1) * 2 ^ (nu))
    dota <- as.matrix(rowSums(x ^ 2))
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      if (nblocks > 0)
      {
        dotab <- rep(1, blocksize) %*% t(dota)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          
          xx <-
            sigma * sqrt(-round(2 * x[lowerl:upperl, ] %*% t(x) - dotab - dota[lowerl:upperl] %*%
                                  t(rep.int(1, n)), 9))
          res1 <- besselJ(xx, nu) * (xx ^ (-nu))
          res1[which(xx < 10e-5)] <- lim
          
          res[lowerl:upperl, ] <- ((res1 / lim) ^ ni) %*% z
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
      {
        xx <-
          sigma * sqrt(-round(
            2 * x[lowerl:n, ] %*% t(x) - rep.int(1, n + 1 - lowerl) %*% t(dota) - dota[lowerl:n] %*%
              t(rep.int(1, n)),
            9
          ))
        res1 <- besselJ(xx, nu) * (xx ^ (-nu))
        res1[which(xx < 10e-5)] <- lim
        res[lowerl:n, ] <- ((res1 / lim) ^ ni) %*% z
      }
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      dotb <- as.matrix(rowSums(y * y))
      
      if (nblocks > 0)
      {
        dotbb <-  rep(1, blocksize) %*% t(dotb)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          xx <-
            sigma * sqrt(-round(2 * x[lowerl:upperl, ] %*% t(y) - dotbb - dota[lowerl:upperl] %*%
                                  t(rep.int(1, n2)), 9))
          res1 <- besselJ(xx, nu) * (xx ^ (-nu))
          res1[which(xx < 10e-5)] <- lim
          
          res[lowerl:upperl, ] <- ((res1 / lim) ^ ni) %*% z
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
      {
        xx <-
          sigma * sqrt(-round(
            2 * x[lowerl:n, ] %*% t(y) - rep.int(1, n + 1 - lowerl) %*% t(dotb) - dota[lowerl:n] %*%
              t(rep.int(1, n2)),
            9
          ))
        res1 <- besselJ(xx, nu) * (xx ^ (-nu))
        res1[which(xx < 10e-5)] <- lim
        res[lowerl:n, ] <- ((res1 / lim) ^ ni) %*% z
      }
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "besselkernel"),
          kernelMult.besselkernel)

kernelMult.anovakernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or a vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    sigma <- kpar(kernel)$sigma
    degree <- kpar(kernel)$degree
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      
      if (nblocks > 0)
      {
        a <- matrix(0, m, blocksize)
        re <- matrix(0, n, blocksize)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          for (j in 1:n)
          {
            a[rep(TRUE, m), rep(TRUE, blocksize)] <- x[j, ]
            re[j, ] <-
              colSums(exp(-sigma * (a - t(x[lowerl:upperl, ])) ^ 2)) ^ degree
          }
          res[lowerl:upperl, ] <- t(re) %*% z
          lowerl <- upperl + 1
          
        }
      }
      if (lowerl <= n) {
        a <- matrix(0, m, n - lowerl + 1)
        re <- matrix(0, n, n - lowerl + 1)
        for (j in 1:n)
        {
          a[rep(TRUE, m), rep(TRUE, n - lowerl + 1)] <- x[j, ]
          re[j, ] <-
            colSums(exp(-sigma * (a - t(x[lowerl:n, , drop = FALSE])) ^ 2)) ^ degree
        }
        res[lowerl:n, ] <- t(re) %*% z
      }
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      nblocks <- floor(n2 / blocksize)
      
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      
      if (nblocks > 0)
      {
        b <- matrix(0, m, blocksize)
        re <- matrix(0, n, blocksize)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          for (j in 1:n)
          {
            b[rep(TRUE, dim(x)[2]), rep(TRUE, blocksize)] <- x[j, ]
            re[j, ] <-
              colSums(exp(-sigma * (b - t(y[lowerl:upperl, ])) ^ 2) ^ degree)
          }
          res[, 1] <- res[, 1] + re %*% z[lowerl:upperl, ]
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
      {
        b <- matrix(0, dim(x)[2], n2 - lowerl + 1)
        re <- matrix(0, n, n2 - lowerl + 1)
        for (i in 1:n)
        {
          b[rep(TRUE, dim(x)[2]), rep(TRUE, n2 - lowerl + 1)] <- x[i, ]
          re[i, ] <-
            colSums(exp(-sigma * (b - t(y[lowerl:n2, , drop = FALSE])) ^ 2) ^ degree)
        }
        
        res[, 1] <- res[, 1] + re %*% z[lowerl:n2]
      }
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "anovakernel"),
          kernelMult.anovakernel)



kernelMult.splinekernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or a vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    n <- dim(x)[1]
    m <- dim(x)[2]
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      x <- t(x)
      if (nblocks > 0)
      {
        re <- matrix(0, dim(z)[1], blocksize)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          
          for (j in lowerl:upperl)
          {
            dr <-  x + x[, j]
            dp <-  x * x[, j]
            dm <-  pmin(x, x[, j])
            re[, j - (i - 1) * blocksize] <-
              apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
          }
          res[lowerl:upperl, ] <- crossprod(re, z)
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n) {
        a <- matrix(0, m, n - lowerl + 1)
        re <- matrix(0, dim(z)[1], n - lowerl + 1)
        for (j in lowerl:(n - lowerl + 1))
        {
          dr <- x + x[, j]
          dp <- x * x[, j]
          dm <-  pmin(x, x[, j])
          re[, j - nblocks * blocksize] <-
            apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
        }
        res[lowerl:n, ] <- crossprod(re, z)
      }
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      nblocks <- floor(n2 / blocksize)
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      x <- t(x)
      y <- t(y)
      if (nblocks > 0)
      {
        re <- matrix(0, dim(z)[1], blocksize)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          
          for (j in lowerl:upperl)
          {
            dr <- y + x[, j]
            dp <- y * x[, j]
            dm <- pmin(y, x[, j])
            re[, j - (i - 1) * blocksize] <-
              apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
          }
          res[lowerl:upperl] <- crossprod(re, z)
          lowerl <- upperl + 1
        }
      }
      if (lowerl <= n)
      {
        b <- matrix(0, dim(x)[2], n - lowerl + 1)
        re <- matrix(0, dim(z)[1], n - lowerl + 1)
        for (j in lowerl:(n - lowerl + 1))
        {
          dr <- y + x[, j]
          dp <- y * x[, j]
          dm <-  pmin(y, x[, j])
          re[, j - nblocks * blocksize] <-
            apply((1 + dp + dp * dm - (dr / 2) * dm ^ 2 + (dm ^ 3) / 3), 2, prod)
        }
        res[lowerl:n] <-  crossprod(re, z)
      }
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "splinekernel"),
          kernelMult.splinekernel)


kernelMult.polykernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    degree <- kpar(kernel)$degree
    scale <- kpar(kernel)$scale
    offset <- kpar(kernel)$offset
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    if (is.null(y))
    {
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      if (nblocks > 0)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            ((scale * x[lowerl:upperl, ] %*% t(x) + offset) ^ degree) %*% z
          lowerl <- upperl + 1
        }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        ((scale * x[lowerl:n, ] %*% t(x) + offset) ^ degree) %*% z
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      
      if (nblocks > 0)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            ((scale * x[lowerl:upperl, ] %*% t(y) + offset) ^ degree) %*% z
          lowerl <- upperl + 1
        }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        ((scale * x[lowerl:n, ] %*% t(y) + offset) ^ degree) %*% z
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "polykernel"),
          kernelMult.polykernel)


kernelMult.tanhkernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or a vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    scale <- kpar(kernel)$scale
    offset <- kpar(kernel)$offset
    n <- dim(x)[1]
    m <- dim(x)[2]
    nblocks <- floor(n / blocksize)
    lowerl <- 1
    upperl <- 0
    
    
    if (is.null(y))
    {
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      if (nblocks > 0)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            tanh(scale * x[lowerl:upperl, ] %*% t(x) + offset) %*% z
          lowerl <- upperl + 1
        }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        tanh(scale * x[lowerl:n, ] %*% t(x) + offset) %*% z
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- matrix(rep(0, dim(z)[2] * n), ncol = dim(z)[2])
      
      if (nblocks > 0)
        for (i in 1:nblocks)
        {
          upperl = upperl + blocksize
          res[lowerl:upperl, ] <-
            tanh(scale * x[lowerl:upperl, ] %*% t(y) + offset) %*% z
          lowerl <- upperl + 1
        }
      if (lowerl <= n)
        res[lowerl:n, ] <-
        tanh(scale * x[lowerl:n, ] %*% t(y) + offset) %*% z
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "tanhkernel"),
          kernelMult.tanhkernel)


kernelMult.vanillakernel <-
  function(kernel,
           x,
           y = NULL,
           z,
           blocksize = 256)
  {
    if (!is(y, "matrix") &&
        !is.null(y) && !is(y, "vector"))
      stop("y must be a matrix or vector")
    if (!is(z, "matrix") &&
        !is(z, "vector"))
      stop("z must be a matrix or a vector")
    n <- dim(x)[1]
    m <- dim(x)[2]
    if (is(x, "vector"))
      x <- as.matrix(x)
    if (is(y, "vector"))
      y <- as.matrix(y)
    if (is.null(y))
    {
      z <- as.matrix(z)
      if (!dim(z)[1] == n)
        stop("z rows must equal x rows")
      res <- t(crossprod(crossprod(x, z), t(x)))
    }
    if (is(y, "matrix"))
    {
      n2 <- dim(y)[1]
      z <- as.matrix(z)
      
      if (!dim(z)[1] == n2)
        stop("z length must equal y rows")
      res <- t(crossprod(crossprod(y, z), t(x)))
    }
    return(res)
  }
setMethod("kernelMult",
          signature(kernel = "vanillakernel"),
          kernelMult.vanillakernel)


## kernelPol return the quadratic form of a kernel matrix
## kernelPol returns the scalar product of x y componentwise with polarities
## of z and k

kernelPol <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(x, "matrix"))
    stop("x must be a matrix")
  if (!is(y, "matrix") && !is.null(y))
    stop("y must be a matrix")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must ba a matrix or a vector")
  n <- nrow(x)
  z <- as.matrix(z)
  
  
  if (!dim(z)[1] == n)
    stop("z must have the length equal to x colums")
  res1 <- matrix(rep(0, n * n), ncol = n)
  if (is.null(y))
  {
    for (i in 1:n)
    {
      for (j in i:n)
      {
        res1[i, j] <- kernel(x[i, ], x[j, ]) * z[j] * z[i]
      }
    }
    res1 <- res1 + t(res1)
    diag(res1) <- diag(res1) / 2
  }
  if (is(x, "matrix") && is(y, "matrix")) {
    m <- dim(y)[1]
    if (is.null(k))
      stop("k not specified!")
    k <- as.matrix(k)
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    if (!dim(z)[2] == dim(k)[2])
      stop("z and k vectors must have the same number of columns")
    if (!dim(x)[1] == dim(z)[1])
      stop("z and x must have the same number of rows")
    if (!dim(y)[1] == dim(k)[1])
      stop("y and k must have the same number of rows")
    res1 <- matrix(0, dim(x)[1], dim(y)[1])
    for (i in 1:n)
    {
      for (j in 1:m)
      {
        res1[i, j] <- kernel(x[i, ], y[j, ]) * z[i] * k[j]
      }
    }
  }
  return(res1)
}

setGeneric("kernelPol", function(kernel, x, y = NULL, z, k = NULL)
  standardGeneric("kernelPol"))


kernelPol.rbfkernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) &&
      !is(y, "vector"))
    stop("y must be a matrix a vector or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  sigma <- kpar(kernel)$sigma
  n <- dim(x)[1]
  dota <- rowSums(x * x) / 2
  z <- as.matrix(z)
  if (!dim(z)[1] == n)
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    if (is(z, "matrix") && !dim(z)[1] == n)
      stop("z must have size equal to x colums")
    res <- crossprod(t(x))
    for (i in 1:n)
      res[i, ] <-
      z[i, ] * (exp(2 * sigma * (res[i, ] - dota - rep(dota[i], n))) * z)
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.matrix(k)
    if (!dim(k)[1] == m)
      stop("k must have equal rows to y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      #2*sigma or sigma
      res[, i] <-
      k[i, ] * (exp(2 * sigma * (res[, i] - dota - rep(dotb[i], n))) * z)
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "rbfkernel"),
          kernelPol.rbfkernel)

kernelPol.laplacekernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) &&
      !is(y, "vector"))
    stop("y must be a matrix, vector or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  sigma <- kpar(kernel)$sigma
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  n <- dim(x)[1]
  dota <- rowSums(x * x) / 2
  z <- as.matrix(z)
  if (!dim(z)[1] == n)
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    if (is(z, "matrix") && !dim(z)[1] == n)
      stop("z must have size equal to x colums")
    res <- crossprod(t(x))
    for (i in 1:n)
      res[i, ] <-
      z[i, ] * (exp(-sigma * sqrt(-round(
        2 * (res[i, ] - dota - rep(dota[i], n)), 9
      ))) * z)
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.matrix(k)
    if (!dim(k)[1] == m)
      stop("k must have equal rows to y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      #2*sigma or sigma
      res[, i] <-
      k[i, ] * (exp(-sigma * sqrt(-round(
        2 * (res[, i] - dota - rep(dotb[i], n)), 9
      ))) * z)
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "laplacekernel"),
          kernelPol.laplacekernel)


kernelPol.besselkernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) && !is(y, "vector"))
    stop("y must be a matrix or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  sigma <- kpar(kernel)$sigma
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  nu <- kpar(kernel)$order
  ni <- kpar(kernel)$degree
  n <- dim(x)[1]
  lim <- 1 / (gamma(nu + 1) * 2 ^ nu)
  dota <- rowSums(x * x) / 2
  z <- as.matrix(z)
  
  if (!dim(z)[1] == n)
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    if (is(z, "matrix") && !dim(z)[1] == n)
      stop("z must have size equal to x colums")
    res <- crossprod(t(x))
    for (i in 1:n)
    {
      xx <- sigma * sqrt(-round(2 * (res[i, ] - dota - rep(dota[i], n)), 9))
      res[i, ] <- besselJ(xx, nu) * (xx ^ (-nu))
      res[i, which(xx < 10e-5)] <- lim
      res[i, ] <- z[i, ] * (((res[i, ] / lim) ^ ni) * z)
    }
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    if (!dim(k)[1] == m)
      stop("k must have equal rows to y")
    k <- as.matrix(k)
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m) {
      #2*sigma or sigma
      xx <-
        sigma * sqrt(-round(2 * (res[, i] - dota - rep(dotb[i], n)), 9))
      res[, i] <- besselJ(xx, nu) * (xx ^ (-nu))
      res[which(xx < 10e-5), i] <- lim
      res[, i] <- k[i, ] * (((res[, i] / lim) ^ ni) * z)
    }
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "besselkernel"),
          kernelPol.besselkernel)


kernelPol.anovakernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) && !is(y, "vector"))
    stop("y must be a matrix or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  sigma <- kpar(kernel)$sigma
  degree <- kpar(kernel)$degree
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  n <- dim(x)[1]
  z <- as.matrix(z)
  if (!dim(z)[1] == n)
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    if (is(z, "matrix") && !dim(z)[1] == n)
      stop("z must have size equal to x colums")
    a <- matrix(0, dim(x)[2], n)
    res <- matrix(0, n, n)
    for (i in 1:n)
    {
      a[rep(TRUE, dim(x)[2]), rep(TRUE, n)] <- x[i, ]
      res[i, ] <-
        z[i, ] * ((colSums(exp(
          -sigma * (a - t(x)) ^ 2
        )) ^ degree) * z)
    }
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.matrix(k)
    if (!dim(k)[1] == m)
      stop("k must have equal rows to y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    
    b <- matrix(0, dim(x)[2], m)
    res <- matrix(0, dim(x)[1], m)
    for (i in 1:n)
    {
      b[rep(TRUE, dim(x)[2]), rep(TRUE, m)] <- x[i, ]
      res[i, ] <-
        z[i, ] * ((colSums(exp(
          -sigma * (b - t(y)) ^ 2
        )) ^ degree) * k)
    }
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "anovakernel"),
          kernelPol.anovakernel)


kernelPol.splinekernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) && !is(y, "vector"))
    stop("y must be a matrix or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  sigma <- kpar(kernel)$sigma
  degree <- kpar(kernel)$degree
  n <- dim(x)[1]
  z <- as.vector(z)
  if (!(length(z) == n))
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    res <- kernelMatrix(kernel, x)
    return(unclass(z * t(res * z)))
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.vector(k)
    if (!(length(k) == m))
      stop("k must have length equal to rows of y")
    
    res <- kernelMatrix(kernel, x, y)
    return(unclass(k * t(res * z)))
  }
}
setMethod("kernelPol",
          signature(kernel = "splinekernel"),
          kernelPol.splinekernel)


kernelPol.polykernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) && !is(y, "vector"))
    stop("y must be a matrix or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  degree <- kpar(kernel)$degree
  scale <- kpar(kernel)$scale
  offset <- kpar(kernel)$offset
  n <- dim(x)[1]
  
  if (is(z, "matrix"))
  {
    z <- as.vector(z)
  }
  m <- length(z)
  
  if (!(m == n))
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    res <- z * t(((scale * crossprod(t(
      x
    )) + offset) ^ degree) * z)
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.vector(k)
    if (!(length(k) == m))
      stop("k must have length equal to rows of y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes must have the same number of columns")
    res <- k * t(((scale * x %*% t(y) + offset) ^ degree) * z)
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "polykernel"),
          kernelPol.polykernel)


kernelPol.tanhkernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) &&
      !is(y, "vector"))
    stop("y must be a matrix, vector or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  scale <- kpar(kernel)$scale
  offset <- kpar(kernel)$offset
  n <- dim(x)[1]
  if (is(z, "matrix"))
  {
    z <- as.vector(z)
  }
  m <- length(z)
  
  if (!(m == n))
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    res <- z * t(tanh(scale * crossprod(t(x)) + offset) * z)
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.vector(k)
    if (!(length(k) == m))
      stop("k must have length equal rows to y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes x, y must have the same number of columns")
    res <- k * t(tanh(scale * x %*% t(y) + offset) * z)
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "tanhkernel"),
          kernelPol.tanhkernel)


kernelPol.vanillakernel <- function(kernel, x, y = NULL, z, k = NULL)
{
  if (!is(y, "matrix") &&
      !is.null(y) &&
      !is(y, "vector"))
    stop("y must be a matrix, vector or NULL")
  if (!is(z, "matrix") &&
      !is(z, "vector"))
    stop("z must be a matrix or a vector")
  if (!is(k, "matrix") &&
      !is(k, "vector") &&
      !is.null(k))
    stop("k must be a matrix or a vector")
  n <- dim(x)[1]
  if (is(z, "matrix"))
  {
    z <- as.vector(z)
  }
  m <- length(z)
  
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!(m == n))
    stop("z must have the length equal to x colums")
  if (is.null(y))
  {
    res <- z * t(crossprod(t(x)) * z)
    return(res)
  }
  if (is(y, "matrix"))
  {
    if (is.null(k))
      stop("k not specified!")
    m <- dim(y)[1]
    k <- as.vector(k)
    if (!length(k) == m)
      stop("k must have length equal rows to y")
    if (!dim(x)[2] == dim(y)[2])
      stop("matrixes x, y must have the same number of columns")
    for (i in 1:m)
      res <- k * t(x %*% t(y) * z)
    return(res)
  }
}
setMethod("kernelPol",
          signature(kernel = "vanillakernel"),
          kernelPol.vanillakernel)

## kernelFast returns the kernel matrix, its usefull in algorithms
## which require iterative kernel matrix computations

kernelFast <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setGeneric("kernelFast", function(kernel, x, y, a)
  standardGeneric("kernelFast"))



kernelFast.rbfkernel <- function(kernel, x, y, a)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix"))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  n <- dim(x)[1]
  dota <- a / 2
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      res[, i] <- exp(2 * sigma * (res[, i] - dota - rep(dotb[i], n)))
    return(res)
  }
}
setMethod("kernelFast",
          signature(kernel = "rbfkernel"),
          kernelFast.rbfkernel)

kernelFast.laplacekernel <- function(kernel, x, y, a)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix"))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  n <- dim(x)[1]
  dota <- a / 2
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m)
      res[, i] <-
      exp(-sigma * sqrt(round(-2 * (
        res[, i] - dota - rep(dotb[i], n)
      ), 9)))
    return(res)
  }
}
setMethod("kernelFast",
          signature(kernel = "laplacekernel"),
          kernelFast.laplacekernel)

kernelFast.besselkernel <- function(kernel, x, y, a)
{
  if (is(x, "vector"))
    x <- as.matrix(x)
  if (is(y, "vector"))
    y <- as.matrix(y)
  if (!is(y, "matrix"))
    stop("y must be a matrix or a vector")
  sigma = kpar(kernel)$sigma
  nu = kpar(kernel)$order
  ni = kpar(kernel)$degree
  n <- dim(x)[1]
  lim <- 1 / (gamma(nu + 1) * 2 ^ (nu))
  dota <- a / 2
  if (is(x, "matrix") && is(y, "matrix")) {
    if (!(dim(x)[2] == dim(y)[2]))
      stop("matrixes must have the same number of columns")
    m <- dim(y)[1]
    dotb <- rowSums(y * y) / 2
    res <- x %*% t(y)
    for (i in 1:m) {
      xx <- sigma * sqrt(round(-2 * (res[, i] - dota - rep(dotb[i], n)), 9))
      res[, i] <- besselJ(xx, nu) * (xx ^ (-nu))
      res[which(xx < 10e-5), i] <- lim
    }
    return((res / lim) ^ ni)
  }
}
setMethod("kernelFast",
          signature(kernel = "besselkernel"),
          kernelFast.besselkernel)


kernelFast.anovakernel <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setMethod("kernelFast",
          signature(kernel = "anovakernel"),
          kernelFast.anovakernel)


kernelFast.polykernel <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setMethod("kernelFast",
          signature(kernel = "polykernel"),
          kernelFast.polykernel)

kernelFast.vanilla <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setMethod("kernelFast",
          signature(kernel = "vanillakernel"),
          kernelFast.vanilla)

kernelFast.tanhkernel <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setMethod("kernelFast",
          signature(kernel = "tanhkernel"),
          kernelFast.tanhkernel)

kernelFast.splinekernel <- function(kernel, x, y, a)
{
  return(kernelMatrix(kernel, x, y))
}
setMethod("kernelFast",
          signature(kernel = "splinekernel"),
          kernelFast.splinekernel)

Try the kerndwd package in your browser

Any scripts or data that you put into this service are public.

kerndwd documentation built on Sept. 4, 2020, 1:08 a.m.