oineus 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oineus-0.9.3/CMakeLists.txt +54 -0
- oineus-0.9.3/MANIFEST.in +22 -0
- oineus-0.9.3/PKG-INFO +37 -0
- oineus-0.9.3/README.md +89 -0
- oineus-0.9.3/bindings/python/CMakeLists.txt +44 -0
- oineus-0.9.3/bindings/python/aa.py +15 -0
- oineus-0.9.3/bindings/python/example.py +42 -0
- oineus-0.9.3/bindings/python/example_cone.py +40 -0
- oineus-0.9.3/bindings/python/example_cone_diff.py +110 -0
- oineus-0.9.3/bindings/python/example_manual.py +62 -0
- oineus-0.9.3/bindings/python/example_opt.py +38 -0
- oineus-0.9.3/bindings/python/example_opt_vr.py +107 -0
- oineus-0.9.3/bindings/python/example_opt_vr.py.bak +38 -0
- oineus-0.9.3/bindings/python/example_vr.py +56 -0
- oineus-0.9.3/bindings/python/example_wasserstein_opt.py +76 -0
- oineus-0.9.3/bindings/python/oineus/__init__.py +267 -0
- oineus-0.9.3/bindings/python/oineus/diff/__init__.py +252 -0
- oineus-0.9.3/bindings/python/oineus.cpp +26 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/PKG-INFO +101 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/SOURCES.txt +12 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/dependency_links.txt +1 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/not-zip-safe +1 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/requires.txt +2 -0
- oineus-0.9.3/bindings/python/oineus.egg-info/top_level.txt +1 -0
- oineus-0.9.3/bindings/python/oineus_common.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_decomposition.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_fil_dgm_simplex_double.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_fil_dgm_simplex_float.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_functions_double.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_functions_float.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_index_diagram.cpp +6 -0
- oineus-0.9.3/bindings/python/oineus_persistence_bindings.h +995 -0
- oineus-0.9.3/bindings/python/oineus_top_optimizer.cpp +98 -0
- oineus-0.9.3/bindings/python/pybind11/.appveyor.yml +35 -0
- oineus-0.9.3/bindings/python/pybind11/.clang-format +38 -0
- oineus-0.9.3/bindings/python/pybind11/.clang-tidy +77 -0
- oineus-0.9.3/bindings/python/pybind11/.cmake-format.yaml +73 -0
- oineus-0.9.3/bindings/python/pybind11/.codespell-ignore-lines +24 -0
- oineus-0.9.3/bindings/python/pybind11/.gitattributes +1 -0
- oineus-0.9.3/bindings/python/pybind11/.github/CODEOWNERS +9 -0
- oineus-0.9.3/bindings/python/pybind11/.github/CONTRIBUTING.md +388 -0
- oineus-0.9.3/bindings/python/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml +61 -0
- oineus-0.9.3/bindings/python/pybind11/.github/ISSUE_TEMPLATE/config.yml +8 -0
- oineus-0.9.3/bindings/python/pybind11/.github/dependabot.yml +7 -0
- oineus-0.9.3/bindings/python/pybind11/.github/labeler.yml +8 -0
- oineus-0.9.3/bindings/python/pybind11/.github/labeler_merged.yml +3 -0
- oineus-0.9.3/bindings/python/pybind11/.github/matchers/pylint.json +32 -0
- oineus-0.9.3/bindings/python/pybind11/.github/pull_request_template.md +19 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/ci.yml +1163 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/configure.yml +88 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/format.yml +60 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/labeler.yml +25 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/pip.yml +114 -0
- oineus-0.9.3/bindings/python/pybind11/.github/workflows/upstream.yml +116 -0
- oineus-0.9.3/bindings/python/pybind11/.gitignore +46 -0
- oineus-0.9.3/bindings/python/pybind11/.pre-commit-config.yaml +152 -0
- oineus-0.9.3/bindings/python/pybind11/.readthedocs.yml +3 -0
- oineus-0.9.3/bindings/python/pybind11/CMakeLists.txt +322 -0
- oineus-0.9.3/bindings/python/pybind11/LICENSE +29 -0
- oineus-0.9.3/bindings/python/pybind11/MANIFEST.in +6 -0
- oineus-0.9.3/bindings/python/pybind11/README.rst +180 -0
- oineus-0.9.3/bindings/python/pybind11/SECURITY.md +13 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/attr.h +690 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/buffer_info.h +208 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/cast.h +1704 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/chrono.h +225 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/common.h +2 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/complex.h +74 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/class.h +743 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/common.h +1258 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/descr.h +171 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/init.h +434 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/internals.h +656 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/type_caster_base.h +1177 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/detail/typeid.h +65 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/eigen/common.h +9 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/eigen/matrix.h +714 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/eigen/tensor.h +516 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/eigen.h +12 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/embed.h +316 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/eval.h +156 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/functional.h +137 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/gil.h +239 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/iostream.h +265 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/numpy.h +1998 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/operators.h +202 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/options.h +92 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/pybind11.h +2890 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/pytypes.h +2541 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/stl/filesystem.h +116 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/stl.h +447 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/stl_bind.h +851 -0
- oineus-0.9.3/bindings/python/pybind11/include/pybind11/type_caster_pyobject_ptr.h +61 -0
- oineus-0.9.3/bindings/python/pybind11/noxfile.py +107 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/__init__.py +17 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/__main__.py +62 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/_version.py +12 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/commands.py +37 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/py.typed +0 -0
- oineus-0.9.3/bindings/python/pybind11/pybind11/setup_helpers.py +498 -0
- oineus-0.9.3/bindings/python/pybind11/pyproject.toml +96 -0
- oineus-0.9.3/bindings/python/pybind11/setup.cfg +42 -0
- oineus-0.9.3/bindings/python/pybind11/setup.py +150 -0
- oineus-0.9.3/bindings/python/pybind11/tools/FindCatch.cmake +76 -0
- oineus-0.9.3/bindings/python/pybind11/tools/FindEigen3.cmake +86 -0
- oineus-0.9.3/bindings/python/pybind11/tools/FindPythonLibsNew.cmake +287 -0
- oineus-0.9.3/bindings/python/pybind11/tools/JoinPaths.cmake +23 -0
- oineus-0.9.3/bindings/python/pybind11/tools/check-style.sh +44 -0
- oineus-0.9.3/bindings/python/pybind11/tools/cmake_uninstall.cmake.in +23 -0
- oineus-0.9.3/bindings/python/pybind11/tools/codespell_ignore_lines_from_errors.py +39 -0
- oineus-0.9.3/bindings/python/pybind11/tools/libsize.py +36 -0
- oineus-0.9.3/bindings/python/pybind11/tools/make_changelog.py +62 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pybind11.pc.in +7 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pybind11Common.cmake +397 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pybind11Config.cmake.in +231 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pybind11NewTools.cmake +256 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pybind11Tools.cmake +233 -0
- oineus-0.9.3/bindings/python/pybind11/tools/pyproject.toml +3 -0
- oineus-0.9.3/bindings/python/pybind11/tools/setup_global.py.in +63 -0
- oineus-0.9.3/bindings/python/pybind11/tools/setup_main.py.in +44 -0
- oineus-0.9.3/bindings/python/setup.py +57 -0
- oineus-0.9.3/bindings/python/tanishq_manual_matching.py +369 -0
- oineus-0.9.3/bindings/python/vectorizer.h +111 -0
- oineus-0.9.3/bindings/python/visualize_critical_set_vr.py +276 -0
- oineus-0.9.3/description.rst +14 -0
- oineus-0.9.3/doc/tutorial.md +452 -0
- oineus-0.9.3/doc/tutorial_arr.md +417 -0
- oineus-0.9.3/doc/tutorial_oop.md +333 -0
- oineus-0.9.3/extern/hera/common/diagram_point.h +262 -0
- oineus-0.9.3/extern/hera/common/diagram_reader.h +479 -0
- oineus-0.9.3/extern/hera/common/diagram_traits.h +32 -0
- oineus-0.9.3/extern/hera/common/hash_combine.h +14 -0
- oineus-0.9.3/extern/hera/common/infinity.h +23 -0
- oineus-0.9.3/extern/hera/common/point.h +40 -0
- oineus-0.9.3/extern/hera/common.h +43 -0
- oineus-0.9.3/extern/hera/dnn/geometry/euclidean-dynamic.h +278 -0
- oineus-0.9.3/extern/hera/dnn/geometry/euclidean-fixed.h +341 -0
- oineus-0.9.3/extern/hera/dnn/local/kd-tree.h +184 -0
- oineus-0.9.3/extern/hera/dnn/local/kd-tree.hpp +616 -0
- oineus-0.9.3/extern/hera/dnn/local/search-functors.h +115 -0
- oineus-0.9.3/extern/hera/dnn/parallel/tbb.h +229 -0
- oineus-0.9.3/extern/hera/dnn/parallel/utils.h +97 -0
- oineus-0.9.3/extern/hera/dnn/utils.h +44 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle.h +38 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_base.h +85 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_base.hpp +95 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_kdtree_pure_geom.h +95 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_kdtree_pure_geom.hpp +234 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_kdtree_restricted.h +120 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_kdtree_restricted.hpp +544 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_lazy_heap.h +195 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_oracle_lazy_heap.hpp +475 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_params.h +52 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_result.h +76 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_runner_gs.h +110 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_runner_gs.hpp +368 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_runner_jac.h +174 -0
- oineus-0.9.3/extern/hera/wasserstein/auction_runner_jac.hpp +600 -0
- oineus-0.9.3/extern/hera/wasserstein/basic_defs_ws.h +138 -0
- oineus-0.9.3/extern/hera/wasserstein/basic_defs_ws.hpp +114 -0
- oineus-0.9.3/extern/hera/wasserstein/catch/catch.hpp +17966 -0
- oineus-0.9.3/extern/hera/wasserstein/def_debug_ws.h +42 -0
- oineus-0.9.3/extern/hera/wasserstein/diagonal_heap.h +149 -0
- oineus-0.9.3/extern/hera/wasserstein.h +437 -0
- oineus-0.9.3/extern/hera/wasserstein_pure_geom.hpp +134 -0
- oineus-0.9.3/extern/icecream/LICENSE.txt +21 -0
- oineus-0.9.3/extern/icecream/icecream.hpp +2226 -0
- oineus-0.9.3/extern/opts/include/opts/opts.h +499 -0
- oineus-0.9.3/extern/spdlog/async.h +87 -0
- oineus-0.9.3/extern/spdlog/async_logger.h +73 -0
- oineus-0.9.3/extern/spdlog/common.h +243 -0
- oineus-0.9.3/extern/spdlog/details/async_logger_impl.h +110 -0
- oineus-0.9.3/extern/spdlog/details/circular_q.h +72 -0
- oineus-0.9.3/extern/spdlog/details/console_globals.h +74 -0
- oineus-0.9.3/extern/spdlog/details/file_helper.h +152 -0
- oineus-0.9.3/extern/spdlog/details/fmt_helper.h +122 -0
- oineus-0.9.3/extern/spdlog/details/log_msg.h +55 -0
- oineus-0.9.3/extern/spdlog/details/logger_impl.h +441 -0
- oineus-0.9.3/extern/spdlog/details/mpmc_blocking_q.h +121 -0
- oineus-0.9.3/extern/spdlog/details/null_mutex.h +45 -0
- oineus-0.9.3/extern/spdlog/details/os.h +421 -0
- oineus-0.9.3/extern/spdlog/details/pattern_formatter.h +1336 -0
- oineus-0.9.3/extern/spdlog/details/periodic_worker.h +71 -0
- oineus-0.9.3/extern/spdlog/details/registry.h +285 -0
- oineus-0.9.3/extern/spdlog/details/thread_pool.h +238 -0
- oineus-0.9.3/extern/spdlog/fmt/bin_to_hex.h +172 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/LICENSE.rst +23 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/chrono.h +452 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/color.h +577 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/core.h +1502 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/format-inl.h +972 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/format.h +3555 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/locale.h +77 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/ostream.h +153 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/posix.h +324 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/printf.h +855 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/ranges.h +308 -0
- oineus-0.9.3/extern/spdlog/fmt/bundled/time.h +160 -0
- oineus-0.9.3/extern/spdlog/fmt/fmt.h +25 -0
- oineus-0.9.3/extern/spdlog/fmt/ostr.h +18 -0
- oineus-0.9.3/extern/spdlog/formatter.h +20 -0
- oineus-0.9.3/extern/spdlog/logger.h +188 -0
- oineus-0.9.3/extern/spdlog/sinks/android_sink.h +121 -0
- oineus-0.9.3/extern/spdlog/sinks/ansicolor_sink.h +161 -0
- oineus-0.9.3/extern/spdlog/sinks/base_sink.h +69 -0
- oineus-0.9.3/extern/spdlog/sinks/basic_file_sink.h +75 -0
- oineus-0.9.3/extern/spdlog/sinks/daily_file_sink.h +141 -0
- oineus-0.9.3/extern/spdlog/sinks/dist_sink.h +94 -0
- oineus-0.9.3/extern/spdlog/sinks/msvc_sink.h +54 -0
- oineus-0.9.3/extern/spdlog/sinks/null_sink.h +49 -0
- oineus-0.9.3/extern/spdlog/sinks/ostream_sink.h +57 -0
- oineus-0.9.3/extern/spdlog/sinks/rotating_file_sink.h +164 -0
- oineus-0.9.3/extern/spdlog/sinks/sink.h +59 -0
- oineus-0.9.3/extern/spdlog/sinks/stdout_color_sinks.h +56 -0
- oineus-0.9.3/extern/spdlog/sinks/stdout_sinks.h +102 -0
- oineus-0.9.3/extern/spdlog/sinks/syslog_sink.h +94 -0
- oineus-0.9.3/extern/spdlog/sinks/wincolor_sink.h +143 -0
- oineus-0.9.3/extern/spdlog/spdlog.h +366 -0
- oineus-0.9.3/extern/spdlog/tweakme.h +145 -0
- oineus-0.9.3/extern/spdlog/version.h +12 -0
- oineus-0.9.3/extern/timer.h +22 -0
- oineus-0.9.3/include/oineus/cell.h +123 -0
- oineus-0.9.3/include/oineus/cell_with_value.h +103 -0
- oineus-0.9.3/include/oineus/common_defs.h +86 -0
- oineus-0.9.3/include/oineus/decomposition.h +1027 -0
- oineus-0.9.3/include/oineus/diagram.h +296 -0
- oineus-0.9.3/include/oineus/filtration.h +624 -0
- oineus-0.9.3/include/oineus/inclusion_filtration.h +352 -0
- oineus-0.9.3/include/oineus/io/read_write.h +190 -0
- oineus-0.9.3/include/oineus/kernel.h +557 -0
- oineus-0.9.3/include/oineus/kernel.h.tmp +534 -0
- oineus-0.9.3/include/oineus/log_wrapper.h +121 -0
- oineus-0.9.3/include/oineus/loss.h +695 -0
- oineus-0.9.3/include/oineus/lower_star.h +367 -0
- oineus-0.9.3/include/oineus/mem_reclamation.h +79 -0
- oineus-0.9.3/include/oineus/min_filtration.h +75 -0
- oineus-0.9.3/include/oineus/oineus.h +17 -0
- oineus-0.9.3/include/oineus/params.h +117 -0
- oineus-0.9.3/include/oineus/product_cell.h +249 -0
- oineus-0.9.3/include/oineus/profile.h +9 -0
- oineus-0.9.3/include/oineus/simpl_map_filtration.h +368 -0
- oineus-0.9.3/include/oineus/simplex.h +210 -0
- oineus-0.9.3/include/oineus/sparse_matrix.h +698 -0
- oineus-0.9.3/include/oineus/timer.h +28 -0
- oineus-0.9.3/include/oineus/top_optimizer.h +703 -0
- oineus-0.9.3/include/oineus/vectorizer.h +374 -0
- oineus-0.9.3/include/oineus/vietoris_rips.h +315 -0
- oineus-0.9.3/legal.txt +14 -0
- oineus-0.9.3/oineus.egg-info/PKG-INFO +37 -0
- oineus-0.9.3/oineus.egg-info/SOURCES.txt +278 -0
- oineus-0.9.3/oineus.egg-info/dependency_links.txt +1 -0
- oineus-0.9.3/oineus.egg-info/not-zip-safe +1 -0
- oineus-0.9.3/oineus.egg-info/requires.txt +3 -0
- oineus-0.9.3/oineus.egg-info/top_level.txt +1 -0
- oineus-0.9.3/peru.yaml +17 -0
- oineus-0.9.3/requirements.txt +3 -0
- oineus-0.9.3/setup.cfg +7 -0
- oineus-0.9.3/setup.py +102 -0
- oineus-0.9.3/src/read_write.cpp +324 -0
- oineus-0.9.3/tests/CMakeLists.txt +58 -0
- oineus-0.9.3/tests/a_6.txt +216 -0
- oineus-0.9.3/tests/check.py +7 -0
- oineus-0.9.3/tests/dgm_vertebra_32_0.npy +0 -0
- oineus-0.9.3/tests/dgm_vertebra_32_1.npy +0 -0
- oineus-0.9.3/tests/dgm_vertebra_32_2.npy +0 -0
- oineus-0.9.3/tests/dgm_vertebra_32_neg_0.npy +0 -0
- oineus-0.9.3/tests/dgm_vertebra_32_neg_1.npy +0 -0
- oineus-0.9.3/tests/dgm_vertebra_32_neg_2.npy +0 -0
- oineus-0.9.3/tests/induced-matching-pytest.py +46 -0
- oineus-0.9.3/tests/kernel-pytest.py +46 -0
- oineus-0.9.3/tests/kernel-test-1.py +72 -0
- oineus-0.9.3/tests/test_oin.py +45 -0
- oineus-0.9.3/tests/test_oin_random.py +58 -0
- oineus-0.9.3/tests/test_oin_vertebra.py +68 -0
- oineus-0.9.3/tests/tests_kernel_cylinder.cpp +72 -0
- oineus-0.9.3/tests/tests_reduction.cpp +137 -0
- oineus-0.9.3/tests/tests_sparse_matrix.cpp +27 -0
- oineus-0.9.3/tests/vertebra_32x32x32_float32.npy +0 -0
- oineus-0.9.3/version.txt +3 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.14)
|
|
2
|
+
|
|
3
|
+
project(oineus LANGUAGES CXX)
|
|
4
|
+
|
|
5
|
+
option(oin_use_spdlog "Use spdlog" OFF)
|
|
6
|
+
option(oin_use_jemalloc "Use jemalloc" OFF)
|
|
7
|
+
option(oin_build_tests "Build tests" ON)
|
|
8
|
+
option(oin_build_examples "Build examples" ON)
|
|
9
|
+
option(oin_gather_add_stats "Gather statistics about summand sizes" OFF)
|
|
10
|
+
option(oin_caliper "Enable profiling with Caliper" OFF)
|
|
11
|
+
|
|
12
|
+
# Default to Release
|
|
13
|
+
|
|
14
|
+
if (NOT CMAKE_BUILD_TYPE)
|
|
15
|
+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
|
16
|
+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
|
17
|
+
endif()
|
|
18
|
+
|
|
19
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
20
|
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
21
|
+
|
|
22
|
+
find_package (Threads REQUIRED)
|
|
23
|
+
find_package (TBB REQUIRED)
|
|
24
|
+
find_package (Boost REQUIRED)
|
|
25
|
+
find_package (Python3 COMPONENTS Interpreter Development REQUIRED)
|
|
26
|
+
|
|
27
|
+
message(WARNING "executable ${Python3_EXECUTABLE}, ${Python_EXECUTABLE} ")
|
|
28
|
+
|
|
29
|
+
include_directories(${Boost_INCLUDE_DIRS})
|
|
30
|
+
|
|
31
|
+
set (libraries ${libraries} ${CMAKE_THREAD_LIBS_INIT} TBB::tbb)
|
|
32
|
+
|
|
33
|
+
if (oin_use_jemalloc)
|
|
34
|
+
set (libraries ${libraries} jemalloc)
|
|
35
|
+
endif()
|
|
36
|
+
|
|
37
|
+
if(oin_caliper)
|
|
38
|
+
find_package(Caliper REQUIRED)
|
|
39
|
+
add_compile_definitions (OINEUS_USE_CALIPER)
|
|
40
|
+
set(libraries ${libraries} caliper)
|
|
41
|
+
endif()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if (oin_build_examples)
|
|
45
|
+
add_subdirectory(examples)
|
|
46
|
+
endif ()
|
|
47
|
+
|
|
48
|
+
add_subdirectory(bindings/python)
|
|
49
|
+
|
|
50
|
+
if (oin_build_tests)
|
|
51
|
+
add_subdirectory(extern/Catch2)
|
|
52
|
+
enable_testing()
|
|
53
|
+
add_subdirectory(tests)
|
|
54
|
+
endif()
|
oineus-0.9.3/MANIFEST.in
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
include CMakeLists.txt description.rst MANIFEST.in README.md licence.txt legal.txt
|
|
2
|
+
include requirements.txt peru.yaml version.txt
|
|
3
|
+
recursive-include bindings/python *
|
|
4
|
+
recursive-exclude bindings/python/pybind11/docs *
|
|
5
|
+
recursive-exclude bindings/python/pybind11/tests *
|
|
6
|
+
recursive-include extern *
|
|
7
|
+
recursive-include include/oineus *
|
|
8
|
+
recursive-include src *
|
|
9
|
+
recursive-include tests *
|
|
10
|
+
recursive-include doc *
|
|
11
|
+
global-exclude *.pyc *.swp
|
|
12
|
+
prune .git
|
|
13
|
+
recursive-exclude extern/Catch2 *
|
|
14
|
+
recursive-exclude ./*venv* *
|
|
15
|
+
recursive-exclude ./doc/_build *
|
|
16
|
+
recursive-exclude ./dist *
|
|
17
|
+
recursive-exclude *build* *
|
|
18
|
+
recursive-exclude *venv* *
|
|
19
|
+
recursive-exclude ./bindings/python/oineus/__pycache__ *
|
|
20
|
+
recursive-exclude ./.peru *
|
|
21
|
+
recursive-exclude ./.pytest_cache *
|
|
22
|
+
recursive-exclude ./tests/__pycache__ *
|
oineus-0.9.3/PKG-INFO
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: oineus
|
|
3
|
+
Version: 0.9.3
|
|
4
|
+
Summary: Library for computing persistent homology
|
|
5
|
+
Home-page: https://github.com/anigmetov/oineus
|
|
6
|
+
Author: Arnur Nigmetov
|
|
7
|
+
Author-email: anigmetov@lbl.gov
|
|
8
|
+
License: BSD
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Education
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: Topic :: Utilities
|
|
15
|
+
Classifier: Programming Language :: C++
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.5
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
20
|
+
Requires-Dist: numpy
|
|
21
|
+
Requires-Dist: scipy
|
|
22
|
+
Requires-Dist: eagerpy
|
|
23
|
+
|
|
24
|
+
Oineus
|
|
25
|
+
==========
|
|
26
|
+
|
|
27
|
+
Oineus is a computational topology library that contains:
|
|
28
|
+
|
|
29
|
+
* Shared-memory parallel algorithm to compute persistent homology.
|
|
30
|
+
* Critical set method for topological optimization.
|
|
31
|
+
* Zero-persistence diagrams.
|
|
32
|
+
* Persistence kernel-image-cokernel computaton.
|
|
33
|
+
|
|
34
|
+
Documentation
|
|
35
|
+
-------------
|
|
36
|
+
|
|
37
|
+
See docs/tutorial.md.
|
oineus-0.9.3/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
## About
|
|
2
|
+
Oineus is an implementation of shared-memory parallel
|
|
3
|
+
computation of persistent homology published in
|
|
4
|
+
*D. Morozov and A. Nigmetov.
|
|
5
|
+
"Towards lockfree persistent homology."
|
|
6
|
+
Proceedings of the 32nd ACM Symposium on Parallelism
|
|
7
|
+
in Algorithms and Architectures. 2020.*
|
|
8
|
+
|
|
9
|
+
It also contains an implementation of the critical set method
|
|
10
|
+
from
|
|
11
|
+
[*A. Nigmetov and D. Morozov,
|
|
12
|
+
"Topological Optimization with Big Steps."
|
|
13
|
+
arXiv preprint arXiv:2203.16748 (2022)."*](https://arxiv.org/abs/2203.16748)
|
|
14
|
+
|
|
15
|
+
Currently it supports computation of lower-star persistence
|
|
16
|
+
of scalar functions on regular grids or of user-defined
|
|
17
|
+
filtrations (where each simplex needs to be created manually).
|
|
18
|
+
It is written in C++ with python bindings (pybind11).
|
|
19
|
+
|
|
20
|
+
## Compilation
|
|
21
|
+
|
|
22
|
+
Oineus requires C++17 standard and python3.
|
|
23
|
+
`Pybind11` is included as a submodule.
|
|
24
|
+
Other dependencies are Boost and TBB,
|
|
25
|
+
install them before compiling Oineus.
|
|
26
|
+
E.g., on Ubuntu
|
|
27
|
+
```shell
|
|
28
|
+
$ sudo apt-get install libtbb-dev
|
|
29
|
+
$ sudo apt-get install libboost-all-dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
After that compilation is standard:
|
|
34
|
+
|
|
35
|
+
```shell
|
|
36
|
+
$ git clone --recurse-submodules git@github.com:anigmetov/oineus.git
|
|
37
|
+
$ cd oineus
|
|
38
|
+
$ mkdir build
|
|
39
|
+
$ cd build
|
|
40
|
+
$ cmake ..
|
|
41
|
+
$ make -j4
|
|
42
|
+
```
|
|
43
|
+
Compiled Oineus python package is located in `[build_directory]/python/bindings`.
|
|
44
|
+
The `oineus` directory there contains the `__init__.py` and the binary
|
|
45
|
+
with C++ bindings whose name is platform-dependent, say, `_oineus.cpython-311-x86_64-linux-gnu.so`.
|
|
46
|
+
If you get an error similar to
|
|
47
|
+
```
|
|
48
|
+
Traceback (most recent call last):
|
|
49
|
+
File "<stdin>", line 1, in <module>
|
|
50
|
+
File "/home/narn/code/oineus/bindings/python/oineus/__init__.py", line 7, in <module>
|
|
51
|
+
from . import _oineus
|
|
52
|
+
ImportError: cannot import name '_oineus' from partially initialized module 'oineus' (most likely due to a circular import) (/home/narn/code/oineus/bindings/python/oineus/__init__.py)
|
|
53
|
+
```
|
|
54
|
+
you are most probably trying to import Oineus from the source directory `oineus/bindings/python`,
|
|
55
|
+
which contains only the `__init__.py`. Make sure that `PYTHONPATH` contains the directory `oineus/build/bindings/python`.
|
|
56
|
+
|
|
57
|
+
Another possibility can be that Pybind11 did not pick up the correct Python
|
|
58
|
+
executable. Suppose that you have system-wide Python, version 3.11,
|
|
59
|
+
but you want to compile for your virtual environment, `venv` or `conda`,
|
|
60
|
+
in which you have Python 3.9. Sometimes, even you activated your Python
|
|
61
|
+
virtual environment, pybind11 chooses a different Python (you can see which one
|
|
62
|
+
in the output of `cmake ..`; also, the name of the binary
|
|
63
|
+
`_oineus.cpython-311-x86_64-linux-gnu.so` contains the version).
|
|
64
|
+
In this case, remove CMakeCache.txt and run
|
|
65
|
+
```shell
|
|
66
|
+
$ cmake .. -DPYTHON_EXECUTABLE=path_to_correct_python
|
|
67
|
+
```
|
|
68
|
+
If the command `which python` shows you the right Python,
|
|
69
|
+
the easiest is
|
|
70
|
+
```shell
|
|
71
|
+
$ cmake .. -DPYTHON_EXECUTABLE=$(which python)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
Python packages needed by Oineus are `numpy` and `scipy`. Some of the examples
|
|
76
|
+
require `torch` for optimization and `matplotlib`, `plotly` and `dash` for
|
|
77
|
+
visualization. File `requirements.txt` contains all of these; if you do not
|
|
78
|
+
need to run examples, it is simpler to just `pip install numpy scipy` in your virtual
|
|
79
|
+
environment.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
See [Tutorial](doc/tutorial.md).
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
Oineus is a free program distributed under modified
|
|
89
|
+
BSD license. See legal.txt for details.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
add_subdirectory(pybind11)
|
|
2
|
+
|
|
3
|
+
if (CMAKE_LIBRARY_OUTPUT_DIRECTORY) # to work with pip
|
|
4
|
+
set (MODULE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
|
5
|
+
else()
|
|
6
|
+
set (MODULE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
7
|
+
endif()
|
|
8
|
+
|
|
9
|
+
file (MAKE_DIRECTORY "${MODULE_OUTPUT_DIRECTORY}/oineus")
|
|
10
|
+
file (GLOB OINEUS_PYTHON "${CMAKE_CURRENT_SOURCE_DIR}/oineus/*.py")
|
|
11
|
+
|
|
12
|
+
add_custom_target (oineus ALL ${CMAKE_COMMAND} -E copy_directory
|
|
13
|
+
${CMAKE_CURRENT_SOURCE_DIR}/oineus ${MODULE_OUTPUT_DIRECTORY}/oineus
|
|
14
|
+
DEPENDS ${OINEUS_PYTHON})
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
pybind11_add_module (_oineus oineus.cpp
|
|
18
|
+
oineus_common.cpp
|
|
19
|
+
oineus_decomposition.cpp
|
|
20
|
+
oineus_index_diagram.cpp
|
|
21
|
+
oineus_fil_dgm_simplex_double.cpp
|
|
22
|
+
oineus_fil_dgm_simplex_float.cpp
|
|
23
|
+
oineus_functions_double.cpp
|
|
24
|
+
oineus_functions_float.cpp
|
|
25
|
+
oineus_top_optimizer.cpp
|
|
26
|
+
)
|
|
27
|
+
target_link_libraries (_oineus PRIVATE ${libraries})
|
|
28
|
+
target_include_directories (_oineus PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../include"
|
|
29
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/../../extern")
|
|
30
|
+
set_target_properties (_oineus PROPERTIES OUTPUT_NAME oineus/_oineus)
|
|
31
|
+
|
|
32
|
+
if (oin_use_spdlog)
|
|
33
|
+
target_compile_definitions(_oineus PRIVATE -DOINEUS_USE_SPDLOG)
|
|
34
|
+
endif()
|
|
35
|
+
|
|
36
|
+
if (oin_gather_add_stats)
|
|
37
|
+
target_compile_definitions(_oineus PRIVATE -DOINEUS_GATHER_ADD_STATS)
|
|
38
|
+
endif()
|
|
39
|
+
|
|
40
|
+
if(oin_build_tests)
|
|
41
|
+
add_custom_target (oineus_copy_to_tests ALL
|
|
42
|
+
${CMAKE_COMMAND} -E copy_directory ${MODULE_OUTPUT_DIRECTORY}/oineus "${CMAKE_CURRENT_BINARY_DIR}/../../tests/oineus"
|
|
43
|
+
DEPENDS _oineus oineus)
|
|
44
|
+
endif()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from icecream import ic
|
|
2
|
+
import oineus as oin
|
|
3
|
+
import numpy as np
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
DIM = 1
|
|
6
|
+
WASS_DIST_Q = 2
|
|
7
|
+
max_dim = 1
|
|
8
|
+
empty = oin.Diagrams_double(DIM+1)[DIM]
|
|
9
|
+
Z = np.random.random((100,2))
|
|
10
|
+
fil,longest_edges = oin.get_vr_filtration_and_critical_edges(Z, max_dim=2, max_radius=np.inf, n_threads=4)
|
|
11
|
+
top_opt = oin.TopologyOptimizer(fil)
|
|
12
|
+
diagram = top_opt.compute_diagram(include_inf_points=False)
|
|
13
|
+
#Same loss as before with edges, i.e. align edges to their critical lengths
|
|
14
|
+
indices, values = top_opt.match(empty, DIM, WASS_DIST_Q )
|
|
15
|
+
ic(indices,values)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!python3
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import oineus as oin
|
|
5
|
+
|
|
6
|
+
# scalar function on 8x8x8 grid
|
|
7
|
+
np.random.seed(1)
|
|
8
|
+
f = np.random.uniform(size=(8, 8, 8))
|
|
9
|
+
|
|
10
|
+
# triangulate domain via Freudenthal and create lower star filtration
|
|
11
|
+
# negate: set to True to get upper-star filtration
|
|
12
|
+
# wrap: set to True to work on torus (periodic boundary conditions)
|
|
13
|
+
fil = oin.get_freudenthal_filtration(data=f, negate=False, wrap=False, max_dim=3, n_threads=1)
|
|
14
|
+
|
|
15
|
+
cells = fil.cells()
|
|
16
|
+
|
|
17
|
+
# Vertices in cells are ids, not sorted_ids
|
|
18
|
+
print(f"Filtration with {len(cells)} cells created,\nvertex 0: {cells[0]},\nlast simplex: {cells[-1]}")
|
|
19
|
+
|
|
20
|
+
# no cohomology
|
|
21
|
+
dualize = False
|
|
22
|
+
# create VRU decomposition object, does not perform reduction yet
|
|
23
|
+
dcmp = oin.Decomposition(fil, dualize)
|
|
24
|
+
|
|
25
|
+
# reduction parameters
|
|
26
|
+
# relevant members:
|
|
27
|
+
# rp.clearing_opt --- whether you want to use clearing, True by default
|
|
28
|
+
# rp.compute_v: True by default
|
|
29
|
+
# rp.n_threads: number of threads to use, default is 1
|
|
30
|
+
# rp. compute_u: False by default (cannot do it in multi-threaded mode, so switch off just to be on the safe side)
|
|
31
|
+
rp = oin.ReductionParams()
|
|
32
|
+
|
|
33
|
+
# perform reduction
|
|
34
|
+
dcmp.reduce(rp)
|
|
35
|
+
|
|
36
|
+
# now we can acess V, R and U
|
|
37
|
+
# indices are sorted_ids of simplices == indices in fil.cells()
|
|
38
|
+
V = dcmp.v_data
|
|
39
|
+
print(f"Example of a V column: {V[-1]}, this chain contains cells:")
|
|
40
|
+
for sigma_idx in V[-1]:
|
|
41
|
+
print(cells[sigma_idx])
|
|
42
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!python3
|
|
2
|
+
|
|
3
|
+
from icecream import ic
|
|
4
|
+
import numpy as np
|
|
5
|
+
import oineus as oin
|
|
6
|
+
|
|
7
|
+
n_pts = 5
|
|
8
|
+
|
|
9
|
+
pts = np.random.uniform(size=n_pts * 2).reshape(n_pts, 2).astype(np.float64)
|
|
10
|
+
|
|
11
|
+
fil_1 = oin.get_vr_filtration(pts, 1, 2.0, 1)
|
|
12
|
+
fil_2 = oin.get_vr_filtration(pts, 1, 2.0, 1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
simplices = fil_1.simplices()
|
|
16
|
+
|
|
17
|
+
fil_min_simplices = []
|
|
18
|
+
|
|
19
|
+
for sigma in simplices:
|
|
20
|
+
min_sigma = oin.Simplex_double(sigma.vertices, min(sigma.value, fil_2.simplex_value_by_vertices(sigma.vertices)))
|
|
21
|
+
fil_min_simplices.append(min_sigma)
|
|
22
|
+
|
|
23
|
+
fil_min = oin.Filtration_double(fil_min_simplices)
|
|
24
|
+
|
|
25
|
+
cone_v = fil_min.n_vertices()
|
|
26
|
+
|
|
27
|
+
# must make copy here! otherwise iteration in for loop below will never end,
|
|
28
|
+
# since we keep adding to the same list over which we iterate
|
|
29
|
+
coned_simplices = simplices[:]
|
|
30
|
+
simplex_id = fil_min.size()
|
|
31
|
+
|
|
32
|
+
for sigma in simplices:
|
|
33
|
+
coned_sigma = sigma.join(new_vertex=cone_v, value=sigma.value, new_id=simplex_id)
|
|
34
|
+
simplex_id += 1
|
|
35
|
+
coned_simplices.append(coned_sigma)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
fil_coned = oin.Filtration_double(coned_simplices, sort_only_by_dimension=True, set_ids=False)
|
|
39
|
+
|
|
40
|
+
print(fil_coned)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!python3
|
|
2
|
+
|
|
3
|
+
from icecream import ic
|
|
4
|
+
import numpy as np
|
|
5
|
+
import oineus as oin
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
n_pts = 50
|
|
9
|
+
|
|
10
|
+
np.random.seed(1)
|
|
11
|
+
|
|
12
|
+
pts_1 = np.random.uniform(low=0.0, high=5.0, size=n_pts * 2).reshape(n_pts, 2).astype(np.float64)
|
|
13
|
+
pts_2 = pts_1 + np.random.uniform(size=n_pts *2, low=-0.01, high=0.01).reshape(pts_1.shape)
|
|
14
|
+
|
|
15
|
+
# input: pts
|
|
16
|
+
# output: VR filtration and torch Tensor with the lengths
|
|
17
|
+
# of critical edges in filtration order, that is:
|
|
18
|
+
# fil.simplices()[sorted_idx].value == lengths[sorted_idx]
|
|
19
|
+
def get_vr_filtration_and_vals(pts, max_dim, max_radius):
|
|
20
|
+
fil, edges = oin.get_vr_filtration_and_critical_edges(pts, max_dim=max_dim, max_radius=max_radius, n_threads=1)
|
|
21
|
+
fil.reset_ids_to_sorted_ids()
|
|
22
|
+
pts = torch.Tensor(pts)
|
|
23
|
+
edge_start, edge_end = edges[:, 0], edges[:, 1]
|
|
24
|
+
lengths = torch.sum((pts[edge_start, :] - pts[edge_end, :])**2, axis=1) ** 0.5
|
|
25
|
+
|
|
26
|
+
return fil, lengths
|
|
27
|
+
|
|
28
|
+
max_dim = 2
|
|
29
|
+
max_radius = 1000.0
|
|
30
|
+
|
|
31
|
+
fil_1, lengths_1 = get_vr_filtration_and_vals(pts_1, max_dim, max_radius)
|
|
32
|
+
fil_2, lengths_2 = get_vr_filtration_and_vals(pts_2, max_dim, max_radius)
|
|
33
|
+
|
|
34
|
+
# create fil_min
|
|
35
|
+
|
|
36
|
+
simplices_1 = fil_1.simplices()
|
|
37
|
+
simplices_2 = fil_2.simplices()
|
|
38
|
+
|
|
39
|
+
fil_min_simplices = []
|
|
40
|
+
|
|
41
|
+
for sigma in simplices_1:
|
|
42
|
+
min_sigma = oin.Simplex_double(sigma.sorted_id, sigma.vertices,
|
|
43
|
+
min(sigma.value, fil_2.simplex_value_by_vertices(sigma.vertices)))
|
|
44
|
+
fil_min_simplices.append(min_sigma)
|
|
45
|
+
|
|
46
|
+
fil_min = oin.Filtration_double(fil_min_simplices, set_ids=False)
|
|
47
|
+
|
|
48
|
+
# now simplices became reshuffled
|
|
49
|
+
# we must permute lengths_1 and lengths_2 accordingly
|
|
50
|
+
# id of simplex in fil_min is it's sorted_id in the original filtration
|
|
51
|
+
|
|
52
|
+
min_sorted_id_to_sorted_id_1 = fil_min.get_inv_sorting_permutation()
|
|
53
|
+
|
|
54
|
+
lengths_1_in_min_order = lengths_1[torch.LongTensor(min_sorted_id_to_sorted_id_1)]
|
|
55
|
+
|
|
56
|
+
min_simplices = fil_min.simplices()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
min_sorted_id_to_sorted_id_2 = [ fil_2.get_sorted_id_by_vertices(min_sigma.vertices) for min_sigma in min_simplices ]
|
|
60
|
+
|
|
61
|
+
lengths_2_in_min_order = lengths_2[torch.LongTensor(min_sorted_id_to_sorted_id_2)]
|
|
62
|
+
|
|
63
|
+
for i, sigma in enumerate(min_simplices):
|
|
64
|
+
s1 = simplices_1[fil_1.get_sorted_id_by_vertices(sigma.vertices)]
|
|
65
|
+
s2 = simplices_2[fil_2.get_sorted_id_by_vertices(sigma.vertices)]
|
|
66
|
+
assert np.abs(s1.value - lengths_1_in_min_order[i]) < 0.0001
|
|
67
|
+
assert np.abs(s2.value - lengths_2_in_min_order[i]) < 0.0001
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
min_critical_values = torch.min(torch.stack((lengths_1_in_min_order, lengths_2_in_min_order)), axis=0)[0]
|
|
71
|
+
|
|
72
|
+
# verify that we got the critical values correctly
|
|
73
|
+
for sigma in min_simplices:
|
|
74
|
+
assert torch.abs(sigma.value - min_critical_values[sigma.sorted_id]) < 0.00001
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
min_and_coned_simplices = min_simplices[:]
|
|
78
|
+
cone_v = fil_min.n_vertices()
|
|
79
|
+
|
|
80
|
+
# append cone vertex
|
|
81
|
+
# TODO: how to ensure that cone_vertex appears first?
|
|
82
|
+
# for now we can ignore it
|
|
83
|
+
min_and_coned_simplices.append(oin.Simplex_double(cone_v, [cone_v], 0.0))
|
|
84
|
+
|
|
85
|
+
simplex_id = len(min_and_coned_simplices)
|
|
86
|
+
|
|
87
|
+
# take cones over simplices from fil_1
|
|
88
|
+
for sigma in simplices_1:
|
|
89
|
+
coned_sigma = sigma.join(new_vertex=cone_v, value=sigma.value, new_id=simplex_id)
|
|
90
|
+
simplex_id += 1
|
|
91
|
+
min_and_coned_simplices.append(coned_sigma)
|
|
92
|
+
|
|
93
|
+
fil_min_and_coned = oin.Filtration_double(min_and_coned_simplices, set_ids=False)
|
|
94
|
+
|
|
95
|
+
# in filtration order
|
|
96
|
+
min_and_coned_simplices = fil_min_and_coned.simplices()
|
|
97
|
+
|
|
98
|
+
for sigma in min_and_coned_simplices:
|
|
99
|
+
if cone_v in sigma.vertices:
|
|
100
|
+
if sigma.dim() == 0:
|
|
101
|
+
continue
|
|
102
|
+
# subtract additional 1 for cone vertex
|
|
103
|
+
orig_sorted_sigma_id = sigma.id - len(fil_1) - 1
|
|
104
|
+
assert(np.abs(lengths_1[orig_sorted_sigma_id] - sigma.value) < 0.00001)
|
|
105
|
+
else:
|
|
106
|
+
orig_sigma_id = sigma.id
|
|
107
|
+
orig_sorted_sigma_id = fil_min.get_sorted_id_by_id(orig_sigma_id)
|
|
108
|
+
assert(np.abs(min_critical_values[orig_sorted_sigma_id] - sigma.value) < 0.00001)
|
|
109
|
+
|
|
110
|
+
print(fil_min_and_coned)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!python3
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import oineus as oin
|
|
5
|
+
|
|
6
|
+
# here we create a simple example (triangle) with vertices
|
|
7
|
+
# v0 (critical value 0.2)
|
|
8
|
+
# v1 (critical value 0.1)
|
|
9
|
+
# v3 (critical value 0.3)
|
|
10
|
+
# edges: e1 = [v0, v1]
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
v0 = oin.Simplex_double([0], 0.2)
|
|
14
|
+
v1 = oin.Simplex_double([1], 0.1)
|
|
15
|
+
v2 = oin.Simplex_double([2], 0.3)
|
|
16
|
+
|
|
17
|
+
# indices of vertices should be sorted
|
|
18
|
+
e1 = oin.Simplex_double([0, 1], 0.9)
|
|
19
|
+
e2 = oin.Simplex_double([0, 2], 0.5)
|
|
20
|
+
e3 = oin.Simplex_double([1, 2], 0.8)
|
|
21
|
+
|
|
22
|
+
t = oin.Simplex_double([0, 1, 2], 1.0)
|
|
23
|
+
|
|
24
|
+
simplices = [v0, v1, v2, e1, e2, e3, t]
|
|
25
|
+
|
|
26
|
+
negate = False
|
|
27
|
+
n_threads = 1
|
|
28
|
+
|
|
29
|
+
# constructor will sort simplices and assign sorted_ids
|
|
30
|
+
fil = oin.Filtration_double(simplices, negate, n_threads)
|
|
31
|
+
|
|
32
|
+
fil_simplices = fil.simplices()
|
|
33
|
+
|
|
34
|
+
for sigma in fil.simplices():
|
|
35
|
+
print(sigma)
|
|
36
|
+
|
|
37
|
+
# no cohomology
|
|
38
|
+
dualize = False
|
|
39
|
+
# create VRU decomposition object, does not perform reduction yet
|
|
40
|
+
dcmp = oin.Decomposition(fil, dualize)
|
|
41
|
+
|
|
42
|
+
# reduction parameters
|
|
43
|
+
# relevant members:
|
|
44
|
+
# rp.clearing_opt --- whether you want to use clearing, True by default
|
|
45
|
+
# rp.compute_v: True by default
|
|
46
|
+
# rp.n_threads: number of threads to use, default is 1
|
|
47
|
+
# rp. compute_u: False by default (cannot do it in multi-threaded mode, so switch off just to be on the safe side)
|
|
48
|
+
rp = oin.ReductionParams()
|
|
49
|
+
|
|
50
|
+
# perform reduction
|
|
51
|
+
dcmp.reduce(rp)
|
|
52
|
+
|
|
53
|
+
# get diagram, including points at infinity
|
|
54
|
+
include_inf_points=True
|
|
55
|
+
dgm = dcmp.diagram(fil, include_inf_points)
|
|
56
|
+
|
|
57
|
+
# diagram in dimension d is numpy array dgm[d], shape = (number of diagram points, 2)
|
|
58
|
+
|
|
59
|
+
for dim in [0, 1]:
|
|
60
|
+
print(f"Diagram in dimension {dim}:")
|
|
61
|
+
print(dgm[dim])
|
|
62
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from icecream import ic
|
|
5
|
+
|
|
6
|
+
import oineus as oin
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def evaluate_func(x, y, z):
|
|
10
|
+
return np.sin(x + 2 * y + 3 * z ** 2)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Create a 16x16x16 grid
|
|
14
|
+
x = np.linspace(-np.pi, np.pi, 16)
|
|
15
|
+
y = np.linspace(-np.pi, np.pi, 16)
|
|
16
|
+
z = np.linspace(-np.pi, np.pi, 16)
|
|
17
|
+
|
|
18
|
+
# Generate a 3D meshgrid
|
|
19
|
+
X, Y, Z = np.meshgrid(x, y, z)
|
|
20
|
+
|
|
21
|
+
# Evaluate the function on the grid
|
|
22
|
+
f = evaluate_func(X, Y, Z)
|
|
23
|
+
|
|
24
|
+
fil, max_value_vertices = oin.get_freudenthal_filtration_and_critical_vertices(f, negate=False, wrap=False, max_dim=2, n_threads=8)
|
|
25
|
+
|
|
26
|
+
top_opt = oin.TopologyOptimizer(fil)
|
|
27
|
+
|
|
28
|
+
dim = 1
|
|
29
|
+
n = 4
|
|
30
|
+
|
|
31
|
+
dgm = top_opt.compute_diagram(include_inf_points=False)
|
|
32
|
+
eps = top_opt.get_nth_persistence(dim, 4)
|
|
33
|
+
indices, values = top_opt.simplify(eps, oin.DenoiseStrategy.BirthBirth, dim)
|
|
34
|
+
critical_sets = top_opt.singletons(indices, values)
|
|
35
|
+
crit_indices, crit_values = top_opt.combine_loss(critical_sets, oin.ConflictStrategy.Max)
|
|
36
|
+
|
|
37
|
+
crit_indices = np.array(crit_indices, dtype=np.int32)
|
|
38
|
+
crit_vertices = max_value_vertices[crit_indices]
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import torch
|
|
5
|
+
from matplotlib import pyplot as plt
|
|
6
|
+
import oineus as oin
|
|
7
|
+
|
|
8
|
+
def sample_data():
|
|
9
|
+
# sample points from the unit circle
|
|
10
|
+
# return points as differentiable torch tensor
|
|
11
|
+
np.random.seed(1)
|
|
12
|
+
|
|
13
|
+
num_points = 120
|
|
14
|
+
noise_std_dev = 0.1
|
|
15
|
+
|
|
16
|
+
angles = np.random.uniform(low=0, high=2*np.pi, size=num_points)
|
|
17
|
+
x = np.cos(angles)
|
|
18
|
+
y = np.sin(angles)
|
|
19
|
+
|
|
20
|
+
x += np.random.normal(loc=0, scale=noise_std_dev, size=num_points)
|
|
21
|
+
y += np.random.normal(loc=0, scale=noise_std_dev, size=num_points)
|
|
22
|
+
|
|
23
|
+
pts = np.vstack((x, y)).T
|
|
24
|
+
pts = torch.Tensor(pts)
|
|
25
|
+
pts.requires_grad_(True)
|
|
26
|
+
|
|
27
|
+
return pts
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def topological_loss(pts: torch.Tensor, dim: int=1, n: int=2):
|
|
31
|
+
pts_as_numpy = pts.clone().detach().numpy().astype(np.float64)
|
|
32
|
+
fil, longest_edges = oin.get_vr_filtration_and_critical_edges(pts_as_numpy, max_dim=2, max_radius=9.0, n_threads=1)
|
|
33
|
+
top_opt = oin.TopologyOptimizer(fil)
|
|
34
|
+
|
|
35
|
+
# dgm = top_opt.compute_diagram(include_inf_points=False)
|
|
36
|
+
# print(dgm.in_dimension(dim))
|
|
37
|
+
|
|
38
|
+
eps = top_opt.get_nth_persistence(dim, n)
|
|
39
|
+
print(f"{eps= }")
|
|
40
|
+
|
|
41
|
+
indices, values = top_opt.simplify(eps, oin.DenoiseStrategy.BirthBirth, dim)
|
|
42
|
+
|
|
43
|
+
critical_sets = top_opt.singletons(indices, values)
|
|
44
|
+
crit_indices, crit_method_values = top_opt.combine_loss(critical_sets, oin.ConflictStrategy.Max)
|
|
45
|
+
|
|
46
|
+
crit_indices = np.array(crit_indices, dtype=np.int32)
|
|
47
|
+
|
|
48
|
+
dgm_method_edges = longest_edges[indices, :]
|
|
49
|
+
dgm_method_edges_x, dgm_method_edges_y = dgm_method_edges[:, 0], dgm_method_edges[:, 1]
|
|
50
|
+
|
|
51
|
+
dgm_method_values = torch.Tensor(values)
|
|
52
|
+
|
|
53
|
+
crit_method_edges = longest_edges[crit_indices, :]
|
|
54
|
+
crit_method_edges_x, crit_method_edges_y = crit_method_edges[:, 0], crit_method_edges[:, 1]
|
|
55
|
+
|
|
56
|
+
crit_method_values = torch.Tensor(crit_method_values)
|
|
57
|
+
|
|
58
|
+
if len(crit_method_edges_x) > 0:
|
|
59
|
+
dgm_loss = torch.sum(torch.abs(torch.sum((pts[dgm_method_edges_x, :] - pts[dgm_method_edges_y, :])**2, axis=1) - dgm_method_values ** 2))
|
|
60
|
+
top_loss = torch.sum(torch.abs(torch.sum((pts[crit_method_edges_x, :] - pts[crit_method_edges_y, :])**2, axis=1) - crit_method_values ** 2))
|
|
61
|
+
else:
|
|
62
|
+
top_loss = torch.zeros(())
|
|
63
|
+
dgm_loss = torch.zeros(())
|
|
64
|
+
|
|
65
|
+
top_loss.requires_grad_(True)
|
|
66
|
+
dgm_loss.requires_grad_(True)
|
|
67
|
+
return top_loss, dgm_loss
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
draw = False
|
|
72
|
+
use_critical_sets = False
|
|
73
|
+
|
|
74
|
+
pts = sample_data()
|
|
75
|
+
|
|
76
|
+
lr = 0.2
|
|
77
|
+
|
|
78
|
+
opt = torch.optim.SGD([pts], lr=lr)
|
|
79
|
+
|
|
80
|
+
for step_idx in range(5):
|
|
81
|
+
opt.zero_grad()
|
|
82
|
+
|
|
83
|
+
loss, dgm_loss = topological_loss(pts, dim=1, n=1)
|
|
84
|
+
|
|
85
|
+
print(f"{step_idx = }, {loss = }, {dgm_loss = }")
|
|
86
|
+
|
|
87
|
+
if draw:
|
|
88
|
+
np_pts = pts.clone().detach().numpy()
|
|
89
|
+
plt.scatter(np_pts[:, 0], np_pts[:, 1], color="green")
|
|
90
|
+
|
|
91
|
+
if loss.item() == 0:
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
if use_critical_sets:
|
|
95
|
+
loss.backward()
|
|
96
|
+
else:
|
|
97
|
+
dgm_loss.backward()
|
|
98
|
+
|
|
99
|
+
opt.step()
|
|
100
|
+
|
|
101
|
+
if draw:
|
|
102
|
+
np_pts = pts.clone().detach().numpy()
|
|
103
|
+
plt.scatter(np_pts[:, 0], np_pts[:, 1], color="red")
|
|
104
|
+
plt.show()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|