开发者

Why is the gr count 0 in my program output?

开发者 https://www.devze.com 2023-04-07 14:46 出处:网络
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.

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!)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号