\HeaderA{pcp}{convenience version of the singular value decomposition}{pcp}
\keyword{array}{pcp}
\keyword{algebra}{pcp}
\begin{Description}\relax
Packages results from an SVD on what can be either a cases by variables
(features) or variables by cases layout, for use in principal component
and related calculations
\end{Description}
\begin{Usage}
\begin{verbatim}
pcp(x = USArrests, varscores = TRUE, cases = "rows", center = "vars", standardize = FALSE, scale.cases = 1, log = FALSE, sc = 1, reflect = c(1, 1))
\end{verbatim}
\end{Usage}
\begin{Arguments}
\begin{ldescription}
\item[\code{x}] matrix on which SVD is to be performed
\item[\code{varscores}] logical; should scores be returned?
\item[\code{cases}] specify either \code{"rows"} or \code{"columns"}
\item[\code{center}] logical: if set to \code{"vars"}, then values of variables
will be centered
\item[\code{standardize}] logical: should values of variables be standardized to
zero mean and unit deviance.  Takes precedence over the setting of 
\code{center}
\item[\code{scale.cases}] set to a value in [0,1]. \code{scale.cases=0} gives 
a pure rotation of the variables. \code{scale.cases=1} weights a/c the 
singular values
\item[\code{log}] logical: should logarithms be taken, prior to the calculation?
\item[\code{sc}] the variable scores are divided by $\sqrt{sc-1}$. By default,
\code{sc} = number of cases
\item[\code{reflect}] a vector of two elements, by default \code{c(1,1)}. 
Use of -1 in one or both positions can be useful in reconciling results
with output from other software
\end{ldescription}
\end{Arguments}
\begin{Details}\relax
\end{Details}
\begin{Value}
\begin{ldescription}
\item[\code{g}] case scores
\item[\code{h}] variable scores
\item[\code{avv}] variable means
\item[\code{sdev}] singular values, divides by the square root of one less than
the number of cases
\end{ldescription}
\end{Value}
\begin{Note}\relax
\end{Note}
\begin{Author}\relax
John Maindonald
\end{Author}
\begin{References}\relax
\end{References}
\begin{SeeAlso}\relax
\code{\LinkA{La.svd}{La.svd}}
\end{SeeAlso}
\begin{Examples}
\begin{ExampleCode}
USArrests.svd <- pcp(x = USArrests)

## The function is currently defined as
function(x=USArrests,
           varscores=TRUE,
           cases="rows",
           center="vars",
           standardize=FALSE,
           scale.cases=1,
           log=FALSE,
           sc=1,
           reflect=c(1,1))
{
  x <- as.matrix(x)
  avv <- 0
  sdv <- 1
  casedim <- 2-as.logical(cases=="rows")
  vardim <- 3-casedim
  ## casedim=1 if rows are cases; otherwise casedim=2
  ## scale.cases=0 gives a pure rotation of the variables
  ## scale.cases=1 weights a/c the singular values
  ncases <- dim(x)[casedim]
  nvar <- dim(x)[vardim]
  if(is.null(sc))sc <- dim(x)[casedim]-1
  if(log)x <- log(x, base=2)
  if(standardize){
    avv <- apply(x, vardim, mean)
    sdv <- apply(x, vardim, sd)        
    x <- sweep(x, vardim, avv,"-")
    x <- sweep(x, vardim, sdv,"/")
  }
  else if(as.logical(match("vars", center, nomatch=0))){
    avv <- apply(x,vardim, mean)
    x <- sweep(x, vardim, avv,"-")}

  svdx <- La.svd(x, method = c("dgesdd"))
  h <- NULL
  if(cases=="rows"){
    g <- sweep(svdx$u, 2, svdx$d^scale.cases, "*")*sqrt(sc)
    if(varscores)
      h <- t((svdx$d^(1-scale.cases)* svdx$vt ))/sqrt(sc)
  }
  else if(cases=="columns"){
    g <- sweep(t(svdx$vt), 2, svdx$d^scale.cases, "*")*sqrt(sc)
    if(varscores)
      h <- sweep(svdx$u, 2, svdx$d^(1-scale.cases),"*")/sqrt(sc)
  }
  invisible(list(g=g, rotation=h, av=avv, sdev=svdx$d/sqrt(ncases-1)))
  }
\end{ExampleCode}
\end{Examples}

