【问题标题】:How can I use for loops to construct a matrix with a modular pattern in R?如何使用 for 循环在 R 中构造具有模块化模式的矩阵?
【发布时间】:2020-04-29 21:07:01
【问题描述】:

我想要一个 (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

我知道我需要使用一些模块化函数,但我不确定如何实现这个问题。

【问题讨论】:

    标签: r for-loop matrix mod


    【解决方案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
    

    【讨论】:

    • 我喜欢这个。非常简单。从这里开始,我将如何对矩阵进行排序以遵循上述帖子中的模式?
    • @Edison - 不确定我是否理解。我认为它已经按照您显示的顺序进行了排序。还是我错过了什么?
    • 你是对的。我不知道我在想什么。感谢您提供这项工作!
    【解决方案2】:

    这会为每个序列计算一次迭代,然后依靠循环来填充长度。

    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
    

    【讨论】:

    • 谢谢!我绝对没有使用你从 R 之神那里调用的这些很棒的功能。
    【解决方案3】:

    这是另一种表征伽罗瓦域的方法(但不像@Gregor Thomas的方法那么简单)

    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
    

    【讨论】:

    • 我非常感谢这个答案,因为我的意图是实际使用 Galois Fields。你能解释一下你的算法在数学上做了什么吗?这太棒了!
    • @Edison 关于伽罗瓦场,可以参考mathworld.wolfram.com/FiniteField.html。如果您只想列出 GF(q^q) 中的所有元素,则很容易以 base-q 表示的格式编写 base-10 数字(请注意顺序,因为 GF 表示取决于原始多项式)。如果你想执行其他 GF 操作,我想你需要玩一下原始多项式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多