Completed
Push — master ( be126b...0fe470 )
by Andrei
01:30
created

pyclustering.core.kmedians()   A

Complexity

Conditions 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 11
rs 9.4285
1
'''
2
3
Wrapper for CCORE library (part of this project).
4
5
Copyright (C) 2015    Andrei Novikov ([email protected])
6
7
pyclustering is free software: you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation, either version 3 of the License, or
10
(at your option) any later version.
11
12
pyclustering is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20
'''
21
22
from ctypes import *;
0 ignored issues
show
Unused Code introduced by
string_at was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
set_last_error was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
DllGetClassObject was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
byref was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_int64 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_short was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_int32 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
Union was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
memset was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
ArgumentError was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
resize was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
Array was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
HRESULT was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_buffer was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
PYFUNCTYPE was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
RTLD_LOCAL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_ushort was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_byte was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_size_t was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_longlong was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_int16 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
DEFAULT_MODE was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
BigEndianStructure was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
PyDLL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
get_last_error was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
GetLastError was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
LittleEndianStructure was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_ubyte was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
addressof was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
create_string_buffer was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
CFUNCTYPE was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
get_errno was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
alignment was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
pydll was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
Structure was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
SetPointerType was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_voidp was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_ssize_t was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_uint16 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
py_object was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
OleDLL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
FormatError was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_int8 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
DllCanUnloadNow was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_uint64 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
CDLL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
windll was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
set_errno was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
kind was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
memmove was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_char_p was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
WinDLL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
WinError was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_wchar was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_ulonglong was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
sizeof was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_char was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
WINFUNCTYPE was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
LibraryLoader was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_wchar_p was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
oledll was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_uint8 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
ARRAY was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_uint32 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_void_p was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
RTLD_GLOBAL was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
create_unicode_buffer was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
wstring_at was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
c_longdouble was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
pythonapi was imported with wildcard, but is not used.
Loading history...
23
24
from pyclustering.core.definitions import *;
0 ignored issues
show
Unused Code introduced by
core was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
os was imported with wildcard, but is not used.
Loading history...
25
26
27
# API that is required for interaction with DLL.
28
def create_pointer_data(sample):
29
    "Allocates memory for representing input data for processing that is described by structure 'data_representation' and returns pointer this structure."
30
    
31
    "(in) sample    - dataset for processing."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
32
    
33
    "Returns pointer to the data for processing."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
34
    
35
    input_data = data_representation();
36
    input_data.number_objects = len(sample);
37
    input_data.dimension = len(sample[0]);
38
    
39
    pointer_objects = (POINTER(c_double) * input_data.number_objects)();
40
     
41
    for index in range(0, input_data.number_objects):
42
        point = (c_double * input_data.dimension)();
43
        for dimension in range(0, input_data.dimension):
44
            point[dimension] = sample[index][dimension];
45
            
46
        pointer_objects[index] = cast(point, POINTER(c_double));
47
       
48
    input_data.pointer_objects = cast(pointer_objects, POINTER(POINTER(c_double)));
49
    input_data = pointer(input_data);
50
    
51
    return input_data;
52
53
54
def extract_clusters(ccore_result):
55
    "Parse clustering result that is provided by the CCORE. Return Python list of clusters."
56
    
57
    "(in) ccore_result    - pointer to clustering result that has been returned by CCORE."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
58
    
59
    "Returns Python list of clusters."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
60
    
61
    pointer_clustering_result = cast(ccore_result, POINTER(clustering_result));    # clustering_result * clusters
62
    number_clusters = pointer_clustering_result[0].number_clusters;
63
    
64
    list_of_clusters = [];
65
    
66
    for index_cluster in range(0, number_clusters):
67
        clusters = cast(pointer_clustering_result[0].pointer_clusters, POINTER(cluster_representation));  # cluster_representation * cluster
68
        
69
        objects = cast(clusters[index_cluster].pointer_objects, POINTER(c_uint));   # cluster->objects (unsigned int *)
70
        
71
        list_of_clusters.append([]);
72
        pointer_container = list_of_clusters[index_cluster];
73
74
        for index_object in range(0, clusters[index_cluster].number_objects):
75
            pointer_container.append(objects[index_object]);
76
    
77
    return list_of_clusters;
78
79
80
def extract_dynamics(ccore_result):
81
    "Parse dynamic result that is provided by the CCORE. Return Python tuple that represent dynamics (times, dynamic)."
82
    
83
    "(in) ccore_result    - pointer to dynamic result that has been returned by CCORE."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
84
    
85
    "Returns Python tuple dynamic (times, dynamic)."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
86
    
87
    pointer_dynamic_result = cast(ccore_result, POINTER(dynamic_result));   # dynamic_result * pointer_dynamic_result
88
    size_dynamic = pointer_dynamic_result[0].size_dynamic;
89
    size_network = pointer_dynamic_result[0].size_network;
90
    
91
    pointer_time = cast(pointer_dynamic_result[0].times, POINTER(c_double));
