11#ifndef IMPLICIT_MANIFOLD_INTERSECTION_ORACLE_H_
12#define IMPLICIT_MANIFOLD_INTERSECTION_ORACLE_H_
16#include <gudhi/Permutahedral_representation/face_from_indices.h>
17#include <gudhi/Functions/Constant_function.h>
18#include <gudhi/Functions/PL_approximation.h>
19#include <gudhi/Coxeter_triangulation/Query_result.h>
20#include <gudhi/Debug_utils.h>
28namespace coxeter_triangulation {
40template <
class Function_,
class Domain_function_ = Constant_function>
44 template <
class Simplex_handle,
class Triangulation>
45 Eigen::VectorXd compute_lambda(
const Simplex_handle& simplex,
const Triangulation& triangulation)
const {
48 for (std::size_t i = 0; i <
cod_d + 1; ++i) matrix(0, i) = 1;
50 for (
auto v : simplex.vertex_range()) {
51 Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v));
52 for (std::size_t i = 1; i <
cod_d + 1; ++i) matrix(i, j) = v_coords(i - 1);
55 Eigen::VectorXd z(
cod_d + 1);
57 for (std::size_t i = 1; i <
cod_d + 1; ++i) z(i) = 0;
58 Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z);
59 if (!z.isApprox(matrix*lambda)) {
61 for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) lambda(i) =
62 std::numeric_limits<double>::quiet_NaN();
69 template <
class Simplex_handle,
class Triangulation>
70 Eigen::VectorXd compute_boundary_lambda(
const Simplex_handle& simplex,
const Triangulation& triangulation)
const {
73 for (std::size_t i = 0; i <
cod_d + 2; ++i) matrix(0, i) = 1;
75 for (
auto v : simplex.vertex_range()) {
76 Eigen::VectorXd v_coords = fun_(triangulation.cartesian_coordinates(v));
77 for (std::size_t i = 1; i <
cod_d + 1; ++i) matrix(i, j) = v_coords(i - 1);
78 Eigen::VectorXd bv_coords = domain_fun_(triangulation.cartesian_coordinates(v));
79 matrix(
cod_d + 1, j) = bv_coords(0);
82 Eigen::VectorXd z(
cod_d + 2);
84 for (std::size_t i = 1; i <
cod_d + 2; ++i) z(i) = 0;
85 Eigen::VectorXd lambda = matrix.colPivHouseholderQr().solve(z);
86 if (!z.isApprox(matrix*lambda)) {
88 for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) lambda(i) =
89 std::numeric_limits<double>::quiet_NaN();
95 template <
class Simplex_handle,
class Triangulation>
97 const Triangulation& triangulation)
const {
99 std::size_t
amb_d = triangulation.dimension();
100 std::size_t
cod_d = simplex.dimension();
101 for (std::size_t i = 0; i < (std::size_t)lambda.size(); ++i) {
102 if (std::isnan(lambda(i)))
return QR({Eigen::VectorXd(),
false});
103 GUDHI_CHECK((std::fabs(lambda(i) - 1.) > std::numeric_limits<double>::epsilon() &&
104 std::fabs(lambda(i) - 0.) > std::numeric_limits<double>::epsilon()),
105 std::invalid_argument(
"A vertex of the triangulation lies exactly on the manifold"));
106 if (lambda(i) < 0. || lambda(i) > 1.)
return QR({Eigen::VectorXd(),
false});
108 Eigen::MatrixXd vertex_matrix(
cod_d + 1,
amb_d);
109 auto v_range = simplex.vertex_range();
110 auto v_it = v_range.begin();
111 for (std::size_t i = 0; i <
cod_d + 1 && v_it != v_range.end(); ++v_it, ++i) {
112 Eigen::VectorXd v_coords = triangulation.cartesian_coordinates(*v_it);
113 for (std::size_t j = 0; j <
amb_d; ++j) vertex_matrix(i, j) = v_coords(j);
115 Eigen::VectorXd intersection = lambda.transpose() * vertex_matrix;
116 return QR({intersection,
true});
121 std::size_t
amb_d()
const {
return fun_.amb_d(); }
124 std::size_t
cod_d()
const {
return fun_.cod_d(); }
127 Eigen::VectorXd
seed()
const {
return fun_.seed(); }
149 template <
class Simplex_handle,
class Triangulation>
151 Eigen::VectorXd lambda = compute_lambda(simplex, triangulation);
152 return intersection_result(lambda, simplex, triangulation);
175 template <
class Simplex_handle,
class Triangulation>
177 const Triangulation& triangulation)
const {
179 Eigen::VectorXd lambda = compute_boundary_lambda(simplex, triangulation);
180 return intersection_result(lambda, simplex, triangulation);
193 template <
class Triangulation>
194 bool lies_in_domain(
const Eigen::VectorXd& p,
const Triangulation& triangulation)
const {
211 : fun_(
function), domain_fun_(domain_function) {}
227 Domain_function_ domain_fun_;
239template <
class Function_,
class Domain_function_>
241 const Function_& function,
const Domain_function_& domain_function) {
252template <
class Function_>
An oracle that supports the intersection query on an implicit manifold.
Definition: Implicit_manifold_intersection_oracle.h:41
Eigen::VectorXd seed() const
The seed point of the implicit manifold.
Definition: Implicit_manifold_intersection_oracle.h:127
Implicit_manifold_intersection_oracle(const Function_ &function, const Domain_function_ &domain_function)
Constructs an intersection oracle for an implicit manifold potentially with boundary from given funct...
Definition: Implicit_manifold_intersection_oracle.h:210
Query_result< Simplex_handle > intersects(const Simplex_handle &simplex, const Triangulation &triangulation) const
Intersection query with the relative interior of the manifold.
Definition: Implicit_manifold_intersection_oracle.h:150
Implicit_manifold_intersection_oracle(const Function_ &function)
Constructs an intersection oracle for an implicit manifold without boundary from a given function.
Definition: Implicit_manifold_intersection_oracle.h:222
const Function_ & function() const
Returns the function that defines the interior of the manifold.
Definition: Implicit_manifold_intersection_oracle.h:200
std::size_t amb_d() const
Ambient dimension of the implicit manifold.
Definition: Implicit_manifold_intersection_oracle.h:121
bool lies_in_domain(const Eigen::VectorXd &p, const Triangulation &triangulation) const
Returns true if the input point lies inside the piecewise-linear domain induced by the given ambient ...
Definition: Implicit_manifold_intersection_oracle.h:194
std::size_t cod_d() const
Codimension of the implicit manifold.
Definition: Implicit_manifold_intersection_oracle.h:124
Query_result< Simplex_handle > intersects_boundary(const Simplex_handle &simplex, const Triangulation &triangulation) const
Intersection query with the boundary of the manifold.
Definition: Implicit_manifold_intersection_oracle.h:176
PL_approximation< Function_, Triangulation_ > make_pl_approximation(const Function_ &function, const Triangulation_ &triangulation)
Static constructor of the piecewise-linear approximation of a function induced by an ambient triangul...
Definition: PL_approximation.h:102
Implicit_manifold_intersection_oracle< Function_ > make_oracle(const Function_ &function)
Static constructor of an intersection oracle from a function without a domain.
Definition: Implicit_manifold_intersection_oracle.h:253
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
The result of a query by an oracle such as Implicit_manifold_intersection_oracle.
Definition: Query_result.h:26