summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/python/CMakeLists.txt3
-rw-r--r--src/python/example/alpha_complex_from_generated_points_on_sphere_example.py4
-rw-r--r--src/python/gudhi/datasets/generators/_points.cc109
-rw-r--r--src/python/gudhi/datasets/generators/points.cc68
-rw-r--r--src/python/gudhi/datasets/generators/points.py56
5 files changed, 169 insertions, 71 deletions
diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt
index 98f2b85f..8c46004a 100644
--- a/src/python/CMakeLists.txt
+++ b/src/python/CMakeLists.txt
@@ -152,7 +152,7 @@ if(PYTHONINTERP_FOUND)
set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/wasserstein', ")
set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'hera/bottleneck', ")
if (NOT CGAL_VERSION VERSION_LESS 4.11.0)
- set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/points', ")
+ set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'datasets/generators/_points', ")
set(GUDHI_PYBIND11_MODULES "${GUDHI_PYBIND11_MODULES}'bottleneck', ")
set(GUDHI_CYTHON_MODULES "${GUDHI_CYTHON_MODULES}'nerve_gic', ")
endif ()
@@ -266,6 +266,7 @@ if(PYTHONINTERP_FOUND)
file(COPY "gudhi/hera/__init__.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi/hera")
file(COPY "gudhi/datasets" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi" FILES_MATCHING PATTERN "*.py")
+
# Some files for pip package
file(COPY "introduction.rst" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
diff --git a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py
index 267e6436..3558077e 100644
--- a/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py
+++ b/src/python/example/alpha_complex_from_generated_points_on_sphere_example.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-from gudhi.datasets.generators import points
+from gudhi.datasets.generators import _points
from gudhi import AlphaComplex
@@ -22,7 +22,7 @@ print("#####################################################################")
print("AlphaComplex creation from generated points on sphere")
-gen_points = points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random")
+gen_points = _points.sphere(n_samples = 50, ambient_dim = 2, radius = 1, sample = "random")
# Create an alpha complex
alpha_complex = AlphaComplex(points = gen_points)
diff --git a/src/python/gudhi/datasets/generators/_points.cc b/src/python/gudhi/datasets/generators/_points.cc
new file mode 100644
index 00000000..55b21b2b
--- /dev/null
+++ b/src/python/gudhi/datasets/generators/_points.cc
@@ -0,0 +1,109 @@
+/* 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): Hind Montassif
+ *
+ * Copyright (C) 2021 Inria
+ *
+ * Modification(s):
+ * - YYYY/MM Author: Description of the modification
+ */
+
+#include <pybind11/pybind11.h>
+#include <pybind11/numpy.h>
+
+#include <gudhi/random_point_generators.h>
+#include <gudhi/Debug_utils.h>
+
+#include <CGAL/Epick_d.h>
+
+namespace py = pybind11;
+
+
+typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern;
+
+py::array_t<double> generate_points_on_sphere(size_t n_samples, int ambient_dim, double radius, std::string sample) {
+
+ if (sample != "random") {
+ throw pybind11::value_error("This sample type is not supported");
+ }
+
+ py::array_t<double> points({n_samples, (size_t)ambient_dim});
+
+ py::buffer_info buf = points.request();
+ double *ptr = static_cast<double *>(buf.ptr);
+
+ GUDHI_CHECK(n_samples == buf.shape[0], "Py array first dimension not matching n_samples on sphere");
+ GUDHI_CHECK(ambient_dim == buf.shape[1], "Py array second dimension not matching the ambient space dimension");
+
+
+ py::gil_scoped_release release;
+ auto points_generated = Gudhi::generate_points_on_sphere_d<Kern>(n_samples, ambient_dim, radius);
+
+ for (size_t i = 0; i < n_samples; i++)
+ for (int j = 0; j < ambient_dim; j++)
+ ptr[i*ambient_dim+j] = points_generated[i][j];
+
+ return points;
+}
+
+py::array_t<double> generate_points_on_torus(size_t n_samples, int dim, bool uniform) {
+
+ std::vector<typename Kern::Point_d> points_generated;
+
+ {
+ py::gil_scoped_release release;
+ points_generated = Gudhi::generate_points_on_torus_d<Kern>(n_samples, dim, uniform);
+ }
+
+ size_t npoints = points_generated.size();
+
+ GUDHI_CHECK(2*dim == points_generated[0].size(), "Py array second dimension not matching the double torus dimension");
+
+ py::array_t<double> points({npoints, (size_t)2*dim});
+
+ py::buffer_info buf = points.request();
+ double *ptr = static_cast<double *>(buf.ptr);
+
+ for (size_t i = 0; i < npoints; i++)
+ for (int j = 0; j < 2*dim; j++)
+ ptr[i*(2*dim)+j] = points_generated[i][j];
+
+ return points;
+}
+
+PYBIND11_MODULE(_points, m) {
+ m.attr("__license__") = "LGPL v3";
+
+ m.def("sphere", &generate_points_on_sphere,
+ py::arg("n_samples"), py::arg("ambient_dim"),
+ py::arg("radius") = 1., py::arg("sample") = "random",
+ R"pbdoc(
+ Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d
+
+ :param n_samples: The number of points to be generated.
+ :type n_samples: integer
+ :param ambient_dim: The ambient dimension d.
+ :type ambient_dim: integer
+ :param radius: The radius. Default value is `1.`.
+ :type radius: float
+ :param sample: The sample type. Default and only available value is `"random"`.
+ :type sample: string
+ :rtype: numpy array of float
+ :returns: the generated points on a sphere.
+ )pbdoc");
+
+ m.def("torus", &generate_points_on_torus,
+ py::arg("n_samples"), py::arg("dim"), py::arg("uniform") = false,
+ R"pbdoc(
+ Generate random i.i.d. points on a d-torus in R^2d
+
+ :param n_samples: The number of points to be generated.
+ :type n_samples: integer
+ :param dim: The dimension of the torus on which points would be generated in R^2*dim.
+ :type dim: integer
+ :param uniform: A flag to define if the points generation is uniform (i.e generated as a grid).
+ :type uniform: bool
+ :rtype: numpy array of float
+ :returns: the generated points on a torus.
+ )pbdoc");
+}
diff --git a/src/python/gudhi/datasets/generators/points.cc b/src/python/gudhi/datasets/generators/points.cc
deleted file mode 100644
index d658946b..00000000
--- a/src/python/gudhi/datasets/generators/points.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* 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): Hind Montassif
- *
- * Copyright (C) 2021 Inria
- *
- * Modification(s):
- * - YYYY/MM Author: Description of the modification
- */
-
-#include <pybind11/pybind11.h>
-#include <pybind11/numpy.h>
-
-#include <gudhi/random_point_generators.h>
-#include <gudhi/Debug_utils.h>
-
-#include <CGAL/Epick_d.h>
-
-namespace py = pybind11;
-
-
-typedef CGAL::Epick_d< CGAL::Dynamic_dimension_tag > Kern;
-
-py::array_t<double> generate_points_on_sphere(size_t n_samples, int ambient_dim, double radius, std::string sample) {
-
- if (sample != "random") {
- throw pybind11::value_error("This sample type is not supported");
- }
-
- py::array_t<double> points({n_samples, (size_t)ambient_dim});
-
- py::buffer_info buf = points.request();
- double *ptr = static_cast<double *>(buf.ptr);
-
- GUDHI_CHECK(n_samples == buf.shape[0], "Py array first dimension not matching n_samples on sphere");
- GUDHI_CHECK(ambient_dim == buf.shape[1], "Py array second dimension not matching the ambient space dimension");
-
-
- py::gil_scoped_release release;
- auto points_generated = Gudhi::generate_points_on_sphere_d<Kern>(n_samples, ambient_dim, radius);
-
- for (size_t i = 0; i < n_samples; i++)
- for (int j = 0; j < ambient_dim; j++)
- ptr[i*ambient_dim+j] = points_generated[i][j];
-
- return points;
-}
-
-PYBIND11_MODULE(points, m) {
- m.attr("__license__") = "LGPL v3";
- m.def("sphere", &generate_points_on_sphere,
- py::arg("n_samples"), py::arg("ambient_dim"),
- py::arg("radius") = 1., py::arg("sample") = "random",
- R"pbdoc(
- Generate random i.i.d. points uniformly on a (d-1)-sphere in R^d
-
- :param n_samples: The number of points to be generated.
- :type n_samples: integer
- :param ambient_dim: The ambient dimension d.
- :type ambient_dim: integer
- :param radius: The radius. Default value is `1.`.
- :type radius: float
- :param sample: The sample type. Default and only available value is `"random"`.
- :type sample: string
- :rtype: numpy array of float
- :returns: the generated points on a sphere.
- )pbdoc");
-}
diff --git a/src/python/gudhi/datasets/generators/points.py b/src/python/gudhi/datasets/generators/points.py
new file mode 100644
index 00000000..a8f5ad54
--- /dev/null
+++ b/src/python/gudhi/datasets/generators/points.py
@@ -0,0 +1,56 @@
+# 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): Hind Montassif
+#
+# Copyright (C) 2021 Inria
+#
+# Modification(s):
+# - YYYY/MM Author: Description of the modification
+
+import numpy as np
+import itertools
+
+def _generate_random_points_on_torus(n_samples, dim):
+
+ # Generate random angles of size n_samples*dim
+ alpha = 2*np.pi*np.random.rand(n_samples*dim)
+
+ # Based on angles, construct points of size n_samples*dim on a circle and reshape the result in a n_samples*2*dim array
+ array_points = np.column_stack([np.cos(alpha), np.sin(alpha)]).reshape(-1, 2*dim)
+
+ return array_points
+
+def _generate_grid_points_on_torus(n_samples, dim):
+
+ # Generate points on a dim-torus as a grid
+ n_samples_grid = int(n_samples**(1./dim))
+ alpha = np.linspace(0, 2*np.pi, n_samples_grid, endpoint=False)
+
+ array_points_inter = np.column_stack([np.cos(alpha), np.sin(alpha)])
+ array_points = np.array(list(itertools.product(array_points_inter, repeat=dim))).reshape(-1, 2*dim)
+
+ return array_points
+
+def torus(n_samples, dim, sample='random'):
+ '''
+ Generate points on a dim-torus in R^2dim either randomly or on a grid
+
+ :param n_samples: The number of points to be generated.
+ :param dim: The dimension of the torus on which points would be generated in R^2*dim.
+ :param sample: The sample type of the generated points. Can be 'random' or 'grid'.
+ :returns: numpy array containing the generated points on a torus.
+ The shape of returned numpy array is :
+ if sample is 'random' : (n_samples, 2*dim)
+ if sample is 'grid' : ((int(n_samples**(1./dim)))**dim, 2*dim)
+ '''
+ if sample == 'random':
+ # Generate points randomly
+ print("Sample is random")
+ return _generate_random_points_on_torus(n_samples, dim)
+ elif sample == 'grid':
+ # Generate points on a grid
+ print("Sample is grid")
+ return _generate_grid_points_on_torus(n_samples, dim)
+ else:
+ raise ValueError("Sample type '{}' is not supported".format(sample))
+ return