# Function to permute arrays of non-atomic elements (e.g. POSIXct)
.aperm2 <- function(x, new_order) {
  old_dims <- dim(x)
  attr_bk <- attributes(x)
  if ('dim' %in% names(attr_bk)) {
    attr_bk[['dim']] <- NULL
  }
  if (is.numeric(x)) {
    x <- aperm(x, new_order)
  } else {
    y <- array(1:length(x), dim = dim(x))
    y <- aperm(y, new_order)
    x <- x[as.vector(y)]
  }
  dim(x) <- old_dims[new_order]
  attributes(x) <- c(attributes(x), attr_bk)
  x
}

# Auxiliar function to compute the mean squared error between 'exp' and 'obs'
Sigma_notBC <- function(exp, obs) {
    return(sqrt(verify(obs, exp, frcst.type = "cont",
                       obs.type = "cont")$MSE))
}

# Auxiliar function to compute the bias between 'exp' and 'obs'
MEBC <- function(exp, obs) {
    return(verify(obs, exp, frcst.type = "cont",
                  obs.type = "cont")$ME)
}

# Auxiliar function to compute the standard deviation of errors
# between 'obs' and 'exp'
Sigma_BC <- function(exp, obs, na.rm = FALSE) {
    return(sd(obs - exp, na.rm = na.rm))
}

# Auxiliar function to compute the linear model used in the method
# called 'LMEV' to correct the bias in the Best NAO weighting 
# methogology 
LMEV <- function(exp, obs, na.rm = FALSE) {
    if (any(names(dim(exp)) == 'member')) {
        exp_ens_mean <- Apply(list(exp), target_dims = 'member',
                              fun = mean, na.rm = na.rm)$output1
        exp_ens_sd <- Apply(list(exp), target_dims = 'member',
                            fun = sd, na.rm = na.rm)$output1
    } else {
        pos <- match(c('time','statistic'), names(dim(exp)))
        exp <- aperm(exp,pos)
        exp_ens_mean <- exp[,1]
        exp_ens_sd <- exp[,2]
    }
    error <- exp_ens_mean - obs
    exp_ens_var <- exp_ens_sd^2
    statModel <- lm(error ~ exp_ens_var)
    return(list(coeff1 = statModel$coefficients[1], coeff2 = statModel$coefficients[2]))
}

