0

Rで文字列の行列を操作する関数を定義しようとしています.

{+,*} 行列の乗算

次元 nの 2 つの正方行列ABの {+,*} 積は、次の要素で定義される 行列Cです: C i,j = Sum k=1,...,n A i,k * B k, 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 要素プロパティを尊重する必要があります。したがって、ifa <- c("q",0,"w")およびb <- c("e")then a*b <- c("qe",0,"we")(そして、計算に影響しないため、0 要素を自由に削除する必要があります。

さらに、等次元行列を乗算しているため、各要素 C i,j = Sum k=1,...,n A i,k * B k,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)

部分的な (動作しない) 実装

0 または文字列の配列 c( s 1 , s 2 ,...) をi,j要素とするnxn 行列M , Nのペアを入力として考えます。出力として、乗算がシンボリック乗算と同様に定義される行列MN = M x Nが必要です。

M i,j の場合、 i,j=0であるまたはN .,jは 0 MN i,j = paste( M i,. , N .,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 を定義するため)。

どのようにできるのか?

ありがとうございました!

PS簡単なサンプルマトリックスを使用してコードをテストできます

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

そして走っている

Mult(Matr,Matr)
4

2 に答える 2

0
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-appliedpmatを配列として再配置すると、最初の行列の 1 列目として 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"
于 2013-03-28T00:30:01.123 に答える
0

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 前に一致します。

各行列の要素をまとめておきたい場合は、次の 2 行を使用できます。

> 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"

もちろん、この後手動でゼロを挿入する必要があります。

于 2013-03-28T00:38:25.887 に答える