Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reorder final lines of NUTS run #73

Merged
merged 3 commits into from
Dec 18, 2024
Merged

reorder final lines of NUTS run #73

merged 3 commits into from
Dec 18, 2024

Conversation

perrydv
Copy link
Contributor

@perrydv perrydv commented Dec 11, 2024

In sampler_NUTS, this PR moves the final calls to calculate and nimCopy (that leave the model fully up-to-date upon exit) to be the last lines, appearing after the adaptation calls rather than before. This avoids the problem that the adaptation calls, when initEpsilon is called, use the model and hence can change its state.

@danielturek
Copy link
Member

@perrydv Two comments:

  1. It seems plausible that inverseTransformStoreCalculate(state_sample$q) should occur before the adaptation also, in particular in the case when initEpsilon will be called. That's because the routines taking place in initEpsilon depend on the model values, so these should be up-to-date.

So, if I'm seeing it correctly, the updated code could look something like:

if((timesRan <= nwarmup) & adaptive) {
    if(adaptEpsilon)   adapt_stepsize(accept_prob)
    update <- FALSE
    if(adaptM)   update <- adapt_M()
    if(update & adaptEpsilon) {
        if(initializeEpsilon) {
            inverseTransformStoreCalculate(state_sample$q)     ## only called in advance, in initEpsilon case
            initEpsilon()
        }
        Hbar <<- 0
        logEpsilonBar <<- 0
        stepsizeCounter <<- 0
        mu <<- log(10*epsilon)
    }
}
inverseTransformStoreCalculate(state_sample$q)      ## always called here
nimCopy(from = model, to = mvSaved, row = 1, nodes = calcNodes, logProb = TRUE)    ## only place copy is called

Thoughts @perrydv ?

  1. It seems similar changes should also be made for the NUTS_classic sampler. Right?

@perrydv
Copy link
Contributor Author

perrydv commented Dec 16, 2024

@danielturek I looked at NUTS_classic and didn't think the same change is needed because the adaptiveProcedure does not use the model. However it would seem harmless to make the same change and thus remove any question when looking at the code in the future.

@danielturek
Copy link
Member

@perrydv What do you think of the updated code, in my earlier comment from several days ago? The idea was to also set the model state correctly, in advance of calling the initEpsilon method. Does that make sense from your perspective?

@perrydv
Copy link
Contributor Author

perrydv commented Dec 18, 2024

@danielturek I think your suggestion makes sense. I think it is defensive in that I think the model should be up to date, but initEpsilon is not called many times and so the number of additional model calculations needed for this defensiveness should not be a noticeable cost. I also realized I was wrong about the NUTS_classic and it does also need similar changes. I have made those changes and pushed them on this branch without testing locally, so let's see if tests run and please review the code.

@danielturek
Copy link
Member

@perrydv Agreed on all counts. I reviewed the changes you made, and LGTM.

@danielturek danielturek merged commit e2d0033 into master Dec 18, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants