Ben Webb wrote: > Daniel Russel wrote: >> I think the three alternatives for weights are 1) Hide it in the >> restraint class. To make this clean, we should hide the the >> ModelData* and mirror its functions in the Restraint base class >> (strictly speaking we only need to mirror add_to_deriv, but for >> symmetry, we should do all if we do one). For the return value, I >> would suggest adding a function weighted_eval which is called by the >> Model or RestraintSet instead of eval and calls eval internally. >> Then, anyone who wants to override that directly will know they need >> to deal with the weights themselves. Note that this proposal breaks >> if we move to a "Particles as Objects" framework since adding to the >> deriv involves an arbitrary function call. > > I like this option, because I think it a very bad idea to rely on > every restraint to do the scaling itself. But I don't think it'll work > for restraints which contain other restraints - for example I may want > a restraint set which contains a bunch of other restraints, and would > then expect each restraint to be scaled twice - once by its own scale > factor and once by the set's. Good point, I didn't think about the nested case. It could be done by having the outer restraint make sure that the inner restraints weights were the product of the outer weight and the inner weight. This does make writing nested restraints more complicated than non-nested ones.
> It seems like option (2) would be able to handle this more easily - > either that or we use option (1) together with something like the > DerivativeAccumulator that Keren proposed. Why don't you like option 2? Option 2 basically is the DerivativeAccumulator. On reflection, I do like it. - The restraint has a single evaluate function which takes a pointer to a DerivativeAccumulator (which is NULL if no derivs are to be accumulated). No more bool. Can we do this with swig? I would assume NULL gets translated into null. This has the added advantage that you can't set derivs if you are not supposed to. - To evaluate a restraint (either in the Model or as an outer nested restraint) you get the weight, w, and tell the DA to multiply its weight by w (push it on to a stack of weights). Then you call evaluate, multiply the return value by w and tell the DA to pop the last weight. - the weights are stored separately from the restraints since they are no longer handled by the restraint - the add_to_deriv functions on ModelData are hidden
This still has problems with Particles as Objects, but I like it otherwise and change my vote :-)