92
    pointer_pointer_dynamic = cast(pointer_dynamic_result[0].dynamic, POINTER(POINTER(c_double)));
93
    
94
    times = [];
95
    dynamic = [];
96
    
97
    for index in range(0, size_dynamic):
98
        times.append(pointer_time[index]);
99
        dynamic.append([]);
100
        
101
        pointer_dynamic = cast(pointer_pointer_dynamic[index], POINTER(c_double));
102
        
103
        for object_dynamic in range(0, size_network):
104
            dynamic[index].append(pointer_dynamic[object_dynamic]);
105
        
106
    return (times, dynamic);
107
108
def extract_pyclustering_package(ccore_package_pointer):
109
    if (ccore_package_pointer == 0):
110
        return [];
111
    
112
    pointer_package = cast(ccore_package_pointer, POINTER(pyclustering_package));
113
    size = pointer_package[0].size;
114
    type_package = pointer_package[0].type;
115
    
116
    result = [];
117
    pointer_data = None;
118
    
119
    if (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_INT):
120
        pointer_data = cast(pointer_package[0].data, POINTER(c_int));
121
    
122
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_UNSIGNED_INT):
123
        pointer_data = cast(pointer_package[0].data, POINTER(c_uint));
124
    
125
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_FLOAT):
126
        pointer_data = cast(pointer_package[0].data, POINTER(c_float));
127
    
128
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_DOUBLE):
129
        pointer_data = cast(pointer_package[0].data, POINTER(c_double));
130
    
131
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_LONG):
132
        pointer_data = cast(pointer_package[0].data, POINTER(c_long));
133
    
134
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_UNSIGNED_LONG):
135
        pointer_data = cast(pointer_package[0].data, POINTER(c_ulong));
136
    
137
    elif (type_package == pyclustering_type_data.PYCLUSTERING_TYPE_LIST):
138
        # pointer_package[0].data == pyclustering_package **
139
        pointer_data = cast(pointer_package[0].data, POINTER(POINTER(pyclustering_package)));
140
        
141
        for index in range(0, size):
142
            pointer_package = cast(pointer_data[index], (POINTER(pyclustering_package)));
143
            result.append(extract_pyclustering_package(pointer_package));
144
145
    else:
146
        assert(0);
147
    
148
    if (type_package != pyclustering_type_data.PYCLUSTERING_TYPE_LIST):
149
        for index in range(0, size):
150
            result.append(pointer_data[index]);
151
    
152
    return result;
153
154
155
def destroy_object(pointer_object):
156
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
157
    ccore.destroy_object(pointer_object);
158
159
160
# Implemented algorithms.
161
def dbscan(sample, eps, min_neighbors, return_noise = False):
162
    "Clustering algorithm DBSCAN returns allocated clusters and noise that are consisted from input data. Calculation is performed via CCORE."
163
    
164
    "(in) data            - input data that is presented as list of points (objects), each point should be represented by list or tuple."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
165
    "(in) eps             - connectivity radius between points, points may be connected if distance between them less then the radius."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
166
    "(in) min_neighbors   - minimum number of shared neighbors that is requied for establish links between points."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
167
    "(in) return_noise    - if True than list of points that have been marked as noise will be returned."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
168
    
169
    "If return_noise is False: Returns list of allocated clusters, each cluster contains indexes of objects in list of data."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
170
    "If return_noise is True: Returns tuple of list of allicated clusters and list of points that are marked as noise."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
171
    
172
    pointer_data = create_pointer_data(sample);
173
    
174
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
175
    result = ccore.dbscan_algorithm(pointer_data, c_double(eps), c_uint(min_neighbors));
176
177
    list_of_clusters = extract_clusters(result);
178
    ccore.free_clustering_result(result);
179
    
180
    noise = list_of_clusters[len(list_of_clusters) - 1];
181
    list_of_clusters.remove(noise);
182
    
183
    if (return_noise is True):
184
        return (list_of_clusters, noise);
185
    else:
186
        return list_of_clusters;
187
188
def cure(sample, number_clusters, number_represent_points, compression):    
189
    pointer_data = create_pointer_data(sample);
190
    
191
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
192
    result = ccore.cure_algorithm(pointer_data, c_uint(number_clusters), c_uint(number_represent_points), c_double(compression));
193
    
194
    list_of_clusters = extract_clusters(result);
195
    
196
    ccore.free_clustering_result(result);
197
    return list_of_clusters;
198
199
def hierarchical(sample, number_clusters):
200
    "Clustering algorithm hierarchical returns allocated clusters and noise that are consisted from input data. Calculation is performed via CCORE."
201
    
202
    "(in) data               - input data that is presented as list of points (objects), each point should be represented by list or tuple."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
203
    "(in) number_clusters    - number of cluster that should be allocated."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
204
    
205
    "Returns list of allocated clusters, each cluster contains indexes of objects in list of data."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
206
    
