2013-03-28 3 views
0

Я пытаюсь определить функцию манипулирует матрицы строк в R.Строка в матрицах: размерный вопрос

{+, *} МАТРИЦЫ Умножение

{+, *} - произведение двух квадратных матриц и B размерности п является матрицей с определяется элементами: с I, J = Сумма к = 1, ..., п I, K * В 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).

{с (,), 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 элемента, сбросив его, как это не повлияет на вычисление.

Кроме того, мы умножение equaldimensioned матрицы, следовательно, каждый элемент C I, J = Сумма к = 1, ..., п я, к * B K, J теперь следует читать как c("A[i,1]B[1,j]",...,"A[i,n]B[n,j]").

. Для незанятости для сплетаемости рассмотрим B всегда a простая матрица, что означает, что каждый из ее элементов является атомной строкой, а не конкатенацией строки (обобщение является последующим шагом).

Приведем пример. Пусть 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 или массив строк с (с , с , ...) как i, j элементов. Как выход я хотел бы иметь матрицу MN = M х N, где умножение определяется по аналогии с символическим умножения:

MN I, J = 0, если M я ,. или N., J М.Н. I, J = паста (М я ,., 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).

Как я могу это сделать?

Спасибо!

P.S. Вы можете проверить код, используя простой пример матрицу

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

и работают

Mult(Matr,Matr) 
+0

Это не работает, потому что вы не можете иметь вектор (длины> = 2) в «слоте» матрицы, т. Е. Вы не можете назначить 'c (" A [i, 1] B [1 , j] ", ...," A [i, n] B [n, j] ")' to 'M [i, j]'. Вы должны * свернуть * этот вектор на строку длиной один символ, как я указал в моих комментариях ниже. –

+0

Хорошо, это делает вашу мысль. Тогда мне, вероятно, придется свернуть его до длины одной строки, используя некоторый разделительный символ и разбить его снова, прежде чем делать умножение. Надеюсь, это возможно. – gvdr

ответ

0

Вы можете использовать paste непосредственно с матрицами , если установить размеры вручную:

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

фильтровать нули и заменить:

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

EDIT: точечный продукт, показанный выше, НЕ является тем, что хочет 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" 

Конечно, вы должны вставить нули вручную после этого.

+0

Возможно, я ошибаюсь, но я боюсь, что прошлая функция дает в качестве выходного потокового «продукта» и не может быть принудительно (как встроена) давать строку по столбцу «продукт», что является желаемым результатом. – gvdr

+0

В этом случае все, что вам нужно сделать, это добавить 'collapse =" "' в ваш вызов 'paste'. например: 'paste (Row, Col, sep =" ", collapse =" ")' –

+0

Кроме того, в вашей функции вы проверяете только, является ли первый элемент 'Row' и' Col' равным нулю для возврата нуля , Это кажется странным. Что именно вы хотите? M [i, j] должен быть равен нулю, если * любой * элемент в 'Row' /' Col' равен нулю или только если * все * из них равны нулю? –

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 -applied pmat переставить как массив даст вам MN [1,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" 
+0

Я не готов к размерному умножению в конечном выходе матрицы, но у меня нет никакой проблемы, проходящей через мерное умножение для получения результата. – gvdr

+0

Проблема в том, что в моей позиции ** MN ** [1,1] я хотел бы иметь строку ** M ** [1.] По ** N ** [., 1] column "product ", а не поточечный продукт. Если, например, первая строка ** M ** является 'c (" a "," b ")', а первая из столбца ** N ** является 'c (" c "," d "), 'вывод в ** MN ** [1,1] должен быть' c ("ac", "bd") '. – gvdr

+0

Это очень полезно, но все же не то, что я хотел. Рассмотрим матрицу «M <- 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 + Ьс, 0,0, с^2, кд + де, 0,0, е^2), 3,3) '). Мне жаль, что я не был более ясен раньше. – gvdr

Смежные вопросы