Simply speaking, I have a function f(x, t2)
and I want to find the value of x
that maximize the integral of f(x, t2)
with respect to t2
. I choose pso algorithm to do the optimization. The excutable code is as follows
library(pso)
xl=0; xu=2000; n=1; t2l=100; t2u=2000; t1=1
g<-function(x, t2) t1*x/(t2 x)
h<-function(z) 1/z^n
gdot<-function(x, t2){
c(x/(t2 x),-t1*x/(t2 x)^2)
}
logdetHinv<-function(dp, dw, t2){
gmat=mapply(function(x) gdot(x,t2),dp)
D0=gmat%*%diag(dw)%*%t(gmat)
D1=gmat%*%diag(1/h(g(dp,t2)))%*%diag(dw)%*%t(gmat)
2*log(det(D1))-log(det(D0))
}
obj<-function(x){
dp=x[1:2]; dw=c(x[3],1-x[3])
fitness_value=-integrate(Vectorize(function(t2) logdetHinv(dp, dw, t2)*1/(t2u-t2l)), t2l, t2u)$value
return(ifelse(dw[2]>0, fitness_value, fitness_value 1e3))
}
x <- psoptim(rep(1,3), fn = obj, lower = c(rep(xl,2),0.1), upper = c(rep(xu,2), 0.9))$par
x
Because the global optimization involves some random procedure, it sometimes reports the correct result
> x
[1] 2000.0000 754.4146 0.5000
the other times it reports error
Error in integrate(Vectorize(function(t2) logdetHinv(dp, dw, t2) * 1/(t2u - :
non-finite function value
In addition: There were 11 warnings (use warnings() to see them)
> warnings()
Warning messages:
1: In log(det(D1)) : NaNs produced
2: In log(det(D0)) : NaNs produced
3: In log(det(D1)) : NaNs produced
4: In log(det(D0)) : NaNs produced
I suppose the algorithm tries take log of some negative values in logdetHinv
, which returns NaN
with a warning message, not an error yet, and finally causes error in integrate
.
I want to avoid such values, maybe with tryCatch
, like if there is warning in the function logdetHinv
, it returns a very small value, but not NaN
, so it will not cause error in integrate
, and the psoptim
is unlikely to choose such values when maximizing the objective function (minimizing -integrate(logdetHinv)
) . I am not familiar with tryCatch
in such complex situation. Where should I put the tryCatch
? Thanks.
Moreover, I would like to know if there are some debugging techniques in R that allow me to know what random value (D0/D1
) cause the error in this case. I guess it is some negative value in log, but it should not, as inside the log is a determinant of a positive definite matrix. In the traceback mode, in browse, if I type D0
the object 'D0' will not be found.
CodePudding user response:
In this case, I would not use tryCatch which is usually more appropriate in testing than in your main code. Why don't you simply test the determinants in your function ? Something like that should work:
logdetHinv<-function(dp, dw, t2){
gmat=mapply(function(x) gdot(x,t2),dp)
D0=gmat%*%diag(dw)%*%t(gmat)
D1=gmat%*%diag(1/h(g(dp,t2)))%*%diag(dw)%*%t(gmat)
detD1 <- max(0.01, det(D1))
detD0 <- max(0.01, det(D0))
2*log(detD1)-log(detD0)
}