Reputation: 3781
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
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