We have been discussing ideas for accelerating the evaluation of certain restraints, particularly excluded volume and connectivity-based ones, by taking advantage of the fact that you often don't care how bad things are once they are sufficiently bad. To be more concrete, the idea is to add a function Model::evaluate_if_ok(Restraints, Weights) which - returns the score if the score is less than Model::get_maximum_score and each restraint score is less than its maximum - otherwise returns a very large score (something greater than Model::get_maximum_score()
The idea is that restraint evaluation in general, and individual restraints in particular can cease their computations if the can prove the score is too high.
The usage scenarios envisioned are: - domino: since we reject any state which scores badly, we can use this method directly - monte carlo: any state that score sufficiently badly is vanishingly unlikely to be accepted, and so we could, in principle, save some work in evaluation by dynamically varying the maximum score to be, say, 5kT times the current score. I'm not sure how useful this is in practice.
Restraints that could benefit: - excluded volume: there is no need to evaluation all of the pairs once we have found several collisions. How to best combine this optimization with the optimization currently used of only updating the non-bonded list periodically is non-obvious, especially given the often incoherent evaluations performed by domino. - connectivity restraints: any large edge that is required means we don't have to check anything else - pairsrestraint: we can skip evaluating later pairs of the earlier ones score too badly
Further directions: - in domino we often only care if each restraint score is below its maximum (assuming there is no model maximum score). In this case, many restraints can do a cheaper computation to simply determine if things are OK. The context of using this is much narrower and the benifit smaller, so I'm not sure we want to implement this now.
The impact on existing code: - no changes need to be made to any restraints/pair scores - restraint/pair scores can be updated to take advantage of this functionality by overloading the Restraint::do_evaluate_if_ok() method (a default implementation is provided)
My questions are: - are there other areas where these ideas might be applied which should be kept in mind when implementing this functionality to make it more generally useful? - are there other restraints which could easily benefit?