我试图在R.中定义一个操作字符串矩阵的函数
{+,*}矩阵乘法
维数n的两个矩阵A和B的{+,*}-乘积是由以下元素定义的矩阵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就是CCD_ 2。
{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总是一个简单的矩阵,这意味着它的每个元素都是原子字符串,而不是字符串的串联(泛化是后续步骤(。
让我们举一个例子。设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矩阵M、N视为输入,无论是0还是字符串数组c(s1、s2,…(作为i、j元素。作为输出,我希望有一个矩阵MN=MxN,其中乘法的定义与符号乘法类似:
MN
i,如果M>i,则j=0或N。,j为0
MNi,j=粘贴(M<1sub>i、.、N<2sub>、j(否则(使用paste()
的分布式特性(
我给出了一个(错误的,没有正确检查零(将基本行/列粘贴函数定义为
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)
如果手动设置维度,则可以直接将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"
正如您所看到的,您的函数在粘贴之前匹配矩阵M
和N
中的元素。
如果你想把每个矩阵的元素放在一起,你可以使用这两行:
> 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"
当然,您必须手动在此之后插入零。
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
函数,它需要一个稍微不同的函数:
插入:
也许你应该发布一个更好的测试用例?然后你可以更明确地表达你想要什么。这显示了应用M <- matrix(c(a^2,a*b+b*c,b*d,0,c^2,c*d+d*e,0,0,e^2),3,3)
0的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"