5. Use an explicit cover¶
Context and Problem Statement¶
The mapper algorithm needs a cover of the high dimensional data in order to function. The end user should be able to supply this. There are two orthogonal questions that need answering.
Should the user provide the raw cover or a method for producing a cover?
How should the data of a cover be encoded?
This seeks to address the first question.
Decision Drivers¶
Minimal overhead for people implementing new covers
Flexibility, as many use cases as possible should be enabled
Type safety, python type checkers should be able to tell what is going on
Considered Options¶
Supply a method for computing the cover
Supply a realized cover
Decision Outcome¶
Chosen option: “Supply a realized cover”, because supplying a method for computing the cover adds no benefits and just complicates the interface.
There was a concern that asking the user to supply a realized cover might increase the overhead on their side. In practice this seems to be a non-issue. Regardless the user is going to request a cover from a function, the only question is what it requires and what it returns. Supplying a cover method looks like this:
# Supply a method for computing the cover
cover_scheme = Width_Balanced_Cover(num_bins=10, percent_overlap=0.2)
result = mapper( cover = cover_scheme, ...)
supplying a realized cover looks like this:
# Supply a cover
cover = width_balanced_cover(projection, num_bins=10, percent_overlap=0.2)
result = mapper(cover = cover, ...)
The amount of work from the user is the same in both cases. The only potential issue would be purely conceptual. The second method requires that you supply the projection at the time of specifying the cover. We think this is a fine amount of understanding to require of our users.
Moreover with the current method it is not immediately obvious how one introspects the computed cover. With the “supply a cover” method this is can be made much more clear; any function which fits a cover is responsible for returning the metadata as well. This results in code which looks like the following:
# Supply a cover
cover, metadata = width_balanced_cover(projection, num_bins=10, percent_overlap=0.2)
result = mapper(cover = cover, ...)
Our interface decision here does not put any requirement that there be a metadata object returned nor makes any requirement of its form. This could lead to issues down the road if many cover schemes are implemented and they diverge on this pattern. This is a bridge we can cross if it comes.
Pros and Cons of the Options¶
Supply a method for computing the cover¶
Good, because we already have this implemented
Good, because it lines up with how users conceptualize mapper
Bad, because it increases the overhead of implementing a new cover
Bad, because it obscures how to interact with covering metadata
Supply a realized cover¶
Good, because it minimizes overhead of implementing a new cover
Good, because it simplifies the implementation of the mapper algorithm
Good, because it makes type hinting easier
Bad, because it maybe adds conceptual overhead to the user
Bad, because it maybe does not line up with how users conceptualize mapper
More Information¶
ADR-0003 reasons on allowing user supplied covers