#' Calculate the Variance explained by Spectral Principal Components
#'
#' This function estimates the (theoretical) fraction of the variance explained
#' by each spectral principal component for some spatial functional data.
#' @param FS the spectral density.
#' @return the fraction of the variance explained by each PC.
#' @seealso \code{\link{fsd.spca}}
#' @details To ensure accuracy of numerical integration, the frequencies of
#'   \code{FS} should be a suitably dense grid. In order for the estimations to
#'   conform with the actual variance explained (1 - NMSE), the tuning
#'   parameters in the estimation of the spectral density need to be chosen
#'   carefully.
#' @keywords fsd
#' @export

fsd.spca.var = function (FS)
{
  if (!inherits(FS, "fsd.freqdom"))
    stop("FS needs to be a spectral density operator")

  if (!is.null(FS$basis)) {
    B = inprod(FS$basis, FS$basis)
  } else {
    B = diag(dim(FS$operators[[1]])[1])
  }
  B.root = eigen(B)$vectors %*% diag(sqrt(eigen(B)$values)) %*%
    t(eigen(B)$vectors)
  for (i in 1:length(FS$operators)) {
    FS$operators[[i]] = B.root %*% FS$operators[[i]] %*% B.root
  }

  FS.E = sapply(FS$operators,
               function(w) {eigen(w, symmetric = TRUE,
                                  only.values = TRUE)$values},
               simplify="array")

  E.int = apply(pmax(Re(FS.E), 0), 1, sum)
  names(E.int) = paste("PC", 1:dim(FS.E)[1])

  E.int/sum(E.int)
}
