如何使用 for 循环在 R 中构建具有模块化模式的矩阵?
How can I use for loops to construct a matrix with a modular pattern in R?
我想要一个 (q^p) x p 矩阵,其中 q 是质数。
如果 q=3, p=3:
我想构建如下模式
0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 2 0
1 2 0
2 2 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 2
0 2 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
0 2 2
1 2 2
2 2 2
我目前的代码是:
F <- matrix(ncol=p,nrow=q^p) #initialize the vector F
for(i in 1:(q^p)){
for(j in 1:p){
F[i,j] <- ((i-1) %% q) * (j %% 3)
}
}
如果另一个例子会有所帮助,这里是 q=2, p=3 矩阵的样子:
0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
我知道我需要使用一些模块化函数,但我不确定如何实现这个问题。
这会为每个序列计算一次迭代,然后依靠循环来填充长度。
foo = function(p, q) {
seqs = lapply(1:p, function(x) rep((1:q) - 1, each = q^(x - 1)))
do.call(cbind, seqs)
}
> foo(3, 2)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 0 0
[3,] 0 1 0
[4,] 1 1 0
[5,] 0 0 1
[6,] 1 0 1
[7,] 0 1 1
[8,] 1 1 1
使用expand.grid
f = function(q, p) {
as.matrix(expand.grid(replicate(p, 1:q-1L, FALSE)))
}
f(2,3)
# Var1 Var2 Var3
# [1,] 0 0 0
# [2,] 1 0 0
# [3,] 0 1 0
# [4,] 1 1 0
# [5,] 0 0 1
# [6,] 1 0 1
# [7,] 0 1 1
# [8,] 1 1 1
f(3,3)
# Var1 Var2 Var3
# [1,] 0 0 0
# [2,] 1 0 0
# [3,] 2 0 0
# [4,] 0 1 0
# [5,] 1 1 0
# [6,] 2 1 0
# [7,] 0 2 0
# [8,] 1 2 0
# [9,] 2 2 0
# [10,] 0 0 1
# [11,] 1 0 1
# [12,] 2 0 1
# [13,] 0 1 1
# [14,] 1 1 1
# [15,] 2 1 1
# [16,] 0 2 1
# [17,] 1 2 1
# [18,] 2 2 1
# [19,] 0 0 2
# [20,] 1 0 2
# [21,] 2 0 2
# [22,] 0 1 2
# [23,] 1 1 2
# [24,] 2 1 2
# [25,] 0 2 2
# [26,] 1 2 2
# [27,] 2 2 2
这是伽罗华域刻画的另一种方法(但不像的方法那么简单)
gf <- function(q,p) {
x <- seq(q**p)-1
t(sapply(x, function(v) {
if (v==0) {
r <- 0
} else {
r <- c()
while (v!=0) {
r <- c(v%%q,r)
v <- v%/%q
}
}
c(rep(0,p-length(r)),r)}))
}
这样
> q <- 3
> p <- 3
> gf(p,q)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 1
[3,] 0 0 2
[4,] 0 1 0
[5,] 0 1 1
[6,] 0 1 2
[7,] 0 2 0
[8,] 0 2 1
[9,] 0 2 2
[10,] 1 0 0
[11,] 1 0 1
[12,] 1 0 2
[13,] 1 1 0
[14,] 1 1 1
[15,] 1 1 2
[16,] 1 2 0
[17,] 1 2 1
[18,] 1 2 2
[19,] 2 0 0
[20,] 2 0 1
[21,] 2 0 2
[22,] 2 1 0
[23,] 2 1 1
[24,] 2 1 2
[25,] 2 2 0
[26,] 2 2 1
[27,] 2 2 2
我想要一个 (q^p) x p 矩阵,其中 q 是质数。
如果 q=3, p=3:
我想构建如下模式0 0 0
1 0 0
2 0 0
0 1 0
1 1 0
2 1 0
0 2 0
1 2 0
2 2 0
0 0 1
1 0 1
2 0 1
0 1 1
1 1 2
0 2 1
0 0 2
1 0 2
2 0 2
0 1 2
1 1 2
0 2 2
1 2 2
2 2 2
我目前的代码是:
F <- matrix(ncol=p,nrow=q^p) #initialize the vector F
for(i in 1:(q^p)){
for(j in 1:p){
F[i,j] <- ((i-1) %% q) * (j %% 3)
}
}
如果另一个例子会有所帮助,这里是 q=2, p=3 矩阵的样子:
0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
我知道我需要使用一些模块化函数,但我不确定如何实现这个问题。
这会为每个序列计算一次迭代,然后依靠循环来填充长度。
foo = function(p, q) {
seqs = lapply(1:p, function(x) rep((1:q) - 1, each = q^(x - 1)))
do.call(cbind, seqs)
}
> foo(3, 2)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 0 0
[3,] 0 1 0
[4,] 1 1 0
[5,] 0 0 1
[6,] 1 0 1
[7,] 0 1 1
[8,] 1 1 1
使用expand.grid
f = function(q, p) {
as.matrix(expand.grid(replicate(p, 1:q-1L, FALSE)))
}
f(2,3)
# Var1 Var2 Var3
# [1,] 0 0 0
# [2,] 1 0 0
# [3,] 0 1 0
# [4,] 1 1 0
# [5,] 0 0 1
# [6,] 1 0 1
# [7,] 0 1 1
# [8,] 1 1 1
f(3,3)
# Var1 Var2 Var3
# [1,] 0 0 0
# [2,] 1 0 0
# [3,] 2 0 0
# [4,] 0 1 0
# [5,] 1 1 0
# [6,] 2 1 0
# [7,] 0 2 0
# [8,] 1 2 0
# [9,] 2 2 0
# [10,] 0 0 1
# [11,] 1 0 1
# [12,] 2 0 1
# [13,] 0 1 1
# [14,] 1 1 1
# [15,] 2 1 1
# [16,] 0 2 1
# [17,] 1 2 1
# [18,] 2 2 1
# [19,] 0 0 2
# [20,] 1 0 2
# [21,] 2 0 2
# [22,] 0 1 2
# [23,] 1 1 2
# [24,] 2 1 2
# [25,] 0 2 2
# [26,] 1 2 2
# [27,] 2 2 2
这是伽罗华域刻画的另一种方法(但不像
gf <- function(q,p) {
x <- seq(q**p)-1
t(sapply(x, function(v) {
if (v==0) {
r <- 0
} else {
r <- c()
while (v!=0) {
r <- c(v%%q,r)
v <- v%/%q
}
}
c(rep(0,p-length(r)),r)}))
}
这样
> q <- 3
> p <- 3
> gf(p,q)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 1
[3,] 0 0 2
[4,] 0 1 0
[5,] 0 1 1
[6,] 0 1 2
[7,] 0 2 0
[8,] 0 2 1
[9,] 0 2 2
[10,] 1 0 0
[11,] 1 0 1
[12,] 1 0 2
[13,] 1 1 0
[14,] 1 1 1
[15,] 1 1 2
[16,] 1 2 0
[17,] 1 2 1
[18,] 1 2 2
[19,] 2 0 0
[20,] 2 0 1
[21,] 2 0 2
[22,] 2 1 0
[23,] 2 1 1
[24,] 2 1 2
[25,] 2 2 0
[26,] 2 2 1
[27,] 2 2 2