
smooth_to_t <- function(y, t) {
  t <- seq_along(t)

  if (ceiling(length(y) / b) > length(t))
    y <- y[seq(length.out=length(t)+2, by=b)]
  if (length(y) > length(t))
    y <- y[seq.int(length(t))]
  for (i in 1:2)
    y <- (predict(loess(y ~t)))
  y %<>% round
  y <- y - min(y)
  return(y)
}

rand_norm <- function(t, N, b, mean=100, sd=100, seed=1, ...) {
  t <- seq_along(t)

  set.seed(seed)
  y <- rnorm(N, mean, sd) %>% sort
  y %<>% smooth_to_t(t)
  return(y)
}

rand_exp <- function(t, N, b, rate=5e-3, seed=1, ...) {
  set.seed(seed)
  y <- rexp(N, rate) %>% sort
  y %<>% smooth_to_t(t)
  return(y)
}

cubed <- function(t, a=1.15, shift=TRUE, smooth=TRUE, ...) {
  t <- seq_along(t)
  if (shift)
    t <- t - median(t)
  y <- a * (t^3)
  if (smooth)
    y %<>% smooth_to_t(t)
  return(y)
}

squared <- function(t, a=1.15, shift=TRUE, smooth=TRUE, ...) {
  t <- seq_along(t)
  if (shift)
    t <- t - median(t)
  y <- a * (t^2)
  if (smooth)
    y %<>% smooth_to_t(t)
  return(y)
}

get_melted_DT <- function(y=y, t=t, melted=TRUE, DT, days=7, aggFunc="max") {

  if (missing(DT)) {
    DT <- data.table(streams=y, time=t)

    if (days >= 1) {
      aggFunc <- match.fun(aggFunc)
      DT[, dd := rev( (seq(.N)-1) %/% days )]
      DT <- DT[, list(streams=sumn(streams), time=aggFunc(time), time_min=min(time), time_max=max(time)), by = dd]
    }

    DT[, linear_acceleration := linear_acceleration(streams, time)]
    DT[, linear_velocity := linear_velocity(streams, time)]
    DT[, cumulative_velocity := cumulative_velocity(streams, time)]
    # DT[, log_linear_acceleration := log(linear_acceleration(streams, time))]
    # DT[, log_cumulative_velocity := log(cumulative_velocity(streams, time))]
    # DT[, log_streams := log(streams)]
  }

  if (!melted)
    return(DT)

  id.vars <- c("time", "time_min", "time_max", "dd") %>% intersect(names(DT))
  DT.melted <- reshape2::melt(DT, id.vars=c("time"), variable.name=c("method"), value.name="value")
  DT.melted[, type := removeText("log_?", method)]
  DT.melted[, what := ifelse(grepl("accel", method), "acceleration", ifelse(grepl("velocity", method), "velocity", "other"))]
  DT.melted[, method := ifelse(grepl("log", method), "log", "natural")]


  DT.melted[, value := as.numeric(value)]
  DT.melted[, time := as.Date(time, origin=.origin)]

  setkeyIfNot(DT.melted, type, method, time, value, verbose=FALSE)
  return(DT.melted)
}


cumulative_velocity <- function(v, t) {
  sapply(seq_along(v), function(i) {
    diff(v[c(1, i)]) / diff(t[c(1, i)])
  })
}
