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

Rework simplex tree options #978

Merged

Conversation

VincentRouvreau
Copy link
Contributor

@VincentRouvreau VincentRouvreau commented Oct 2, 2023

  • move options in a separated header
  • fast_persistence (no doc)
  • python
  • Rename Simplex_tree_interface_full_featured with Simplex_tree_python_interface
  • Benchmark fast cofaces
  • Replace fast_cofaces option with full_feature
  • default
  • minimal
  • full_featured
  • Benchmark stable simplex handles

Fix #905

…ree_options_fast_persistence. Specific Simplex_tree_options_for_python for Python. Rename Simplex_tree_interface_full_featured with Simplex_tree_python_interface
* how to save on storage by not storing a filtration value. */

struct MyOptions : Gudhi::Simplex_tree_options_full_featured {
struct MyOptions : Gudhi::Simplex_tree_options_minimal {
// Implicitly use 0 as filtration value for all simplices
static const bool store_filtration = false;
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should comment out that line (keep it but make it a comment), since this is the default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or maybe we should not derive from any existing options and set all the options we need for this example.
Tell me your preference.

Copy link
Member

Choose a reason for hiding this comment

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

No, in an example, deriving from something is good, that's what we want to recommend.

Copy link
Contributor Author

@VincentRouvreau VincentRouvreau Oct 20, 2023

Choose a reason for hiding this comment

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

Rephrase simplex tree options for this example on 0a82c1e

typedef IndexingTag Indexing_tag;
/// Must be a signed integer type. It admits a total order <.
/** @brief Must be a signed integer type. It admits a total order <. */
Copy link
Member

Choose a reason for hiding this comment

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

Not this PR, but at some point, for ourselves (not necessarily for users), it would be nice to have a comment explaining where such requirements ("signed") come from.

src/Simplex_tree/example/mini_simplex_tree.cpp Outdated Show resolved Hide resolved
@@ -47,11 +47,11 @@ class Euclidean_witness_complex_interface {
delete witness_complex_;
}

void create_simplex_tree(Gudhi::Simplex_tree<>* simplex_tree, double max_alpha_square, std::size_t limit_dimension) {
void create_simplex_tree(Simplex_tree<Simplex_tree_options_for_python>* simplex_tree, double max_alpha_square, std::size_t limit_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 there a reason not to use Simplex_tree_interface here (and related places)?

Copy link
Contributor Author

@VincentRouvreau VincentRouvreau Oct 19, 2023

Choose a reason for hiding this comment

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

Here it is ok, so I changed it on 55f9f8e
But there is an issue with Tangential_complex _interface while using create_complex. I added a comment on the problematic line

@@ -47,11 +47,11 @@ class Euclidean_witness_complex_interface {
delete witness_complex_;
}

void create_simplex_tree(Gudhi::Simplex_tree<>* simplex_tree, double max_alpha_square, std::size_t limit_dimension) {
void create_simplex_tree(Simplex_tree<Simplex_tree_options_for_python>* simplex_tree, double max_alpha_square, std::size_t limit_dimension) {
Copy link
Contributor Author

@VincentRouvreau VincentRouvreau Oct 19, 2023

Choose a reason for hiding this comment

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

Here it is ok, so I changed it on 55f9f8e
But there is an issue with Tangential_complex _interface while using create_complex. I added a comment on the problematic line

void create_simplex_tree(Simplex_tree<>* simplex_tree) {
tangential_complex_->create_complex<Gudhi::Simplex_tree<Gudhi::Simplex_tree_options_full_featured>>(*simplex_tree);
void create_simplex_tree(Simplex_tree<Simplex_tree_options_for_python>* simplex_tree) {
tangential_complex_->create_complex<Simplex_tree<Simplex_tree_options_for_python>>(*simplex_tree);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
tangential_complex_->create_complex<Simplex_tree<Simplex_tree_options_for_python>>(*simplex_tree);
tangential_complex_->create_complex<Simplex_tree_interface>(*simplex_tree);

Here, when it calls insert_simplex_and_subfaces, it calls the method from Simplex_tree_interface and it fails because it is not returning the type required by tangential complex

Copy link
Member

Choose a reason for hiding this comment

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

So the issue is that Simplex_tree_interface::insert_simplex_and_subfaces overrides the functions of the base class but has an incompatible API? Shouldn't we rename that function so it does not clash with the one in the base class then?

Copy link
Member

Choose a reason for hiding this comment

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

Actually, that function does not seem to be used anywhere, can't we remove it?

Copy link
Contributor Author

@VincentRouvreau VincentRouvreau Oct 20, 2023

Choose a reason for hiding this comment

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

Oh, ok ! That should be some dead code. I removed it and now my suggestion is possible on a6c5e0a

@VincentRouvreau
Copy link
Contributor Author

@hschreiber @mglisse Some benchmarks to decide what options we do activate for the Python interface

link_nodes_by_label stable_simplex_handles OFF filename Rips max_edge_length Rips construction in sec Rips construction memory in Mo SimplexTree construction in sec SimplexTree construction memory in Mo SimplexTree number of simplices Persistence computation in sec Persistence computation memory in Mo
false false tore3D_300.off 3.5 0.002 1.84 1.152 1859.43 57770908 62.260 14228.86
true false tore3D_300.off 3.5 0.002 1.85 1.878 2741.14 57770908 67.564 14228.80
false true tore3D_300.off 3.5 0.002 1.81 3.412 3622.38 57770908 78.363 14228.73
true true tore3D_300.off 3.5 0.002 1.80 4.342 4503.83 57770908 81.205 14228.78
link_nodes_by_label stable_simplex_handles OFF filename Rips construction in sec Rips construction memory in Mo SimplexTree construction in sec SimplexTree construction memory in Mo SimplexTree number of simplices edge collapse construction in sec edge collapse construction memory in Mo edge collapse number of simplices expansion(5) construction in sec expansion(5) construction memory in Mo expansion(5) number of simplices Persistence computation in sec Persistence computation memory in Mo
false false 5-forex-2500.off 0.151 150.76 0.076 103.18 3126250 14.341 6.08 9304 0.001 0.00 20925 0.005 0.00
true false 5-forex-2500.off 0.152 150.75 0.155 151.65 3126250 14.141 5.60 9304 0.001 0.00 20925 0.005 0.00
false true 5-forex-2500.off 0.153 150.73 0.245 190.84 3126250 14.407 4.74 9304 0.002 0.00 20925 0.006 0.00
true true 5-forex-2500.off 0.150 150.72 0.278 238.53 3126250 14.293 6.07 9304 0.002 0.00 20925 0.006 0.00
link_nodes_by_label stable_simplex_handles OFF filename Alpha precision Alpha construction in sec Alpha construction memory in Mo SimplexTree construction in sec SimplexTree construction memory in Mo SimplexTree number of simplices Persistence computation in sec Persistence computation memory in Mo
false false 5-forex-2500.off fast 2.041 48.97 3.364 212.66 2278347 1.615 17.99
false false 5-forex-2500.off safe 2.013 49.80 7.064 664.78 2278347 1.644 0.55
false false 5-forex-2500.off exact 1.954 49.73 23.352 720.63 2278347 1.585 14.16
true false 5-forex-2500.off fast 2.113 49.00 3.802 249.55 2278347 1.790 17.99
true false 5-forex-2500.off safe 1.831 49.76 7.330 701.88 2278347 1.925 0.55
true false 5-forex-2500.off exact 1.900 49.71 23.676 757.68 2278347 1.776 0.55
false true 5-forex-2500.off fast 2.056 48.96 4.041 278.04 2278347 1.991 17.92
false true 5-forex-2500.off safe 1.903 49.75 7.582 730.27 2278347 2.032 0.54
false true 5-forex-2500.off exact 1.834 49.78 23.621 786.18 2278347 1.966 13.43
true true 5-forex-2500.off fast 2.067 48.95 4.155 312.95 2278347 2.121 17.93
true true 5-forex-2500.off safe 1.820 49.74 7.648 765.29 2278347 2.121 0.55
true true 5-forex-2500.off exact 1.817 49.70 23.759 821.02 2278347 2.153 14.87

@mglisse
Copy link
Member

mglisse commented Oct 20, 2023

For stable_simplex_handles, I think we said there was no point activating it in Python since for now it has 0 benefit.
For link_nodes_by_label, I think I'd be in favor of keeping it false for now (same behavior as previous releases) and possibly revisiting later. My reasoning is that it increases the size of the SimplexTree significantly (+50%), and while it makes finding cofaces less ridiculously slow on sparse complexes, that operation is still way slower than finding faces, so people who need really fast cofaces would be better off using a different datastructure that explicitly stores the links of the Hasse diagram. I am open to counter-arguments though.

@hschreiber
Copy link
Collaborator

hschreiber commented Oct 23, 2023

Yes, stable_simplex_handles should be false for python, as the user never accesses the simplex handles directly, so it slows down things for nothing.
For link_nodes_by_label, I admit, I don't know how much python users need cofaces when using the simplex tree. Do we have feedback on this?

@DavidLapous
Copy link
Member

A possibility, which is not headache-free, is to have both in the same simplextree : as the current python interface only stores the simplextree c++ pointer, we just need to add a private member in the python simplextree class, telling by run time how to reinterpret_cast the simplextree in c++. This may cost another python call for each method, but it should be fine. To avoid confusion of python users, it might also be useful to define __repr__ to differentiate them.

This can also apply to PR #976 .

@mglisse
Copy link
Member

mglisse commented Oct 23, 2023

For link_nodes_by_label, I admit, I don't know how much python users need cofaces when using the simplex tree. Do we have feedback on this?

A search in the issues and gudhi-users finds surprisingly little. I know some people have used cofaces on examples small enough that they did not care about performance. The few cases I remember where people cared about the speed of cofaces were for C++.

A possibility, which is not headache-free, is to have both in the same simplextree : as the current python interface only stores the simplextree c++ pointer, we just need to add a private member in the python simplextree class, telling by run time how to reinterpret_cast the simplextree in c++.

So essentially a std::variant or a virtual base (though we may use other technical means to achieve it). That's a possibility. It has a cost though, both in speed (although the difference may be negligible depending on how we implement it) and maintenance (it increases and complicates the code), so it needs to be worth the trouble. But if we do decide that we want "fast" cofaces without forcing a slowdown on other operations and increasing the use of memory, that does look like a sensible approach.

For multi-persistence, while it still seems possible, my first reaction without thinking much about it is that the interfaces are likely to differ enough that a separate Python class makes more sense.

Copy link
Member

@mglisse mglisse left a comment

Choose a reason for hiding this comment

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

We will need to say something in the release notes about it.

@VincentRouvreau VincentRouvreau merged commit ec56efe into GUDHI:master Nov 20, 2023
6 of 7 checks passed
@VincentRouvreau VincentRouvreau deleted the rework_simplex_tree_options branch November 20, 2023 09:14
@VincentRouvreau
Copy link
Contributor Author

We will need to say something in the release notes about it.

Ok, I will propose something

@VincentRouvreau VincentRouvreau added the 3.9.0 GUDHI version 3.9.0 label Nov 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.9.0 GUDHI version 3.9.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Simplex_tree_options_full_featured vs link_nodes_by_label
4 participants