Masking out elements of piddles is something that PDL has supported for a long time via bad values. This works well if all operations performed on the piddle respect bad values, and it doesn't quite matter that you may be overwriting a value with the bad value (at worst, you keep a copy of the original, unmasked piddle)
One can also use an external mask (i.e. a boolean/byte piddle) and use that to select elements to operate on. This works well when there are multiple piddles which share the same mask, and you don't want to alter the values in the masked piddles. There are some applications where the combination of approaches makes sense: having an external mask which is used to set bad values in copies of piddles. When the mask is changed, the piddles are updated to reflect the changes in the mask. I've written and duplicated this code enough times that it's time to come up with an abstraction to handle the machinations, and I'd like to make sure that the design is properly reviewed.. There are two classes involved, the Mask class and the MaskedPiddle class (all names are placedholders) with a publisher/subscriber (pub/sub) relationship. The Mask class subclasses PDL, and "is" a boolean/byte piddle. It should only be changed using the value() method (which installs a new piddle) or the (overridden) set() or assign (.=, &=, |=, etc) methods. When it is changed, it calls the update() method on all of the MaskedPiddle objects which have been registered to it using its subscribe() method. MaskedPiddle is also a subclass of PDL, and can have any type. When created it is passed an existing data piddle and either an existing Mask object or a mask piddle (which will be the basis for a Mask object unique to the MaskedPiddle object). It will register with the Mask object so it will receive updates. Updates will be effected by its update() method, which uses the Mask object to set elements in a *copy* of the data piddle to either the bad value or some other specified value. The copy is what will be exposed to PDL operations on the MaskedPiddle object. It, like Mask, should only be changed using the value() [which installs a new piddle] or the (overridden) set() or .=/assign methods. There's a further wrinkle. If the piddle represented by a MaskedPiddle object has existing bad values, they *may* be reflected in the Mask that is registered with it, and will be propagated to all of the other piddles registered with that Mask. Any changes in the badness of a MaskedPiddle will be propagated through its registered Mask to the other registered piddles as well. The Mask class keeps track of the (lazily evaluated) number of elements, and the MaskedPiddle class keeps track of lazily evaluated summary statistics (e.g., dsum, etc.) These will be invalidated when Masks or MaskedPiddles are changed. This doesn't require any new machinery in PDL (other than a wished for method of making piddles read only so that all of the piddles remain synchronized). Any thoughts on this approach or something I've missed? Thanks, Diab ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ pdl-devel mailing list pdl-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/pdl-devel