-1

Inspired from this question fast large matrix multiplication in R, I am wondering if I could use crossprod on three or more matrices. I am trying to calculate a general list which contains the cross products of several lists of matrices with Map(crossprod,listA,listB). I tried Map(crossprod,listA,listB,listC) but got the crossproducts for listA and listB's element matrices only. Lists A, B, C have the same number of matrices. All the matrices are of the same dimension. My current fix is

result1<-Map(crossprod,listA,listB)
Map(crossprod,result1,listC)  

How do I do a one-line code? Thank you very much!

Little Bee
  • 1,175
  • 2
  • 13
  • 22
  • 1
    Try `Reduce("%*%", list(listA, listB, listC)0` – akrun Jul 22 '19 at 02:54
  • @akrun: Thank you for your reply. I got an error. `Error in f(init, x[[i]]) : requires numeric/complex matrix/vector arguments`. `is.matrix(listA[["matrix1"]] = TRUE` thought. – Little Bee Jul 22 '19 at 03:01

2 Answers2

1

An option is accumulate

library(purrr)
out2 <- flatten(tail(accumulate(lst1, map2, crossprod), 1))

-checking with OP's output

out1 <- Map(crossprod,result1,listC) 
identical(out1, out2)
#[1] TRUE

Or using base R

do.call(c, tail(Reduce(function(...) Map(crossprod, ...), 
         lst1, accumulate = TRUE), 1))

data

m1 <- matrix(1:9, 3, 3)
m2 <- matrix(11:19, 3, 3)
listA <- list(m1, m2)
listB <- listA
listC <- listA
lst1 <- mget(paste0("list", c("A", "B", "C")))
akrun
  • 874,273
  • 37
  • 540
  • 662
1
library(purrr)

a = matrix(runif(9),ncol=3)
b = matrix(runif(9),ncol=3)
c = matrix(runif(9),ncol=3)

ListA = list(a,b)
ListB = list(a,c)
ListC = list(b,c)

# list with the lists of matrix
L = list(ListA,ListB,ListC)
Reduce("%*%",map(L,~Reduce("%*%",.)))

#Validation
a %*% b %*% a %*% c %*% b%*% c
Daniel Fischer
  • 947
  • 6
  • 8