2

I'd like to understand better how outer works and how to vectorize functions. Below is a minimal example for what I am trying to do:I have a set of numbers 2,3,4. for each combination (a,b) of create a diagonal matrix with a a b b b on the diagonal, and then do something with it, e.g. calculating its determinant (this is just for demonstration purposes). The results of the calculation should be written in a 3 by 3 matrix, one field for each combination.

The code below isn't working - apparently, outer (or my.func) doesn't understand that I don't want the whole lambdas vector to be applied - you can see that this is the case when you uncomment the print command included.

lambdas <- c(1:2)
my.func <- function(lambda1,lambda2){
# print(diag(c(rep(lambda1,2),rep(lambda2,2))))
 det(diag(c(rep(lambda1,2),rep(lambda2,2))))
}
det.summary <- outer(lambdas,lambdas, FUN="my.func")

How do I need to modify my function or the call of outer so things behave like I'd like to?

I guess I need to vectorize my function somehow, but I don't know how, and in which way the outer call would be processed differently.

Edit: I've changed size of the matrices to make it a bit less messy. I'd like to generate 4 diagonal 4 by 4 matrices, with the following diagonals; in are brackets the corresponding parameters lambda1, lambda2:

1 1 1 1 (1,1), 1 1 2 2 (1,2), 2 2 1 1 (2,1), 2 2 2 2 (2,2).

Then, I want to calculate their determinants (which is an arbitrary choice here) and put the results into a matrix, whose first column corresponds to lambda1=1, the second to lambda1=2, and the rows correspond to the choice of lambda2. det.summary should be a 2 by to matrix with the following values:

1 4
4 16

as these are the determinants of the diagonal matrices listed above.

Roland
  • 517
  • 8
  • 25

1 Answers1

3

What do you know, there is a Vectorize function (capital "V")!

outer(lambdas,lambdas, Vectorize(my.func))
#      [,1] [,2]
# [1,]    1    4
# [2,]    4   16

As you figured out (and as it took me a while to figure out) outer requires the function to be vectorized. In some ways, it is the opposite of the *pply functions which effectively vectorize an operation by feeding the operator/function each value in turn. But this is easily dealt with, as shown above.

BrodieG
  • 51,669
  • 9
  • 93
  • 146
  • 1
    I thought @agstudy's answer to my similar question deserved all the votes it got. http://stackoverflow.com/questions/18110397/why-doesnt-outer-work-the-way-i-think-it-should-in-r – IRTFM Jan 30 '14 at 02:36
  • @IShouldBuyABoat, interesting, I eventually figured this out on my own by using `browser()` like he does. It seems we reached similar conclusions, though it isn't clear to me whether there is something you disagree with here, or if you're just pointing to other resources. – BrodieG Jan 30 '14 at 02:42
  • Just point out that this is a duplicate and the proper response is to apply the check to the older answer. Which you have not yet done. – IRTFM Jan 30 '14 at 02:44
  • @IShouldBuyABoat, I don't understand what you mean? How can I apply a check to a question I did not ask? You mean I should upvote that answer even though I came up with this independently? I'm confused. – BrodieG Jan 30 '14 at 02:50
  • @IShouldBuyABoat, also, that answer doesn't even suggest the use of `Vectorize`, rather, `mapply`, so I really don't get it. The closest is eddi's comment, which incidentally I almost supplied as an answer to your question before I noticed he had already posted it as a comment. And even that one is not the same as this one due to the `...` argument for `sum`. – BrodieG Jan 30 '14 at 13:39
  • Look at the code for `Vectorize`. As its help page says, tt's just a wrapper for `mapply`. – IRTFM Jan 31 '14 at 01:31
  • @IShouldBuyABoat sure, but still, the simple answer to this question is "use Vectorize", which isn't what the other answer suggested. It just so happens `Vectorize` doesn't work for your example without adjustments due to the lack of named arguments, but it works perfectly fine here. – BrodieG Jan 31 '14 at 01:39