Completed
Push — 0.8.dev ( e2d899...cfe6de )
by Andrei
02:27
created

calculate_metric()   B

Complexity

Conditions 6

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
dl 0
loc 30
rs 7.5384
c 0
b 0
f 0
1
"""!
2
3
@brief Module provides various metrics - abstraction of the notion of distance in a metric space.
4
5
@authors Andrei Novikov ([email protected])
6
@date 2014-2018
7
@copyright GNU Public License
8
9
@cond GNU_PUBLIC_LICENSE
10
    PyClustering is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
15
    PyClustering is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
20
    You should have received a copy of the GNU General Public License
21
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
@endcond
23
24
"""
25
26
27
from enum import IntEnum;
28
29
import collections;
30
31
32
class type_metric(IntEnum):
33
    """!
34
    @brief Enumeration of supported metrics in the module for distance calculation between two points.
35
36
    """
37
38
    ## Euclidean distance, for more information see function 'euclidean_distance'.
39
    EUCLIDEAN = 0;
40
41
    ## Square Euclidean distance, for more information see function 'euclidean_distance_square'.
42
    EUCLIDEAN_SQUARE = 1;
43
44
    ## Manhattan distance, for more information see function 'manhattan_distance'.
45
    MANHATTAN = 2;
46
47
    ## Chebyshev distance, for more information see function 'chebyshev_distance'.
48
    CHEBYSHEV = 3;
49
50
    ## User defined function for distance calculation between two points.
51
    USER_DEFINED = 1000;
52
53
54
def calculate_metric(point1, point2, metric, func=None):
55
    """!
56
    @brief Calculates metric between two points in line with specified metric function.
57
58
    @param[in] point1 (numeric|list): The first point.
59
    @param[in] point2 (numeric|list): The second point.
60
    @param[in] metric (type_metric): Metric that is used for distance calculation between two points.
61
    @param[in] func (callable): Used only if metric is 'type_metric.USER_DEFINED' and represents callable object
62
                with two arguments: 'point1' and 'point2', notation is: 'func(point1, point2)'.
63
64
    @return (double) Distance between two points.
65
66
    """
67
    if metric == type_metric.EUCLIDEAN:
68
        return euclidean_distance(point1, point2);
69
70
    elif metric == type_metric.EUCLIDEAN_SQUARE:
71
        return euclidean_distance_square(point1, point2);
72
73
    elif metric == type_metric.MANHATTAN:
74
        return manhattan_distance(point1, point2);
75
76
    elif metric == type_metric.CHEBYSHEV:
77
        return chebyshev_distance(point1, point2);
78
79
    elif metric == type_metric.USER_DEFINED:
80
        return func(point1, point2);
81
82
    else:
83
        raise ValueError("Unknown type of metric: '%d'", metric);
84
85
86
def euclidean_distance(point1, point2):
87
    """!
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \s was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
88
    @brief Calculate Euclidean distance between vectors.
89
    @details The Euclidean between vectors (points) a and b is calculated by following formula:
90
91
    \f[
92
    dist(a, b) = \sqrt{ \sum_{i=0}^{N}(a_{i} - b_{i})^{2}) };
93
    \f]
94
95
    Where N is a length of each vector.
96
97
    @param[in] point1 (numeric|list): The first vector.
98
    @param[in] point2 (numeric|list): The second vector.
99
100
    @return (double) Euclidean distance between two vectors.
101
102
    """
103
104
    distance = euclidean_distance_square(point1, point2);
105
    return distance ** 0.5;
106
107
108
def euclidean_distance_square(point1, point2):
109
    """!
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \s was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
110
    @brief Calculate square Euclidean distance between vectors.
111
112
    \f[
113
    dist(a, b) = \sum_{i=0}^{N}(a_{i} - b_{i})^{2});
114
    \f]
115
116
    @param[in] point1 (numeric|list): The first vector.
117
    @param[in] point2 (numeric|list): The second vector.
118
119
    @return (double) Square Euclidean distance between two vectors.
120
121
    """
122
123
    if isinstance(point1, collections.Iterable):
124
        distance = 0.0;
125
        for i in range(len(point1)):
126
            distance += (point1[i] - point2[i]) ** 2.0;
127
128
        return distance;
129
130
    return (point1 - point2) ** 2.0;
131
132
133
def manhattan_distance(point1, point2):
134
    """!
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \s was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
Bug introduced by
A suspicious escape sequence \l was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
135
    @brief Calculate Manhattan distance between vector a and b.
136
137
    \f[
138
    dist(a, b) = \sum_{i=0}^{N}\left | a_{i} - b_{i} \right |;
139
    \f]
140
141
    @param[in] point1 (numeric|list): The first vector.
142
    @param[in] point2 (numeric|list): The second vector.
143
144
    @return (double) Manhattan distance between two vectors.
145
146
    """
147
148
    if isinstance(point1, collections.Iterable):
149
        distance = 0.0;
150
        dimension = len(point1);
151
152
        for i in range(dimension):
153
            distance += abs(point1[i] - point2[i]);
154
155
        return distance;
156
157
    return abs(point1 - point2);
158
159
160
def chebyshev_distance(point1, point2):
161
    """!
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \m was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
Bug introduced by
A suspicious escape sequence \l was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
162
    @brief Calculate Chebyshev distance between vector a and b.
163
164
    \f[
165
    dist(a, b) = \max_{}i\left (\left | a_{i} - b_{i} \right |\right );
166
    \f]
167
168
    @param[in] point1 (numeric|list): The first vector.
169
    @param[in] point2 (numeric|list): The second vector.
170
171
    @return (double) Chebyshev distance between two vectors.
172
173
    """
174
    if isinstance(point1, collections.Iterable):
175
        distance = 0.0;
176
        dimension = len(point1);
177
178
        for i in range(dimension):
179
            distance = max(distance, abs(point1[i] - point2[i]));
180
181
        return distance;
182
183
    return abs(point1 - point2);