% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/snf.R
\name{snf}
\alias{snf}
\alias{snf.}
\title{Smith normal form}
\usage{
snf(mat, code = FALSE)

snf.(mat, code = FALSE)
}
\arguments{
\item{mat}{a matrix (integer entries)}

\item{code}{return only the M2 code? (default: \code{FALSE})}
}
\value{
a list of \code{m2_matrix} objects with names \code{D}, \code{P}, and
\code{Q}
}
\description{
For an integer matrix M, this computes the matrices D, P, and Q such that
\emph{D = PMQ}, which can be seen as an analogue of the singular value
decomposition. All are integer matrices, and P and Q are unimodular (have
determinants +- 1).
}
\examples{

\dontrun{ requires Macaulay2

##### basic usage
########################################

M <- matrix(c(
   2,  4,   4,
  -6,  6,  12,
  10, -4, -16
), nrow = 3, byrow = TRUE)

snf(M)

(mats <- snf(M))
P <- mats$P; D <- mats$D; Q <- mats$Q

P \%*\% M \%*\% Q                # = D
solve(P) \%*\% D \%*\% solve(Q)  # = M

det(P)
det(Q)


M <- matrix(c(
     1,    2,    3,
     1,   34,   45,
  2213, 1123, 6543,
     0,    0,    0
), nrow = 4, byrow = TRUE)
(mats <- snf(M))
P <- mats$P; D <- mats$D; Q <- mats$Q
P \%*\% M \%*\% Q                # = D



##### understanding lattices
########################################




# cols of m generate the lattice L
M <- matrix(c(2,-1,1,3), nrow = 2)
row.names(M) <- c("x", "y")
M

# plot lattice
df <- expand.grid(x = -20:20, y = -20:20)
pts <- t(apply(df, 1, function(v) M \%*\% v))
w <- c(-15, 15)
plot(pts, xlim = w, ylim = w)

# decompose m
(mats <- snf(M))
P <- mats$P; D <- mats$D; Q <- mats$Q

# PMQ = D, the columns of MQ = P^(-1) D  are a simpler basis of
# the lattice generated by (the cols of) M
(basis <- solve(P) \%*\% D)

# plot lattice generated by new basis
pts2 <- t(apply(df, 1, function(v) basis \%*\% v))
points(pts2, pch = "*", col = "red")



##### other options
########################################

snf.(M)
snf(M, code = TRUE)




}

}
\seealso{
\code{\link[=m2_matrix]{m2_matrix()}}
}
