The optimize function is only designed to handle one function argument as I understand it. But sometimes a function can depend on different input ranges of variables and parameters.
for example:
x.r<-rnorm(100)
y<-function(x,p) -x^2+p*1/exp(x^3)
optimize(y,upper=range(x.r)[2],lower=range(x.r)[1])
x.r. the domain of x being passed to y can change from sample to sample. Instead of using a generic x, I want to be able to draw from many x.r domains of values to run y over. Is there some way to modify the optimize function so that I could pass both y, the function, and x it's domain variables as well as the optimize parameter(s) p?
With the above I get an error:
> optimize(y,upper=range(x.r)[2],lower=range(x.r)[1])
Error in p * 1 : 'p' is missing
edit: per suggestion below (which makes sense... but) I tried.
x.r<-rnorm(100)
p<-seq(-5,5,1)
y<-function(x,p) -x^2+p*1/exp(x^3)
optimize(y,upper=range(x.r)[2],lower=range(x.r)[1],p)
results was: Error in p * 1 : 'p' is missing
Also,
> optimize(y,upper=range(x.r)[2],lower=range(x.r)[1],p,x.r)
Error in optimize(y, upper = range(x.r)[2], lower = range(x.r)[1], p, :
invalid function value in 'optimize'
any other ideas?
edit 2: per comments below a loop would work, but seems like an odd way to approach it. I'm not sure if it's uniquely taking the x.r domain into account either.
x.r<-rnorm(100)
p<-seq(-5,5,1)
y<-function(p=p,x=x.r) -x^2+p*1/exp(x^3)
for(v in p){
print(optimize(y,upper=range(p)[2],lower=range(p)[1],p=v))}
> for(v in p){
+ print(optimize(y,upper=range(p)[2],lower=range(p)[1],p=v))}
$minimum
[1] -4.999944
$objective
[1] -9.637547e+54
$minimum
[1] -4.999944
$objective
...
I call optimise
over p
x.r <- rnorm(100)
p <- seq(-5,5,1)
y<-function(x,p) -x^2+ p/exp(x^3)
ll <- lapply(p,function(i)
optimize(y,upper=range(x.r)[2],lower=range(x.r)[1],p=i))
ll[[which.min(sapply(ll,'[[','minimum'))]]
$minimum
[1] -2.14628
$objective
[1] -98357.67
Of course if maximum = TRUE
the last becomes
ll[[which.max(sapply(ll,'[[','maximum'))]]
Another way out of this which works even when the thing you are calling doesn't allow you to specify extra named parameters that are passed on to the function is to create a function-generating function that generates a function with a given p.
yp <- function(p){force(p);function(x){-x^2+p*1/exp(x^3)}}
yp1=yp(1)
yp2=yp(2)
and now the yp
functions are just a function of x:
> yp1(0)
[1] 1
> yp2(0)
[1] 2
so your loop becomes:
x.r <- rnorm(100)
pv <- seq(-5,5,1)
ll <- lapply(pv,function(p){
Y = yp(p)
optimize(Y,upper=range(x.r)[2],lower=range(x.r)[1])
})
which is looping over the pv
vector and putting each value in p
to create a function Y
based on that value. Nothing else (apart from upper
and lower
) is passed into optimize
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With