Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generating matrices/using outer

Tags:

r

I'm a new (~1 day old) R user. I'm trying to generate all 216 outcomes of three throws of a six-sided die. The point is to then apply some function to each triplet (say, maximum face value). This is what I've come up with:

mat <- matrix(numeric(0), ncol=3)
for (i in 1:6) {
    for (j in 1:6) {
        for (k in 1:6) {
            mat <- rbind(mat, c(i, j, k))
        }
    }
}

# find maximum of each outcome
apply(mat, 1, max)

Is there a better and more concise way to do this with R? I would've liked to use outer this way:

outer(1:6, outer(1:6, 1:6, max), max)

but it fails with the error

Error in outer(1:6, 1:6, max) : dims [product 36] do not match the length of object [1]

like image 948
Aky Avatar asked Nov 14 '15 13:11

Aky


People also ask

How do you write a matrix as an outer product?

In linear algebra, the outer product of two coordinate vectors is a matrix. If the two vectors have dimensions n and m, then their outer product is an n × m matrix.

How do you use outer product in Numpy?

To get the Outer product of two arrays, use the numpy. outer() method in Python. The 1st parameter a is the first input vector. Input is flattened if not already 1-dimensional.

What does NP Outer do?

outer() function compute the outer product of two vectors. Parameters : a : [array_like] First input vector.

What is inner and outer product of matrices?

Definition: Inner and Outer Product. If u and v are column vectors with the same size, then uT v is the inner product of u and v; if u and v are column vectors of any size, then uvT is the outer product of u and v.


1 Answers

We can use expand.grid to create the combinations in a data.frame, convert to matrix and get the maximum value of each row by rowMaxs from library(matrixStats).

library(matrixStats)
rowMaxs(as.matrix(expand.grid(rep(list(1:6),3))))
#[1] 1 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 2
#[38] 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 3 3
#[75] 3 4 5 6 3 3 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 4 4 4
#[112] 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 5 5 5 5
#[149] 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6
#[186] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

Or we can use pmax with expand.grid

do.call(pmax, expand.grid(rep(list(1:6),3)))

Or as suggested by @Ben Bolker, we can also use apply with MARGIN=1

apply(expand.grid(rep(list(1:6),3)),1,max) 

Another option is outer with pmax.

c(outer(1:6, outer(1:6, 1:6, FUN=pmax), FUN= pmax))
#[1] 1 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 2
#[38] 2 3 4 5 6 2 2 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 3 3
#[75] 3 4 5 6 3 3 3 4 5 6 3 3 3 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 4 4 4
#[112] 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 4 4 4 4 5 6 5 5 5 5 5 6 6 6 6 6 6 6 5 5 5 5
#[149] 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6
#[186] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6

Or outer with Vectorized max

f1 <- function(x,y) max(x,y)
c(outer(1:6, outer(1:6, 1:6, Vectorize(f1)), Vectorize(f1)))
like image 122
akrun Avatar answered Sep 29 '22 05:09

akrun