1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
% 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()}}
}
|