summaryrefslogtreecommitdiff
path: root/src/python/gudhi/subsampling.pyx
blob: b11d07e542d8f06cac1883aa67157b4004b02110 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# 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) 2016 Inria
#
# Modification(s):
#   - YYYY/MM Author: Description of the modification

from cython cimport numeric
from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp cimport bool
import os

__author__ = "Vincent Rouvreau"
__copyright__ = "Copyright (C) 2016 Inria"
__license__ = "GPL v3"

cdef extern from "Subsampling_interface.h" namespace "Gudhi::subsampling":
    vector[vector[double]] subsampling_n_farthest_points(vector[vector[double]] points, unsigned nb_points)
    vector[vector[double]] subsampling_n_farthest_points(vector[vector[double]] points, unsigned nb_points, unsigned starting_point)
    vector[vector[double]] subsampling_n_farthest_points_from_file(string off_file, unsigned nb_points)
    vector[vector[double]] subsampling_n_farthest_points_from_file(string off_file, unsigned nb_points, unsigned starting_point)
    vector[vector[double]] subsampling_n_random_points(vector[vector[double]] points, unsigned nb_points)
    vector[vector[double]] subsampling_n_random_points_from_file(string off_file, unsigned nb_points)
    vector[vector[double]] subsampling_sparsify_points(vector[vector[double]] points, double min_squared_dist)
    vector[vector[double]] subsampling_sparsify_points_from_file(string off_file, double min_squared_dist)

def choose_n_farthest_points(points=None, off_file='', nb_points=0, starting_point = ''):
    """Subsample by a greedy strategy of iteratively adding the farthest point
    from the current chosen point set to the subsampling.
    The iteration starts with the landmark `starting point`.

    :param points: The input point set.
    :type points: Iterable[Iterable[float]]

    Or

    :param off_file: An OFF file style name.
    :type off_file: string

    And in both cases

    :param nb_points: Number of points of the subsample (the subsample may be \
    smaller if there are fewer than nb_points distinct input points)
    :type nb_points: int
    :param starting_point: The iteration starts with the landmark `starting \
    point`, which is the index of the point to start with. If not set, this \
    index is chosen randomly.
    :type starting_point: int
    :returns:  The subsample point set.
    :rtype: List[List[float]]
    """
    if off_file:
        if os.path.isfile(off_file):
            if starting_point == '':
                return subsampling_n_farthest_points_from_file(off_file.encode('utf-8'),
                                                               nb_points)
            else:
                return subsampling_n_farthest_points_from_file(off_file.encode('utf-8'),
                                                               nb_points,
                                                               starting_point)
        else:
            print("file " + off_file + " not found.")
    else:
        if points is None:
            # Empty points
            points=[]
        if starting_point == '':
            return subsampling_n_farthest_points(points, nb_points)
        else:
            return subsampling_n_farthest_points(points, nb_points,
                                                 starting_point)

def pick_n_random_points(points=None, off_file='', nb_points=0):
    """Subsample a point set by picking random vertices.

    :param points: The input point set.
    :type points: Iterable[Iterable[float]]

    Or

    :param off_file: An OFF file style name.
    :type off_file: string

    And in both cases

    :param nb_points: Number of points of the subsample.
    :type nb_points: int
    :returns:  The subsample point set.
    :rtype: List[List[float]]
    """
    if off_file:
        if os.path.isfile(off_file):
            return subsampling_n_random_points_from_file(off_file.encode('utf-8'),
                nb_points)
        else:
            print("file " + off_file + " not found.")
    else:
        if points is None:
            # Empty points
            points=[]
        return subsampling_n_random_points(points, nb_points)

def sparsify_point_set(points=None, off_file='', min_squared_dist=0.0):
    """Outputs a subset of the input points so that the squared distance
    between any two points is greater than or equal to min_squared_dist.

    :param points: The input point set.
    :type points: Iterable[Iterable[float]]

    Or

    :param off_file: An OFF file style name.
    :type off_file: string

    And in both cases

    :param min_squared_dist: Minimum squared distance separating the output \
    points.
    :type min_squared_dist: float
    :returns:  The subsample point set.
    :rtype: List[List[float]]
    """
    if off_file:
        if os.path.isfile(off_file):
            return subsampling_sparsify_points_from_file(off_file.encode('utf-8'),
                                                         min_squared_dist)
        else:
            print("file " + off_file + " not found.")
    else:
        if points is None:
            # Empty points
            points=[]
        return subsampling_sparsify_points(points, min_squared_dist)