【问题标题】:String manipulation in matrices: a dimensional issue矩阵中的字符串操作:一个维度问题
【发布时间】:2013-03-18 07:22:33
【问题描述】:

我正在尝试在 R 中定义一个操作字符串矩阵的函数。

{+,*} 矩阵乘法

两个n维方阵AB的{+,*}积是一个由元素定义的矩阵C : Ci,j = Sumk=1,...,nAi, k * Bk,j.

例如,考虑矩阵M <- matrix(c(a,b,0,0,c,d,0,0,e),3,3)。那么M乘以M就是M <- matrix(c(a^2,a*b+b*c,b*d,0,c^2,c*d+d*e,0,0,e^2),3,3)

{c(,),paste0(,)} 矩阵乘法

我想实现的这个操作的规则与前面所说的乘法相同,其中的基本突变是总和应该是串联,乘积应该是粘贴。换句话说,在前面的公式中我们找到a+b,现在输出应该是“c(a,b)”,当我们找到a*b时,现在我们应该读为paste0(a,b)

必须尊重一些常见的属性,即分配属性和 0 元素属性。因此,如果 a <- c("q",0,"w")b <- c("e") 然后 a*b <- c("qe",0,"we") (我们应该随意忘记 0 元素,将其删除,因为它不会影响计算。

此外,我们将等维矩阵相乘,因此每个元素 Ci,j = Sumk=1,...,nAi,k * Bk,j 现在读作c("A[i,1]B[1,j]",...,"A[i,n]B[n,j]")

为了简单起见,让我们考虑 B 总是一个 simple 矩阵,这意味着它的每个元素都是原子字符串,而不是字符串的串联(概括是后续的步骤)。

让我们举个例子。让A <- matrix(c("a","b",0,0,"c","d",0,0,"e"),3,3),然后mult(A,A) = matrix(c("aa",c("ab","bc"),"bd",0,"cc",c("cd","de"),0,0,"ee"),3,3)mult(mult(A,A),A) = matrix(c("aaa",c("aab","abc","bcc"),c("abd","bcd","bde"),0,"ccc",c("ccd","cde","dee"),0,0,"eee"),3,3)

部分(不工作)实施

考虑作为输入一对 nxn 矩阵 MN 是否为 0 或字符串数​​组 c(s1,s2,...) 作为 i,j 元素。作为输出,我想要一个矩阵 MN = M x N,其中乘法的定义类似于符号乘法:

MNi,j = 0 如果 Mi,.N.,j 为 0
MNi,j = paste(Mi, .,N.,j) 否则(使用paste()distributive属性)

我给出了基本行/列粘贴函数的定义(错误,未正确检查零)

MijPaste <- function(Row,Col){
  if(Col[1]=="0"){
    Mij <- 0
  } else if(Row[1]=="0"){
      Mij <- 0
    } else
      Mij <- paste(Row,Col,sep="")
  return(Mij)
}

我无法从这一步转到乘法函数的正确定义,因为我想在矩阵中插入的元素 Mij 的维度不正确。因此我得到一个number of items to replace is not a multiple of replacement length 错误。我目前的实现是:

# define the dimension of the matrix, here for example 3
dim <- 3
# define the Multiplication function as an iteration of the MijPaste function
Mult <- function(M1,M2){
    #allocate a matrix of dimension nxn
    M <-  matrix(0,dim,dim)
    #for each element i,j define it as the MijPaste of row i column j
      for(i in 1:dim){
      for(j in 1:dim){
        stringi <- M1[i,]
        stringj <- M2[,j]
        M[i,j] <- MijPaste(stringi,stringj)
      }
    }
  return(M)
}

代码不起作用。我可能可以将矩阵更改为多维数组,但我希望输出可用作矩阵以进行进一步乘法(例如定义 (MxN)xC)。

我该怎么办?

谢谢!

附:您可以使用简单的示例矩阵来测试代码

Matr <- matrix(c("11","12","13","21","22","23","31","32","33"),dim,dim)

正在运行

Mult(Matr,Matr)

【问题讨论】:

  • 它不起作用,因为在矩阵“槽”中不能有向量(长度 >= 2),即,不能将 c("A[i,1]B[1,j]",...,"A[i,n]B[n,j]") 分配给 M[i,j]。正如我在下面的 cmets 中指出的那样,您必须首先将该向量 折叠 为长度为 1 的字符串。
  • 好的,这就是你的意思。然后,我可能不得不使用一些分隔符将它折叠成一个长度为一的字符串,并在进行乘法之前再次分解它。希望这是可行的。

标签: string r matrix multidimensional-array exponentiation


【解决方案1】:

如果您手动设置维度,您可以直接将paste 与矩阵一起使用:

MN <- matrix(paste(M, N, sep=""), nrow=nrow(M), ncol=ncol(M))

现在过滤零并替换:

MN[(M==0) | (N==0)] <- 0

编辑:上面显示的逐点乘积不是 OP 想要的。

正如我在评论中所说,您可以修复您的功能,将collapse="" 添加到您的第一个功能。我得到以下结果:

> M <- matrix(LETTERS[1:9],3,3)
> N <- matrix(LETTERS[10:18],3,3)

> M
     [,1] [,2] [,3]
[1,] "A"  "D"  "G" 
[2,] "B"  "E"  "H" 
[3,] "C"  "F"  "I" 
> N
     [,1] [,2] [,3]
[1,] "J"  "M"  "P" 
[2,] "K"  "N"  "Q" 
[3,] "L"  "O"  "R" 

> Mult(M,N)
     [,1]     [,2]     [,3]    
[1,] "AJDKGL" "AMDNGO" "APDQGR"
[2,] "BJEKHL" "BMENHO" "BPEQHR"
[3,] "CJFKIL" "CMFNIO" "CPFQIR"

如您所见,您的函数匹配矩阵MN 中的元素在粘贴之前

如果要将每个矩阵的元素保持在一起,可以使用以下两行:

> coll <- function(x)paste(x,collapse="")
> outer(apply(M,1,coll),apply(N,2,coll),paste0)
     [,1]     [,2]     [,3]    
[1,] "ADGJKL" "ADGMNO" "ADGPQR"
[2,] "BEHJKL" "BEHMNO" "BEHPQR"
[3,] "CFIJKL" "CFIMNO" "CFIPQR"

当然,您必须在此之后手动插入零。

【讨论】:

  • 我可能是错的,但我担心过去的函数给出一个逐点“产品”作为输出,并且不能强制(作为内置)逐列给出“产品”,这是所需的输出.
  • 在这种情况下,您只需在对paste 的调用中添加collapse=""。即,像这样:paste(Row,Col,sep="",collapse="")
  • 另外,在您的函数中,您只检查RowCol 的第一个元素是否为零以返回零。这似乎很奇怪。你到底想要什么?如果Row/Col 中的任何 元素为零或仅当所有 元素为零时,M[i,j] 应该为零?
  • 是的,你完全正确。检查不正确。我认为解释我想要什么的最好方法是用 (+,) 算术,其中 ab 是粘贴 (a,b) 而 a+b 是 c(a,b) 和该操作适用于 0 的通常属性。我将在主要问题中为每个人更清楚地说明这一点,并举一个更好的例子。
  • @gvdr,我等着! :-)
