scikit-tda / cechmate

Custom filtration constructors for Python
http://cechmate.scikit-tda.org
MIT License
22 stars 11 forks source link

Nonsimplicial complexes #25

Open trevorkarn opened 3 years ago

trevorkarn commented 3 years ago

I'd like to add an argument "simplicial" to cm.phat_diagrams which would default to True and would check that the filtration was indeed a simplicial complex, not just a CW(?)-complex. If one wanted to use a CW(?)-complex, they could pass simplicial=False and proceed. I was thinking the check would also coerce a "non-simplicial" filtration to one by remembering only the first time a simplex was added, so if it is "added again" we are effectively just saying "ok its already present at time t so keep going."

I am concerned that checking every time may not make sense if the user knows that they have a simplicial complex and then the check would slow things down and not be useful. So I'm not sure whether it should be something like assert_simplicial which would default to False, and then passing True would do the check and coerce to a simplicial filtration. Does anyone have any thoughts?

The following example exhibits the nonsimplicial (CW?) behavior:

>>> filtration = [('a',0),('b',0),('ab',1),('ab',2),('ab',3)]
>>> cm.phat_diagrams(filtration, show_inf=True, verbose=False)
[array([[ 0., 1.], [ 0., inf]]), array([[ 2., inf], [ 3., inf]])]

This makes sense if each instance of the additional 'ab' edge is a new edge, because we have two vertices and three edges between them, so past t=3, we would expect two generators for the 1st homology. 

I want to call it a CW-complex but that doesn't seem quite right because cechmate does check that lower dimensional things are added before higher dimensional things, so it doesn't allow for a cellular decomposition of a 2-sphere into a 0-cell and a 2-cell (without a 1-cell). For example:

>>> filtration = [('a',0),('aaa',0)]
>>> cm.phat_diagrams(filtration, show_inf=True, verbose=False)
Traceback (most recent call last):
    ...
Exception: Error: Not a proper filtration: ['a' 'a' 'a'] added before ('a', 'a')

It also gives funky results when you try to construct $S^1$ with a 0-cell and a 1-cell.

>>> filtration = [('a',0),('aa',0)]
>>> cm.phat_diagrams(filtration, show_inf=True, verbose=False)
[]

which makes sense on the level of ∂(aa) = a-a = 0, but not on the level of the actual topology. In any case, I don't think the first example is a simplicial complex because a simplicial complex on {a,b} should be a subset of 2^{a,b}, not a sub-multiset. (I'm just saying this so that you can correct me if I'm misunderstanding something.)

However, the structure of S2 can be built up in a somewhat interesting way by:

>>> filtration = [('a',0),('b',0),('c',0),('ab',1),('bc',2),('ac',3),('abc',4),('abc',5)]
>>> cm.phat_diagrams(filtration, show_inf=True, verbose=False)
[array([[ 0.,  1.],
       [ 0.,  2.],
       [ 0., inf]]), array([[3, 4]]), array([[ 5., inf]])]

I'm not sure if what I described was the intended behavior or not, but I do see some use cases for it, so I think it should be kept for added flexibility in the complexes which one can construct.