#' @include multivariate.data.frame.R
#' @include multivariate.R
#'
NULL

#' Compute the XX' and set the diagonale to zero.
#'
#' This is an internal function.
#'
#' @param X a matrix of numeric
#'
#' @examples
#'    # Build a matrices of 3 x 4 matrix.
#'    A <- matrix(1:12,nrow=3)
#'    ..crossprod_diag0(A)
#'
#'
#' @author Eric Coissac & Christelle Gonindard-Melodelima
..tcrossprod_diag0 = function(X) {
  XX = X %*% t(X)
  diag(XX)=0
  return(XX)
}

..tcrossprod = function(X) {
  XX = X %*% t(X)
  return(XX)
}

..covv = function(...,tcp) {

  Xs <- list(...)
  if (length(Xs)==1) {
    x = Xs[[1]]
    if (is.multivariate.data.frame(x))
      Xs=x
    else if (is.pm(x))
      return(x$cov)
    else
      Xs=multivariate.data.frame(x)
  }
  else
      Xs=as.multivariate.data.frame(Xs)

    Xnames=names(Xs)

    Xs <- project(Xs)
    Xs <- as.multivariate.data.frame(mapply(tcp,
                 Xs,
                 SIMPLIFY = FALSE))

    nX <- length(Xs)

    Xx <- rep(1:nX,nX)
    Xy <- rep(1:nX,rep(nX,nX))

    n  <- nrow(Xs)

    CovXXs <- mapply(function(x,y) sum(Xs[[x]] * Xs[[y]]),
                  Xx,Xy,
                  SIMPLIFY = TRUE) / (n-1)


    dim(CovXXs)=c(nX,nX)
    colnames(CovXXs)=Xnames
    rownames(CovXXs)=Xnames

    return(CovXXs)
}

..rv = function(...,cov) {
  COV = cov(...)
  s = sqrt(diag(COV))
  VV= outer(s,s)
  return(COV/VV)
}

..rv.partial = function(...,r) {
  C = solve(sqrt(r(...)))
  D = sqrt(diag(C) %o% diag(C))
  return((C/D)^2)
}


#' Compute the variance, covariance matrix of K coordinate matrices.
#'
#' Covariance between two matrices is defined as the sum of the
#' sigular values of the X'Y matrix. All the matrices must have
#' the same number of rows.
#'
#' @param ... the set of matrices
#'
#' @examples
#'    # Build Three matrices of 3 rows.
#'    A <- matrix(1:9,nrow=3)
#'    B <- matrix(10:15,nrow=3)
#'    C <- matrix(20:31,nrow=3)
#'    # compute the variance covariance matrix
#'    covv(A,B,C)
#'    covv(A=A,B=B,C=C)
#'
#' @author Eric Coissac & Christelle Gonindard-Melodelima
#' @export
covv = function(...) {
  ..covv(...,tcp = ..tcrossprod)
}


#' Compute the variance, covariance matrix of K coordinate matrices.
#'
#' Covariance between two matrices is defined as the sum of the
#' sigular values of the X'Y matrix. All the matrices must have
#' the same number of rows.
#'
#' @param ... the set of matrices
#'
#' @examples
#'    # Build Three matrices of 3 rows.
#'    A <- matrix(1:9,nrow=3)
#'    B <- matrix(10:15,nrow=3)
#'    C <- matrix(20:31,nrow=3)
#'    # compute the variance covariance matrix
#'    covv2(A,B,C)
#'    covv2(A=A,B=B,C=C)
#'
#' @author Eric Coissac & Christelle Gonindard-Melodelima
#' @export
covv2 = function(...) {
  ..covv(...,tcp = ..tcrossprod_diag0)
}

#' Compute RV coefficient matrix of K coordinate matrices.
#'
#'
#'
#' @author Eric Coissac
#' @author Christelle Gonindard-Melodelima
#' @export
rv = function(...) {
  ..rv(...,cov = covv)
}

#' Compute RV2 coefficient matrix of K coordinate matrices.
#'
#'
#'
#' @author Eric Coissac
#' @author Christelle Gonindard-Melodelima
#' @export
rv2 = function(...) {
  ..rv(...,cov = covv2)
}


#' Compute the RV2 partial correlation matrix of K coordinate matrices
#'
#' @author Eric Coissac
#' @author Christelle Gonindard-Melodelima
#' @export
rv.partial = function(...) {
  ..rv.partial(...,r=rv)
}

#' Compute the RV2 partial correlation matrix of K coordinate matrices
#'
#' @author Eric Coissac
#' @author Christelle Gonindard-Melodelima
#' @export
rv2.partial = function(...) {
  ..rv.partial(...,r=rv2)
}


