diff options
author | ROUVREAU Vincent <vincent.rouvreau@inria.fr> | 2021-04-03 10:27:08 +0200 |
---|---|---|
committer | ROUVREAU Vincent <vincent.rouvreau@inria.fr> | 2021-04-03 10:27:08 +0200 |
commit | e4381a3e2ad79d3150cd03704bef3fc006e7c54b (patch) | |
tree | 755aa40eb646798ed87152d4940b9f4b8379ea96 /src/python/include | |
parent | 98cc06acb5f4b7caf4c23645614a472f7f9b5f3a (diff) |
Python alpha complex specific 3d with weighted version and functor to get points
Diffstat (limited to 'src/python/include')
-rw-r--r-- | src/python/include/Alpha_complex_factory.h | 48 | ||||
-rw-r--r-- | src/python/include/Alpha_complex_interface.h | 59 | ||||
-rw-r--r-- | src/python/include/Alpha_complex_interface_3d.h | 71 |
3 files changed, 130 insertions, 48 deletions
diff --git a/src/python/include/Alpha_complex_factory.h b/src/python/include/Alpha_complex_factory.h index 36e98615..5d3bfb65 100644 --- a/src/python/include/Alpha_complex_factory.h +++ b/src/python/include/Alpha_complex_factory.h @@ -31,6 +31,34 @@ namespace Gudhi { namespace alpha_complex { +template<typename CgalPointType, bool Weighted> +struct Point_cgal_to_cython; + +template<typename CgalPointType> +struct Point_cgal_to_cython<CgalPointType, false> { + std::vector<double> operator()(CgalPointType const& point) const + { + std::vector<double> vd; + vd.reserve(point.dimension()); + for (auto coord = point.cartesian_begin(); coord != point.cartesian_end(); coord++) + vd.push_back(CGAL::to_double(*coord)); + return vd; + } +}; + +template<typename CgalPointType> +struct Point_cgal_to_cython<CgalPointType, true> { + std::vector<double> operator()(CgalPointType const& weighted_point) const + { + auto point = weighted_point.point(); + std::vector<double> vd; + vd.reserve(point.dimension()); + for (auto coord = point.cartesian_begin(); coord != point.cartesian_end(); coord++) + vd.push_back(CGAL::to_double(*coord)); + return vd; + } +}; + template <typename CgalPointType> std::vector<double> pt_cgal_to_cython(CgalPointType const& point) { std::vector<double> vd; @@ -159,13 +187,14 @@ class Inexact_weighted_alpha_complex_dD final : public Abstract_alpha_complex { Alpha_complex<Kernel, true> alpha_complex_; }; -template <complexity Complexity> +template <complexity Complexity, bool Weighted = false> class Alpha_complex_3D final : public Abstract_alpha_complex { private: - using Point = typename Alpha_complex_3d<Complexity, false, false>::Bare_point_3; + using Bare_point = typename Alpha_complex_3d<Complexity, Weighted, false>::Bare_point_3; + using Point = typename Alpha_complex_3d<Complexity, Weighted, false>::Point_3; - static Point pt_cython_to_cgal_3(std::vector<double> const& vec) { - return Point(vec[0], vec[1], vec[2]); + static Bare_point pt_cython_to_cgal_3(std::vector<double> const& vec) { + return Bare_point(vec[0], vec[1], vec[2]); } public: @@ -173,18 +202,23 @@ class Alpha_complex_3D final : public Abstract_alpha_complex { : alpha_complex_(boost::adaptors::transform(points, pt_cython_to_cgal_3)) { } + Alpha_complex_3D(const std::vector<std::vector<double>>& points, const std::vector<double>& weights) + : alpha_complex_(boost::adaptors::transform(points, pt_cython_to_cgal_3), weights) { + } + virtual std::vector<double> get_point(int vh) override { Point const& point = alpha_complex_.get_point(vh); - return pt_cgal_to_cython(point); + return Point_cgal_to_cython<Point, Weighted>()(point); } virtual bool create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square, bool default_filtration_value) override { - return alpha_complex_.create_complex(*simplex_tree, max_alpha_square); + alpha_complex_.create_complex(*simplex_tree, max_alpha_square); + return true; } private: - Alpha_complex_3d<Complexity, false, false> alpha_complex_; + Alpha_complex_3d<Complexity, Weighted, false> alpha_complex_; }; diff --git a/src/python/include/Alpha_complex_interface.h b/src/python/include/Alpha_complex_interface.h index 43c96b2f..31a8147b 100644 --- a/src/python/include/Alpha_complex_interface.h +++ b/src/python/include/Alpha_complex_interface.h @@ -30,10 +30,20 @@ class Alpha_complex_interface { Alpha_complex_interface(const std::vector<std::vector<double>>& points, const std::vector<double>& weights, bool fast_version, bool exact_version) - : points_(points), - weights_(weights), - fast_version_(fast_version), - exact_version_(exact_version) { + : empty_point_set_(points.size() == 0) { + if (fast_version) { + if (weights.size() == 0) { + alpha_ptr_ = std::make_unique<Inexact_alpha_complex_dD>(points, exact_version); + } else { + alpha_ptr_ = std::make_unique<Inexact_weighted_alpha_complex_dD>(points, weights, exact_version); + } + } else { + if (weights.size() == 0) { + alpha_ptr_ = std::make_unique<Exact_alpha_complex_dD>(points, exact_version); + } else { + alpha_ptr_ = std::make_unique<Exact_weighted_alpha_complex_dD>(points, weights, exact_version); + } + } } std::vector<double> get_point(int vh) { @@ -42,47 +52,14 @@ class Alpha_complex_interface { void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square, bool default_filtration_value) { - if (points_.size() > 0) { - std::size_t dimension = points_[0].size(); - if (dimension == 3 && weights_.size() == 0 && !default_filtration_value) { - if (fast_version_) - alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::FAST>>(points_); - else if (exact_version_) - alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::EXACT>>(points_); - else - alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::SAFE>>(points_); - if (!alpha_ptr_->create_simplex_tree(simplex_tree, max_alpha_square, default_filtration_value)) { - // create_simplex_tree will fail if all points are on a plane - Retry with dD by setting dimension to 2 - dimension--; - alpha_ptr_.reset(); - } - } - // Not ** else ** because we have to take into account if 3d fails - if (dimension != 3 || weights_.size() != 0 || default_filtration_value) { - if (fast_version_) { - if (weights_.size() == 0) { - alpha_ptr_ = std::make_unique<Inexact_alpha_complex_dD>(points_, exact_version_); - } else { - alpha_ptr_ = std::make_unique<Inexact_weighted_alpha_complex_dD>(points_, weights_, exact_version_); - } - } else { - if (weights_.size() == 0) { - alpha_ptr_ = std::make_unique<Exact_alpha_complex_dD>(points_, exact_version_); - } else { - alpha_ptr_ = std::make_unique<Exact_weighted_alpha_complex_dD>(points_, weights_, exact_version_); - } - } - alpha_ptr_->create_simplex_tree(simplex_tree, max_alpha_square, default_filtration_value); - } - } + // Nothing to be done in case of an empty point set + if (!empty_point_set_) + alpha_ptr_->create_simplex_tree(simplex_tree, max_alpha_square, default_filtration_value); } private: std::unique_ptr<Abstract_alpha_complex> alpha_ptr_; - std::vector<std::vector<double>> points_; - std::vector<double> weights_; - bool fast_version_; - bool exact_version_; + bool empty_point_set_; }; } // namespace alpha_complex diff --git a/src/python/include/Alpha_complex_interface_3d.h b/src/python/include/Alpha_complex_interface_3d.h new file mode 100644 index 00000000..bb66b8e1 --- /dev/null +++ b/src/python/include/Alpha_complex_interface_3d.h @@ -0,0 +1,71 @@ +/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. + * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details. + * Author(s): Vincent Rouvreau + * + * Copyright (C) 2021 Inria + * + * Modification(s): + * - YYYY/MM Author: Description of the modification + */ + +#ifndef INCLUDE_ALPHA_COMPLEX_INTERFACE_3D_H_ +#define INCLUDE_ALPHA_COMPLEX_INTERFACE_3D_H_ + +#include "Alpha_complex_factory.h" +#include <gudhi/Alpha_complex_options.h> + +#include "Simplex_tree_interface.h" + +#include <iostream> +#include <vector> +#include <string> +#include <memory> // for std::unique_ptr + +namespace Gudhi { + +namespace alpha_complex { + +class Alpha_complex_interface_3d { + public: + Alpha_complex_interface_3d(const std::vector<std::vector<double>>& points, + const std::vector<double>& weights, + bool fast_version, bool exact_version) + : empty_point_set_(points.size() == 0) { + const bool weighted = (weights.size() > 0); + if (fast_version) + if (weighted) + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::FAST, true>>(points, weights); + else + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::FAST>>(points); + else if (exact_version) + if (weighted) + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::EXACT, true>>(points, weights); + else + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::EXACT>>(points); + else + if (weighted) + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::SAFE, true>>(points, weights); + else + alpha_ptr_ = std::make_unique<Alpha_complex_3D<Gudhi::alpha_complex::complexity::SAFE>>(points); + } + + std::vector<double> get_point(int vh) { + return alpha_ptr_->get_point(vh); + } + + void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, double max_alpha_square) { + // Nothing to be done in case of an empty point set + if (!empty_point_set_) + alpha_ptr_->create_simplex_tree(simplex_tree, max_alpha_square, false); + } + + private: + std::unique_ptr<Abstract_alpha_complex> alpha_ptr_; + bool empty_point_set_; +}; + +} // namespace alpha_complex + +} // namespace Gudhi + +#endif // INCLUDE_ALPHA_COMPLEX_INTERFACE_3D_H_ |