I've developed this into the modules PDLx::Mask and PDLx::MaskedData.

For now, they're just up at github & bitbucket:

https://github.com/djerius/PDLx-Mask

https://bitbucket.org/djerius/pdlx-mask

See the end of the .pm files for complete docs.

There's a dependency on

https://github.com/djerius/PDLx-DetachedObject

Comments appreciated.

Diab


On Tue, Oct 11, 2016 at 11:26 AM, Diab Jerius <djer...@cfa.harvard.edu> wrote:
> 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

Reply via email to