Daniel Russel wrote: >> Calling State::update() in Model::evaluate() would not be sufficient, >> at least for nonbonded lists, because you can also call >> Restraint::evaluate() on individual restraints from the Python interface. > Sure, but I don't think there is any reason to guarantee that randomly > calling evaluate on restraints gives you anything meaningful unless you > are careful to update everything the restraint needs yourself. The Model > is there to do this. We could put in a hook so that someone can request > the Model update everything.
True, or we could just not allow people to call Restraint::evaluate directly. Do we have any use cases for such direct calls? (If yes, I'll write a quick unit test for that so that we can't break it in future.) I know one at least one of Bret's unit tests works that way, but it doesn't necessarily have to, as far as I can tell.
>> 1. Classes can register callbacks/actions with ModelData::set_float, >> or this could trigger a State::set_float method, to be notified >> whenever the model is changed. > The main problem is that given "the float at index 10 is being set to > 13.5", you have to lookup somewhat what is at index 10 and whether you > care about it. Doing this every time anything is changed, for each of > several State objects seems likely to be slow.
Well, for nonbonded lists you don't care what the index is, only what the old and new values are. But anyway, this won't work, because we can't tell for sure if we need to do an update based purely on, say, the x coordinate changing, since we need the 3D distance.
>> The advantage of the former is that the callback can go away after a >> nonbond update is triggered, saving the overhead of a function call >> for subsequent set_float()s. > How can it go away? You still have to keep track for the next update, no?
The callback would be removed after an update is triggered. The next rebuild of the nonbonded list would add the callback again.
>> 2. Classes to allow the get/set of the 'optimizable state' (right now, >> this is just all optimizable floats) could have similar methods, >> useful for optimizers such as CG and steepest descent which change all >> attributes simultaneously. > > I think in the normal course of things, if anything updates, lots of > things update, so it probably more efficient to have State objects go > search for changes they care about than notify them of every little > change. However, this would require the non-bonded list to keep a copy > of the original coordinates to determine how far things moved.
This would be really inefficient for Monte Carlo-like optimization strategies, unless perhaps you implemented MC by turning on/off particles like crazy. But Keren told me earlier of some thoughts she had in this direction, so perhaps she'd like to offer some wisdom at this point...
> Keep State as it is, with the exception that ModelData has a dirty bit > controlled by Model which Model uses to check if the States should be > updated.
How/when would this dirty bit be got/set?
> Add a FloatDataMonitor class which is called when floats change in the > ModelData (we can add String and Int ones later). > > We can have a FloatStatistic monitor which keeps statistics for a list > of fields. The non-bonded list (a State) can use it to keep track of how > far things move and delay update until needed.
Now that I think about it, I don't think this would work, at least for nonbonded lists, because 1. the statistic we want to keep track of is not (dx,dy,dz) but (dx*dx + dy*dy + dz*dz) (and we don't care about statistics once they've exceeded the threshold for update anyway) and 2. we want 8 individual moves of 1A to be treated the same as one move of 8A. So going down this route would require the nonbonded list to keep a copy of the coordinates for comparison purposes - and a method to allow optimizers or other 'model state transforms' to do a more efficient batch update of the variables (e.g. so that we don't have to do our nonbond list check three times when we move a particle, for the individual changes in x,y,z, but just once).
Ben