Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zigzag persistence part1 #917

Open
wants to merge 141 commits into
base: master
Choose a base branch
from

Conversation

hschreiber
Copy link
Collaborator

@hschreiber hschreiber commented Jul 21, 2023

New module to compute zigzag persistence. To simplify the review process, this version contains only the main functionality, that is to compute the barcode.
Following functionalities will be added in separated PRs:

  • python interface
  • construction of oscillating rips filtrations from given edges
  • use of discrete Morse theory to simplify filtration
  • implementation of Dey and Hou's FastZigzag algorithm (?)(further tests are necessary)

The code is based on PR #401 and requires PR #886 and draft #669.

/**
* @brief List of options used for the matrix maintained for the zigzag persistence computation.
*/
struct ZigzagPersistenceOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relation between this concept and PersistenceMatrixOptions?

Comment on lines +53 to +56
* \details The type ZigzagComplex::Simplex_key counts the number of
* insertions and deletions of simplices, which may be large in zigzag persistence and require
* more than 32 bits of storage. The type used (int, long, etc) should be chosen in
* consequence. Simplex_key must be signed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that already said in the concept?


protected: // note that we don't assume b_ <= d_
int dim_; // homological dimension
value_type b_; // filtration value associated to birth index
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't match with the comment above for birth() which says that b_ is the birth index.

* closed for finite indices b and d, and open for left-infinite and/or
* right-infinite endpoints.
*/
struct filtration_value_interval : interval<Filtration_value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we capitalize type names?

if (Base::b_ == Base::d_) {
return 0;
} // otherwise inf - inf would return nan.
return std::abs(Base::b_ - Base::d_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have d_ smaller than b_?

}

/**
* @brief Returns the current persistence diagram ordered first by length, than by dimension,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really the role of this function to sort the intervals? The cost is probably negligible compared to the rest, but if I don't care about the order or if I want a different order, I am not very happy paying for this useless sort. Actually, it looks like it calls _get_persistence_diagram which also sorts with a different order, so we always pay for 2 sorts?

_retrieve_infinit_bars(diag);
}

std::stable_sort(diag.begin(), diag.end(), comp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment explaining why stable_sort and not plain sort here?

using Simplex_key = typename Complex::Simplex_key; /**< Key type, must be signed. */
using Simplex_handle = typename Complex::Simplex_handle; /**< Simplex ID type in the complex. */
using Vertex_handle = typename Complex::Vertex_handle; /**< Vertex ID type in the complex. */
using Filtration_value = typename Complex::Filtration_value; /**< Filtration value type. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are filtration values interpreted exactly? Operations have an index (operation 0 is inserting this vertex, operation 1 is inserting this other vertex, etc). Is the filtration value just a map from indexes to reals (or whatever type) that we bundle with this structure for convenience, without any meaning? Or does it have an actual semantic (for instance say 2 simplices removed at the same filtration value may be removed in any order)?

matrix_type matrix_; /**< Matrix storing a base of the current chain complex. */
std::unordered_map<index, int> births_; /**< Map simplex index in F to corresponding birth. */
birth_ordering birth_ordering_; /**< Maintains <b ordering of the births. */
std::list<index_interval> persistence_diagram_; /**< Stores current closed persistence intervals. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complex cpx_; /**< Complex in which the current simplices are stored. */
int dim_max_; /**< Maximal dimension of a bar to record. */
matrix_type matrix_; /**< Matrix storing a base of the current chain complex. */
std::unordered_map<index, int> births_; /**< Map simplex index in F to corresponding birth. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plain int, there is no relevant typedef?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants