R/mode.in.R

Defines functions mode.bind mode.out mode.in

Documented in mode.bind mode.in mode.out

#' @title Add / Remove / Bind modes in emd objects
#'
#' @param emd emd-type object
#' @param obj emd or pulse type object
#' @param xy an Instrinsic Mode Function to add
#' @param mode,keep,lose [mode.in] the position where to add the mode /
#' [mode.out] the modes to keep or lose / [mode.bind] the modes to merge
#' @param adjust whether to adapt the initial signal of an emd object ($xy in
#' the emd object) when adding or removing a mode
#' @param name the name of the new mode
#' @param reorder whether to reinitialise the index of modes when suppressing
#' one
#'
#' @examples
#' set.seed(42)
#'
#' n <- 600
#' t <- seq_len(n)
#'
#' p1 <- 30
#' p2 <- 240
#'
#' xy <- (1 + 0.6 * sin(t*2*pi/p2)) * sin(t*2*pi/p1)  + 2 * sin(t*2*pi/p2) +
#'   rnorm(n, sd = 0.5)
#'
#' inter_dt <- round(runif(length(xy), min = 0.5, max = 1.5),1)
#'
#' dt <- cumsum(inter_dt)
#'
#' dec <- extricate(xy, dt, nimf = 7, sifting = 10,
#'                  repl = 10, comb = 10, factor_noise = 10,
#'                  speak = TRUE)
#'
#' opar <- par('mfrow')
#'
#' par(mfrow = c(2,1))
#'
#' integrity(xy, dec)
#'
#' ht  <- inst.pulse(dec, plot = FALSE)
#'
#' plot_hist(x = 1/ht$f, breaks = 500, id = ht$mode,
#'           xlog = TRUE, text = TRUE, xlab = "Period",
#'           main = "Initial Decomposition")
#'
#' bound <- mode.bind(dec, mode = c(6,7))
#'
#' ht2  <- inst.pulse(bound, plot = FALSE)
#'
#' plot_hist(x = 1/ht2$f, breaks = 500, id = ht2$mode,
#'           xlog = TRUE, text = TRUE, xlab = "Period",
#'           main = "Binding of modes 6 and 7")
#'
#' par(mfrow = opar)
#'
#' \dontrun{
#' plot_emd(bound, dir = tempdir(), adapt.axis = TRUE)}
#'
#' @importFrom StratigrapheR seq_mult
#' @export

mode.in <- function(emd, xy, mode = NA, adjust = TRUE, name = "Added")
{

  if(!is.emd(emd)) stop("Incorrect 'emd' object")

  repl  <- unique(emd$repl[1,])
  repln <- length(repl)

  nimf <- ncol(emd$m)/repln
  nc   <- nrow(emd$m)

  omode <- unique(emd$mode[1,])

  if(any(is.na(mode))) mode <- max(omode) + 1

  xy <- as.vector(xy)

  lxy <- length(xy)

  if(lxy == nc){

    if(adjust) rexy <- emd$xy + xy else rexy <- emd$xy

    addxy <- rep(xy, repln)

  } else if(lxy != repln * nc){

    stop("'xy' should have the same number of elements than the original ",
         "signal [length(emd$dt)], or that length multiplied by the number of",
         " replicates [max(emd$repl) * length(emd$dt)]")

  } else {

    if(adjust) {
      stop("to add 'xy' to the original signal, it should have ",
           "the same number of elements than the original ",
           "signal [length(emd$dt)]")
    } else {
      rexy  <- emd$xy
      addxy <- xy
    }

  }

  addxy   <- matrix(addxy, ncol = repln)

  colnames(addxy) <- paste(name ,"M", mode, "R",
                           repl, sep = "")

  # change m and mode ----

  seq1 <- seq_mult(nimf * repln, nimf)
  seq2 <- seq_mult((nimf + 1) * repln, repln)

  o <- emd$mode[,seq1]

  low  <- o[1,] < mode
  high <- o[1,] >= mode

  nmode <- emd$mode[1, seq_len(nimf)]

  hmode <- nmode[nmode >= mode]
  if(any(omode == mode))  hmode <- hmode +1
  nmode <- c(nmode[nmode < mode], mode,  hmode)

  om <- emd$m[,seq1]
  nm <- cbind(om[,low], addxy,om[,high])[,seq2]

  output <- as.emd(rexy, emd$dt, imf = nm, ini = emd$ini,
                   repl = repl, mode = nmode)

  return(output)

}

#' @rdname mode.in
#' @export

mode.out <- function(obj, keep = NULL, lose = NULL, adjust = F, reorder = F)
{

  if(is.null(keep) & is.null(lose)) return(obj)

  isemd <- suppressWarnings(is.emd(obj))
  ispul <- suppressWarnings(is.pulse(obj))

  if(!isemd & !ispul) {
    stop("The 'obj' parameter should be an emd or pulse object. Use is.emd()",
         "or is.pulse on the object for more precision")
  } else if(isemd & ispul){
    stop("The 'obj' parameter should be either an emd object or a pulse",
         " object. Not both. But nice try anyway !")
  }

  repl  <- unique(obj$repl[1,])
  repln <- length(repl)

  if(isemd & adjust & repln != 1) {
    stop("To adjust, the number of replicates in the 'emd' object should be 1")
  }

  mode <- keep

  if(is.null(keep)){
    is   <- unique(obj$mode[1,])
    mode <- is[!(is %in% lose)]
  }

  out    <- obj$mode[1,] %in% mode

  keep_mode <- rep(mode, repln)
  keep_mode <- matrix(rep(keep_mode, each = nrow(obj$mode)),
                      nrow = nrow(obj$mode))

  if(isTRUE(reorder)) modeout <- NULL else modeout <- mode

  if(isemd){

    keep_m <- obj$m[,out,drop = F]

    output <- as.emd(obj$xy, obj$dt, imf = keep_m, ini = obj$ini,
                     mode = modeout, repl = repl)

    if(isemd & adjust){

      if(sum(!out) == 1) {
        remove_m <- obj$m[,!out]
      } else {
        remove_m  <- rowSums(obj$m[,!out])
      }

      rexy      <- obj$xy - remove_m
      output$xy <- rexy

    }

  } else if(ispul){

    keep_f <- obj$f[,out,drop = F]
    keep_a <- obj$a[,out,drop = F]

    output <- as.pulse(obj$dt, f = keep_f, a = keep_a,
                       mode = modeout, repl = repl)

  }

  return(output)

}

#' @rdname mode.in
#' @export

mode.bind <- function(emd, mode = NA, xy = NULL, adjust = T,
                      name = "bound")
{

  if(!is.emd(emd)) stop("Incorrect 'emd' object")

  repl  <- unique(emd$repl[,1])
  repln <- length(repl)

  if(all(is.na(mode))) mode <- max(unique(emd$mode[1,]))

  if(length(xy) == 1) xy <- rep(xy, nrow(emd$m))

  if(length(xy) != 0) {
    emd  <- mode.in(emd, xy, mode = max(mode) + 1, adjust = adjust)
    mode <- c(mode, max(mode) + 1)
  }

  bound   <- condense(emd$m[,emd$mode[1,] %in% mode],
                      length(mode), fun = "sum")
  cleaned <- mode.out(emd, lose = mode, adjust = F, reorder = T)
  output  <- mode.in(cleaned, xy = bound, mode = min(mode), adjust = F,
                     name = name)

  return(output)

}

Try the DecomposeR package in your browser

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

DecomposeR documentation built on Feb. 16, 2023, 9:50 p.m.