GabyLP
GabyLP

Reputation: 3781

R- outer with matrix

Let's suppose I want to minimize a function:

x<-seq(-4.5,4.5,by=.2)
y<-seq(-4.5,4.5,by=.2)
f <- function(x1,x2){(x1^2 + x2)^2 }
z <- outer(x,y,f)

Where z is a matrix of dimension 46 x 46:

  > class(z)
[1] "matrix"
> dim(z)
[1] 46 46

So I make a graph of the result with:

persp(x,y,z,phi=-45,theta=45,col="yellow",shade=.65 ,ticktype="detailed")

If I write the previous, it works, but since I want to minimize the function using optim, if I use that I get:

optim(c(-4,-4), f, df)$par

> Error in fn(par, ...) : argument "x2" is missing, with no default

So I need to use an array in order to use optim after all. So if I write:

f <- function(x) (x[1]^2 + x[2])^2 
x <- seq(-4.5,4.5,by=.2)
y <- seq(-4.5,4.5,by=.2)
s<-data.frame(cbind(x,y))

I can use optim:

optim(c(-4,-4), f, df)$par

But outer gives an error:

z <- outer(s,f)

Error in as.vector(x, mode) : cannot coerce type 'closure' to vector of type 'any'

I don't know how to solve it.

Upvotes: 3

Views: 1079

Answers (1)

Frank
Frank

Reputation: 66819

I believe the goal here is to not have to write the function two different ways, right?

f0 <- function(x1,x2) ( x1^2   + x2   )^2
f  <- function(x)     ( x[1]^2 + x[2] )^2 

Similarly, maybe you just want to use just s<-data.frame(cbind(x,y)) (without x and y).

Here's what I would consider doing:

outer(s[[1]],s[[2]],Vectorize(function(xi,yi) f(c(xi,yi))))

This way you only have to write the function once, in the way amenable to using optim (with a single argument).


Note: If you want the grids x and y to have a different number of points, you should store s <- list(x,y) instead. The code will work the same.

Upvotes: 1

Related Questions