#' Normalized Dissimilarity Score
#'
#' @description
#'
#' Demonstration function to compute the `psi` dissimilarity score (Birks and Gordon 1985). Psi is computed as \eqn{\psi = (2a / b) - 1}, where \eqn{a} is the sum of distances between the relevant samples of two time series, and \eqn{b} is the cumulative sum of distances between consecutive samples in the two time series.
#'
#' When `diagonal = TRUE`, one is added to the result of the equation above.
#'
#' @param a (required, numeric) Result of [psi_cost_path_sum()], the sum of distances of the least cost path between two time series. Default: NULL
#' @param b (required, numeric) Result of [psi_auto_sum()], the cumulative sum of the consecutive cases of two time series. Default: NULL
#' @param diagonal (optional, logical) Used to correct `psi` when diagonals are used during the computation of the least cost path. If the cost matrix and least cost path were computed using `diagonal = TRUE`, this argument should be `TRUE` as well. Default: TRUE
#'
#' @details
#' When `b` is zero (both series are perfectly flat with no variation between
#' consecutive samples), the function returns `NA` because the normalisation
#' denominator is undefined.
#'
#' @return numeric value
#' @examples
#' #distance metric
#' d <- "euclidean"
#'
#' #use diagonals in least cost computations
#' diagonal <- TRUE
#'
#' #simulate two irregular time series
#' x <- zoo_simulate(
#'   name = "x",
#'   rows = 100,
#'   seasons = 2,
#'   seed = 1
#'   )
#'
#' y <- zoo_simulate(
#'   name = "y",
#'   rows = 80,
#'   seasons = 2,
#'   seed = 2
#'   )
#'
#' if(interactive()){
#'   zoo_plot(x = x)
#'   zoo_plot(x = y)
#' }
#'
#' #dynamic time warping
#'
#' #distance matrix
#' dist_matrix <- psi_distance_matrix(
#'   x = x,
#'   y = y,
#'   distance = d
#' )
#'
#' #cost matrix
#' cost_matrix <- psi_cost_matrix(
#'   dist_matrix = dist_matrix,
#'   diagonal = diagonal
#' )
#'
#' #least cost path
#' cost_path <- psi_cost_path(
#'   dist_matrix = dist_matrix,
#'   cost_matrix = cost_matrix,
#'   diagonal = diagonal
#' )
#'
#' if(interactive()){
#'   utils_matrix_plot(
#'     m = cost_matrix,
#'     path = cost_path
#'     )
#' }
#'
#'
#' #computation of psi score
#'
#' #sum of distances in least cost path
#' a <- psi_cost_path_sum(
#'   path = cost_path
#'   )
#'
#' #auto sum of both time series
#' b <- psi_auto_sum(
#'   x = x,
#'   y = y,
#'   distance = d
#' )
#'
#' #dissimilarity score
#' psi_equation(
#'   a = a,
#'   b = b,
#'   diagonal = diagonal
#' )
#'
#' #full computation with distantia()
#' tsl <- list(
#'   x = x,
#'   y = y
#' )
#'
#' distantia(
#'   tsl = tsl,
#'   distance = d,
#'   diagonal = diagonal
#' )$psi
#'
#' if(interactive()){
#'   distantia_dtw_plot(
#'     tsl = tsl,
#'     distance = d,
#'     diagonal = diagonal
#'   )
#' }
#' @autoglobal
#' @export
#' @family psi_demo
psi_equation <- function(
    a = NULL,
    b = NULL,
    diagonal = TRUE
    ){

  if(!is.numeric(a)){
    stop("distantia::psi_equation(): argument 'a' must be numeric.", call. = FALSE)
  }

  if(!is.numeric(b)){
    stop("distantia::psi_equation(): argument 'b' must be numeric.", call. = FALSE)
  }

  if(is.logical(diagonal) == FALSE){
    stop("distantia::psi_equation(): argument 'diagonal' must be logical.", call. = FALSE)
  }

  psi_equation_cpp(
    a,
    b,
    diagonal
  )

}