【解决方案2】:
pmat <- function(m1, m2) matrix(
          ifelse(m1=="0"|m2=="0", "0", paste0(m1,m2) ) ,
                            dim(m1)[1], dim(m1)[2] )


> pmat(Matr, Matr)
     [,1]   [,2]   [,3]  
[1,] "1111" "2121" "3131"
[2,] "1212" "2222" "3232"
[3,] "1313" "2323" "3333"

我不知道你是否准备好进行维度乘法。如果您希望每个索引有 N 个元素,那么您需要 kronecker 函数,这需要稍微不同的函数:

插入:

也许您应该发布一个更好的测试用例?那么你可以更明确地说明你想要什么。这显示了 kronecker-applied pmat 重新排列为数组将给你 MN[1,1] 作为第一个矩阵的第一列:

 M <- matrix(c("a1","b1","c1","0"),2,2)
 N <- matrix(c("c2","d2","e2","f2"),2,2)
 MN <- array( kmat,c( 2,2,4))
 MN[ , 1,1]
#[1] "a1c2" "a1d2"

> pmat <- function(m1, m2) matrix( ifelse(m1=="0"|m2=="0", "0", paste0(m1,m2) )  )
> kronecker(Matr, Matr, pmat)
      [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]  
 [1,] "1111" "1121" "1131" "2111" "2121" "2131" "3111" "3121" "3131"
 [2,] "1112" "1122" "1132" "2112" "2122" "2132" "3112" "3122" "3132"
 [3,] "1113" "1123" "1133" "2113" "2123" "2133" "3113" "3123" "3133"
 [4,] "1211" "1221" "1231" "2211" "2221" "2231" "3211" "3221" "3231"
 [5,] "1212" "1222" "1232" "2212" "2222" "2232" "3212" "3222" "3232"
 [6,] "1213" "1223" "1233" "2213" "2223" "2233" "3213" "3223" "3233"
 [7,] "1311" "1321" "1331" "2311" "2321" "2331" "3311" "3321" "3331"
 [8,] "1312" "1322" "1332" "2312" "2322" "2332" "3312" "3322" "3332"
 [9,] "1313" "1323" "1333" "2313" "2323" "2333" "3313" "3323" "3333"

【讨论】:

  • 我还没有准备好在最终矩阵输出中进行维数乘法,但是通过维数乘法来检索输出没有任何问题。
  • 这里的问题是,在我的 MN [1,1] 位置,我希望有一个 M [1,.] 行N [.,1] 列“产品”,而不是逐点产品。例如,如果 M 的第一行是 c("a","b"),而 N 的第一列是 c("c","d"),则 MN 中的输出[1,1] 应该是c("ac","bd")
  • 这很有用,但仍然不是我想要的。考虑矩阵M &lt;- matrix(c("a","b",0,0,"c","d",0,0,"e"),3,3)。如果我正确使用了 kroenecker 函数,如果我计算 M 乘以 M,则结果是 matrix(c("aa","bb",0,0,"cc","dd",0,0,"ee"),3,3) 而所需的输出,类似于通常的矩阵乘法 %*%,应该是 matrix(c("aa",c("ab","bc"),0,0,"cc","cd+de",0,0,"ee"),3,3)(或者,使用常见的 ( +,*) 算术,matrix(c(a^2,ab+bc,0,0,c^2,cd+de,0,0,e^2),3,3))。很抱歉之前没有说得更清楚。
猜你喜欢
  • 2020-12-16
  • 1970-01-01
  • 2021-05-07
  • 2020-10-16
  • 1970-01-01
  • 2018-05-08
  • 2011-06-09
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多