Why is the gr count 0 in my program output?
I'm new to R and DM/ML, and I wrote a small program to try out the optim function.
I used optim with SANN method. I defined my own gr
function and made some config with the control
parameter.
The problem is that when I print the output, the count of gr
, which stands for the number of calls to the gr function, is 0, while the number of calls to fn is correct.
Here's my runnable code(I think the cost function is irrevelant so I posted a simple one):
people = list('Seymour'='BOS',
'Franny'='DAL',
'Zooey'='CAK',
'Walt'='MIA',
'Buddy'='ORD',
'Les'='OMA')
schedulecost <- function(schedule){
return(sum(schedule))
}
annealingOptimize <- function(domains, step=1, T=10000,costf=schedulecost){
solution <- sample(1:9, 2 * length(people), replace=T)
grFunction <- function(sol){
index <- sample(c(1:length(domains$Up)), 1, replace=T)
delta <- as.integer(runif(1,min=-step-1,max=step+1))
newValue <- sol[index] + delta
if (newValue > domains$Up[index]){
newValue <- domains$Up[index]
}
if (newValue < domains$Down[index]){
newValue <- domains$Down[index]
}
sol[index] <- newValue
return(sol)
}
values <- optim(solution,costf,gr=grFunction, method='SANN',
control=list(temp=T, REPORT=1, maxit=200, tmax=10))
print(values)
return(values$par)
}
domains <- list(Down=rep(1,length(people) * 2), Up=rep(9, length(people) * 2))
schedule <-annealingOptimize(domains)
And the output is:
$par
[1] 2 2 6 2 3 5 5 1 9 1 1 7
$value
[1] 44
$counts
function gradient
200 NA
$convergence
[1] 0
$message
NULL
In my understanding, the count of gr
should equal to the count of fn
, since you need to call the fn
iff you have a new candidate from a call to gr
.
Is my understanding incorrect(if yes, what's their relationship) or there's something wrong with my code.
Any one can help ?
Thanks so much !
Update:
As @Dwin pointed out, in the help documentation it says: "Method "SANN" ... uses only function values but is relatively slow. " But in the description of the parameter gr
it says: "For the "SANN" method it specifies a function to generate a new candidate开发者_如何学C point. "
If you add some print statement in my grFunction
, you can see that it actually got called very intensively.
Besides, if the SANN method just use fn
and doesn't use gr, then what the sentence for gr
really mean ?
Investigating the code in src/main/optim.c
shows that the SANN method really does call the gradient function (which you have of course confirmed via your print statements), but that it doesn't bother to update the gradient count. Here's the call to the internal SANN function samin
:
samin (npar, dpar, &val, fminfn, maxit, tmax, temp, trace, (void *)OS);
for (i = 0; i < npar; i++)
REAL(par)[i] = dpar[i] * (OS->parscale[i]);
fncount = npar > 0 ? maxit : 1;
grcount = NA_INTEGER;
and I can confirm that samin
calls genptry
, which calls the gradient function.
This strikes me as a bug (which could be reported to the R development list, or on the R bugs tracker), but a harmless one. As you point out, presumably the gradient (= candidate point generator) function always gets called exactly the same number of times (OK, give or take one or two during the set-up stage) as the objective function ... (but I understand the confusion when the function doesn't do what it says in the documentation!)
精彩评论