207
    pointer_data = create_pointer_data(sample);
208
    
209
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
210
    result = ccore.hierarchical_algorithm(pointer_data, c_uint(number_clusters));
211
    
212
    list_of_clusters = extract_clusters(result);
213
    
214
    ccore.free_clustering_result(result);
215
    return list_of_clusters;
216
217
218
def kmeans(sample, centers, tolerance):
219
    "Clustering algorithm K-Means returns allocated clusters. Calculation is performed via CCORE."
220
    
221
    "(in) data        - input data that is presented as list of points (objects), each point should be represented by list or tuple."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
222
    "(in) centers     - initial coordinates of centers of clusters that are represented by list: [center1, center2, ...]."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
223
    "(in) tolerance   - stop condition: if maximum value of change of centers of clusters is less than tolerance than algorithm will stop processing."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
224
    
225
    "Returns list of allocated clusters, each cluster contains indexes of objects in list of data."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
226
    
227
    pointer_data = create_pointer_data(sample);
228
    pointer_centers = create_pointer_data(centers);
229
    
230
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
231
    result = ccore.kmeans_algorithm(pointer_data, pointer_centers, c_double(tolerance));
232
    
233
    list_of_clusters = extract_clusters(result);
234
    
235
    ccore.free_clustering_result(result);
236
    return list_of_clusters;
237
238
239
def kmedians(sample, centers, tolerance):
240
    pointer_data = create_pointer_data(sample);
241
    pointer_centers = create_pointer_data(centers);
242
    
243
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
244
    result = ccore.kmedians_algorithm(pointer_data, pointer_centers, c_double(tolerance));
245
    
246
    list_of_clusters = extract_clusters(result);
247
    ccore.free_clustering_result(result);
248
    
249
    return list_of_clusters;
250
251
252
def rock(sample, eps, number_clusters, threshold):
253
    "Clustering algorithm ROCK returns allocated clusters and noise that are consisted from input data. Calculation is performed via CCORE."
254
    
255
    "(in) data                - input data - list of points where each point is represented by list of coordinates."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
256
    "(in) eps                 - connectivity radius (similarity threshold), points are neighbors if distance between them is less than connectivity radius."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
257
    "(in) number_clusters     - defines number of clusters that should be allocated from the input data set."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
258
    "(in) threshold           - value that defines degree of normalization that influences on choice of clusters for merging during processing."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
259
    
260
    "Returns list of allocated clusters, each cluster contains indexes of objects in list of data."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
261
    
262
    pointer_data = create_pointer_data(sample);
263
    
264
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
265
    result = ccore.rock_algorithm(pointer_data, c_double(eps), c_uint(number_clusters), c_double(threshold));
266
    
267
    list_of_clusters = extract_pyclustering_package(result);
268
    ccore.free_pyclustering_package(result);
269
    
270
    return list_of_clusters;    
271
272
273
def xmeans(sample, centers, kmax, tolerance):
274
    "Clustering algorithm X-Means returns allocated clusters. Calculation is performed via CCORE."
275
    
276
    "(in) data        - input data that is presented as list of points (objects), each point should be represented by list or tuple."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
277
    "(in) centers     - initial coordinates of centers of clusters that are represented by list: [center1, center2, ...]."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
278
    "(in) kmax        - maximum number of clusters that can be allocated."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
279
    
280
    "Returns list of allocated clusters, each cluster contains indexes of objects in list of data."
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
281
    
282
    pointer_data = create_pointer_data(sample);
283
    pointer_centers = create_pointer_data(centers);
284
    
285
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
286
    result = ccore.xmeans_algorithm(pointer_data, pointer_centers, c_uint(kmax), c_double(tolerance));
287
    
288
    list_of_clusters = extract_clusters(result);
289
    
290
    ccore.free_clustering_result(result);
291
    return list_of_clusters;
292
293
294
"CCORE Interface for HSYNCNET oscillatory network"
0 ignored issues
show
Unused Code introduced by
This string statement has no effect and could be removed.
Loading history...
295
296
def hsyncnet_create_network(sample, number_clusters, initial_phases):
297
    pointer_data = create_pointer_data(sample);
298
    
299
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
300
    pointer_network = ccore.hsyncnet_create_network(pointer_data, c_uint(number_clusters), c_uint(initial_phases));
301
    
302
    return pointer_network;
303
304
305
def hsyncnet_destroy_network(pointer_network):
306
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
307
    ccore.hsyncnet_destroy_network(pointer_network);
308
309
310
def hsyncnet_process(network_pointer, order, solution, collect_dynamic):
311
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
312
    return ccore.hsyncnet_process(network_pointer, c_double(order), c_uint(solution), c_bool(collect_dynamic));  
313
314
315
def hsyncnet_analyser_destroy(pointer_analyser):
316
    ccore = cdll.LoadLibrary(PATH_DLL_CCORE_64);
317
    ccore.syncnet_analyser_destroy(pointer_analyser);     
318
319