libqueso/queso — pull request #204 by eRite (2014-02-11 03:27:07+00:00)
Title: Option to input likelihood of initial chain position in Metropolis-Hastings code (Issue #202)

I've added in the ability to re-use previously computed likelihoods in the multilevel solver (see issue #202). Here is a summary of the changes to the existing code:

I've added two new constructors to MetropolisHastingsSG that take an initial logPrior and logLikelihood as input. These values are then stored as class members for later use in chain generation. The generateFullChain method now checks the newly added member boolean, m_computeInitialPriorAndLikelihoodValues, to see if it should call the likelihood function (and compute logPrior) at the initial position or use the input values. If the user calls one of the old MetropolisHastingsSG constructors, m_computeInitialPriorAndLikelihoodValues is automatically set to true, indicating that no initial values were passed in and so the likelihood function should be called at the initial chain position.

In order to pass the previous level logLike and logPrior to the MetropolisHastingsSG constructor from within the multilevel solver, I've added logPrior and logLikelihood values to the BalancedLinkedChainControlStruct and I've modified the functions comprising steps 7, 9, and 10 - as well as generateUnbLinkedChains_all, prepareBalLinkedChains_inter0, and mpiExchangePositions_inter0. These private methods now require, as additional input, the previous level exponent, the current level exponent, and the previous sequences of logLikes and logPriors. The two exponents are required because the previous level likelihoods are stored as prevLikelihood = prevExponent*actualLogLikelihoodFromPreviousLevel. Thus, initialLogLikeCurrentLevel = (currExponent/prevExponent)*logLikeLevelPreviousLevel. Care is taken in the case that prevExponent = 0.0 (as is the case at the beginning of level 1). In the case where load balancing is done, I've added code to mpiExchangePositions_inter0 that communicates previous level logPrior and logLikelhoods to receiving nodes.

To turn on this new functionality, I've added the boolean option, m_initialPositionUsePreviousLevelLikelihood, to MLSamplingLevelOptions. By default, this option is turned off - which forces MLSampling to call the old MetropolisHastingsSG constructor with no initial likelihood or prior values. The option can, of course, be turned on by setting:
ip_ml_default_initialPositionUsePreviousLevelLikelihood = 1
in the config file. Then the new MetropolisHastingsSG constructor is called.

To sum it up, I've added constructors to MetropolisHastingsSG and changed private methods in MLSampling. No existing public interfaces have changed. I've also added a new option to MLSamplingLevelOptions that allows users to toggle this new feature. By default, the feature is off. I've been running my own inverse problems with the feature on for a few weeks now. In my experience, it speeds up the BayesMLSolver by factors between 1.5 and 2. Your own results will vary - but basically whenever the intermediate level chains have short lengths (usually, in my experience), this feature reduces a lot of unnecessary computation.