pyclustering  0.10.1
pyclustring is a Python, C++ data mining library.
__init__.py
1 """!
2 
3 @brief Utils that are used by modules of pyclustering.
4 
5 @authors Andrei Novikov (pyclustering@yandex.ru)
6 @date 2014-2020
7 @copyright BSD-3-Clause
8 
9 """
10 
11 import time
12 import numpy
13 
14 
15 from numpy import array
16 from PIL import Image
17 
18 import matplotlib.pyplot as plt
19 from mpl_toolkits.mplot3d import Axes3D
20 
21 from sys import platform as _platform
22 
23 from pyclustering.utils.metric import distance_metric, type_metric
24 
25 
26 
27 pi = 3.1415926535
28 
29 
30 def read_sample(filename):
31  """!
32  @brief Returns data sample from simple text file.
33  @details This function should be used for text file with following format:
34  @code
35  point_1_coord_1 point_1_coord_2 ... point_1_coord_n
36  point_2_coord_1 point_2_coord_2 ... point_2_coord_n
37  ... ...
38  @endcode
39 
40  @param[in] filename (string): Path to file with data.
41 
42  @return (list) Points where each point represented by list of coordinates.
43 
44  """
45 
46  file = open(filename, 'r')
47 
48  sample = [[float(val) for val in line.split()] for line in file if len(line.strip()) > 0]
49 
50  file.close()
51  return sample
52 
53 
54 def calculate_distance_matrix(sample, metric=distance_metric(type_metric.EUCLIDEAN)):
55  """!
56  @brief Calculates distance matrix for data sample (sequence of points) using specified metric (by default Euclidean distance).
57 
58  @param[in] sample (array_like): Data points that are used for distance calculation.
59  @param[in] metric (distance_metric): Metric that is used for distance calculation between two points.
60 
61  @return (list) Matrix distance between data points.
62 
63  """
64 
65  amount_rows = len(sample)
66  return [[metric(sample[i], sample[j]) for j in range(amount_rows)] for i in range(amount_rows)]
67 
68 
69 def read_image(filename):
70  """!
71  @brief Returns image as N-dimension (depends on the input image) matrix, where one element of list describes pixel.
72 
73  @param[in] filename (string): Path to image.
74 
75  @return (list) Pixels where each pixel described by list of RGB-values.
76 
77  """
78 
79  with Image.open(filename) as image_source:
80  data = [list(pixel) for pixel in image_source.getdata()]
81  return data
82 
83 
84 def rgb2gray(image_rgb_array):
85  """!
86  @brief Returns image as 1-dimension (gray colored) matrix, where one element of list describes pixel.
87  @details Luma coding is used for transformation and that is calculated directly from gamma-compressed primary intensities as a weighted sum:
88 
89  \f[Y = 0.2989R + 0.587G + 0.114B\f]
90 
91  @param[in] image_rgb_array (list): Image represented by RGB list.
92 
93  @return (list) Image as gray colored matrix, where one element of list describes pixel.
94 
95  @code
96  colored_image = read_image(file_name);
97  gray_image = rgb2gray(colored_image);
98  @endcode
99 
100  @see read_image()
101 
102  """
103 
104  image_gray_array = [0.0] * len(image_rgb_array)
105  for index in range(0, len(image_rgb_array), 1):
106  image_gray_array[index] = float(image_rgb_array[index][0]) * 0.2989 \
107  + float(image_rgb_array[index][1]) * 0.5870 \
108  + float(image_rgb_array[index][2]) * 0.1140
109 
110  return image_gray_array
111 
112 
113 def stretch_pattern(image_source):
114  """!
115  @brief Returns stretched content as 1-dimension (gray colored) matrix with size of input image.
116 
117  @param[in] image_source (Image): PIL Image instance.
118 
119  @return (list, Image) Stretched image as gray colored matrix and source image.
120 
121  """
122  wsize, hsize = image_source.size
123 
124  # Crop digit exactly
125  (ws, hs, we, he) = gray_pattern_borders(image_source)
126  image_source = image_source.crop((ws, hs, we, he))
127 
128  # Stretch it to initial sizes
129  image_source = image_source.resize((wsize, hsize), Image.ANTIALIAS)
130 
131  # Transform image to simple array
132  data = [pixel for pixel in image_source.getdata()]
133  image_pattern = rgb2gray(data)
134 
135  return image_pattern, image_source
136 
137 
139  """!
140  @brief Returns coordinates of gray image content on the input image.
141 
142  @param[in] image (Image): PIL Image instance that is processed.
143 
144  @return (tuple) Returns coordinates of gray image content as (width_start, height_start, width_end, height_end).
145 
146  """
147 
148  width, height = image.size
149 
150  width_start = width
151  width_end = 0
152  height_start = height
153  height_end = 0
154 
155  row, col = 0, 0
156  for pixel in image.getdata():
157  value = float(pixel[0]) * 0.2989 + float(pixel[1]) * 0.5870 + float(pixel[2]) * 0.1140
158 
159  if value < 128:
160  if width_end < col:
161  width_end = col
162 
163  if height_end < row:
164  height_end = row
165 
166  if width_start > col:
167  width_start = col
168 
169  if height_start > row:
170  height_start = row
171 
172  col += 1
173  if col >= width:
174  col = 0
175  row += 1
176 
177  return width_start, height_start, width_end + 1, height_end + 1
178 
179 
180 def average_neighbor_distance(points, num_neigh):
181  """!
182  @brief Returns average distance for establish links between specified number of nearest neighbors.
183 
184  @param[in] points (list): Input data, list of points where each point represented by list.
185  @param[in] num_neigh (uint): Number of neighbors that should be used for distance calculation.
186 
187  @return (double) Average distance for establish links between 'num_neigh' in data set 'points'.
188 
189  """
190 
191  if num_neigh > len(points) - 1:
192  raise NameError('Impossible to calculate average distance to neighbors '
193  'when number of object is less than number of neighbors.')
194 
195  dist_matrix = [[0.0 for i in range(len(points))] for _ in range(len(points))]
196  for i in range(0, len(points), 1):
197  for j in range(i + 1, len(points), 1):
198  distance = euclidean_distance(points[i], points[j])
199  dist_matrix[i][j] = distance
200  dist_matrix[j][i] = distance
201 
202  dist_matrix[i] = sorted(dist_matrix[i])
203 
204  total_distance = 0
205  for i in range(0, len(points), 1):
206  # start from 0 - first element is distance to itself.
207  for j in range(0, num_neigh, 1):
208  total_distance += dist_matrix[i][j + 1]
209 
210  return total_distance / (num_neigh * len(points))
211 
212 
213 def medoid(data, indexes=None, **kwargs):
214  """!
215  @brief Calculate medoid for input points.
216 
217  @param[in] data (list): Set of points for that median should be calculated.
218  @param[in] indexes (list): Indexes of input set of points that will be taken into account during median calculation.
219  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'metric', 'data_type').
220 
221  <b>Keyword Args:</b><br>
222  - metric (distance_metric): Metric that is used for distance calculation between two points.
223  - data_type (string): Data type of input sample 'data' (available values: 'points', 'distance_matrix').
224 
225  @return (uint) index of point in input set that corresponds to median.
226 
227  """
228 
229  index_median = None
230  distance = float('Inf')
231 
232  metric = kwargs.get('metric', type_metric.EUCLIDEAN_SQUARE)
233  data_type = kwargs.get('data_type', 'points')
234 
235  if data_type == 'points':
236  calculator = lambda index1, index2: metric(data[index1], data[index2])
237  elif data_type == 'distance_matrix':
238  if isinstance(data, numpy.matrix):
239  calculator = lambda index1, index2: data.item(index1, index2)
240 
241  else:
242  calculator = lambda index1, index2: data[index1][index2]
243  else:
244  raise TypeError("Unknown type of data is specified '%s'." % data_type)
245 
246  if indexes is None:
247  range_points = range(len(data))
248  else:
249  range_points = indexes
250 
251  for index_candidate in range_points:
252  distance_candidate = 0.0
253  for index in range_points:
254  distance_candidate += calculator(index_candidate, index)
255 
256  if distance_candidate < distance:
257  distance = distance_candidate
258  index_median = index_candidate
259 
260  return index_median
261 
262 
264  """!
265  @brief Calculate Euclidean distance between vector a and b.
266  @details The Euclidean between vectors (points) a and b is calculated by following formula:
267 
268  \f[
269  dist(a, b) = \sqrt{ \sum_{i=0}^{N}(b_{i} - a_{i})^{2}) };
270  \f]
271 
272  Where N is a length of each vector.
273 
274  @param[in] a (list): The first vector.
275  @param[in] b (list): The second vector.
276 
277  @return (double) Euclidian distance between two vectors.
278 
279  @note This function for calculation is faster then standard function in ~100 times!
280 
281  """
282 
283  distance = euclidean_distance_square(a, b);
284  return distance**(0.5);
285 
286 
288  """!
289  @brief Calculate square Euclidian distance between vector a and b.
290 
291  @param[in] a (list): The first vector.
292  @param[in] b (list): The second vector.
293 
294  @return (double) Square Euclidian distance between two vectors.
295 
296  """
297 
298  if ( ((type(a) == float) and (type(b) == float)) or ((type(a) == int) and (type(b) == int)) ):
299  return (a - b)**2.0;
300 
301  distance = 0.0;
302  for i in range(0, len(a)):
303  distance += (a[i] - b[i])**2.0;
304 
305  return distance;
306 
307 
309  """!
310  @brief Calculate Manhattan distance between vector a and b.
311 
312  @param[in] a (list): The first cluster.
313  @param[in] b (list): The second cluster.
314 
315  @return (double) Manhattan distance between two vectors.
316 
317  """
318 
319  if ( ((type(a) == float) and (type(b) == float)) or ((type(a) == int) and (type(b) == int)) ):
320  return abs(a - b);
321 
322  distance = 0.0;
323  dimension = len(a);
324 
325  for i in range(0, dimension):
326  distance += abs(a[i] - b[i]);
327 
328  return distance;
329 
330 
331 def average_inter_cluster_distance(cluster1, cluster2, data = None):
332  """!
333  @brief Calculates average inter-cluster distance between two clusters.
334  @details Clusters can be represented by list of coordinates (in this case data shouldn't be specified),
335  or by list of indexes of points from the data (represented by list of points), in this case
336  data should be specified.
337 
338  @param[in] cluster1 (list): The first cluster where each element can represent index from the data or object itself.
339  @param[in] cluster2 (list): The second cluster where each element can represent index from the data or object itself.
340  @param[in] data (list): If specified than elements of clusters will be used as indexes,
341  otherwise elements of cluster will be considered as points.
342 
343  @return (double) Average inter-cluster distance between two clusters.
344 
345  """
346 
347  distance = 0.0;
348 
349  if (data is None):
350  for i in range(len(cluster1)):
351  for j in range(len(cluster2)):
352  distance += euclidean_distance_square(cluster1[i], cluster2[j]);
353  else:
354  for i in range(len(cluster1)):
355  for j in range(len(cluster2)):
356  distance += euclidean_distance_square(data[ cluster1[i]], data[ cluster2[j]]);
357 
358  distance /= float(len(cluster1) * len(cluster2));
359  return distance ** 0.5;
360 
361 
362 def average_intra_cluster_distance(cluster1, cluster2, data=None):
363  """!
364  @brief Calculates average intra-cluster distance between two clusters.
365  @details Clusters can be represented by list of coordinates (in this case data shouldn't be specified),
366  or by list of indexes of points from the data (represented by list of points), in this case
367  data should be specified.
368 
369  @param[in] cluster1 (list): The first cluster.
370  @param[in] cluster2 (list): The second cluster.
371  @param[in] data (list): If specified than elements of clusters will be used as indexes,
372  otherwise elements of cluster will be considered as points.
373 
374  @return (double) Average intra-cluster distance between two clusters.
375 
376  """
377 
378  distance = 0.0
379 
380  for i in range(len(cluster1) + len(cluster2)):
381  for j in range(len(cluster1) + len(cluster2)):
382  if data is None:
383  # the first point
384  if i < len(cluster1):
385  first_point = cluster1[i]
386  else:
387  first_point = cluster2[i - len(cluster1)]
388 
389  # the second point
390  if j < len(cluster1):
391  second_point = cluster1[j]
392  else:
393  second_point = cluster2[j - len(cluster1)]
394 
395  else:
396  # the first point
397  if i < len(cluster1):
398  first_point = data[cluster1[i]]
399  else:
400  first_point = data[cluster2[i - len(cluster1)]]
401 
402  if j < len(cluster1):
403  second_point = data[cluster1[j]]
404  else:
405  second_point = data[cluster2[j - len(cluster1)]]
406 
407  distance += euclidean_distance_square(first_point, second_point)
408 
409  distance /= float((len(cluster1) + len(cluster2)) * (len(cluster1) + len(cluster2) - 1.0))
410  return distance ** 0.5
411 
412 
413 def variance_increase_distance(cluster1, cluster2, data = None):
414  """!
415  @brief Calculates variance increase distance between two clusters.
416  @details Clusters can be represented by list of coordinates (in this case data shouldn't be specified),
417  or by list of indexes of points from the data (represented by list of points), in this case
418  data should be specified.
419 
420  @param[in] cluster1 (list): The first cluster.
421  @param[in] cluster2 (list): The second cluster.
422  @param[in] data (list): If specified than elements of clusters will be used as indexes,
423  otherwise elements of cluster will be considered as points.
424 
425  @return (double) Average variance increase distance between two clusters.
426 
427  """
428 
429  # calculate local sum
430  if data is None:
431  member_cluster1 = [0.0] * len(cluster1[0])
432  member_cluster2 = [0.0] * len(cluster2[0])
433 
434  else:
435  member_cluster1 = [0.0] * len(data[0])
436  member_cluster2 = [0.0] * len(data[0])
437 
438  for i in range(len(cluster1)):
439  if data is None:
440  member_cluster1 = list_math_addition(member_cluster1, cluster1[i])
441  else:
442  member_cluster1 = list_math_addition(member_cluster1, data[ cluster1[i] ])
443 
444  for j in range(len(cluster2)):
445  if data is None:
446  member_cluster2 = list_math_addition(member_cluster2, cluster2[j])
447  else:
448  member_cluster2 = list_math_addition(member_cluster2, data[ cluster2[j] ])
449 
450  member_cluster_general = list_math_addition(member_cluster1, member_cluster2)
451  member_cluster_general = list_math_division_number(member_cluster_general, len(cluster1) + len(cluster2))
452 
453  member_cluster1 = list_math_division_number(member_cluster1, len(cluster1))
454  member_cluster2 = list_math_division_number(member_cluster2, len(cluster2))
455 
456  # calculate global sum
457  distance_general = 0.0
458  distance_cluster1 = 0.0
459  distance_cluster2 = 0.0
460 
461  for i in range(len(cluster1)):
462  if data is None:
463  distance_cluster1 += euclidean_distance_square(cluster1[i], member_cluster1)
464  distance_general += euclidean_distance_square(cluster1[i], member_cluster_general)
465 
466  else:
467  distance_cluster1 += euclidean_distance_square(data[ cluster1[i]], member_cluster1)
468  distance_general += euclidean_distance_square(data[ cluster1[i]], member_cluster_general)
469 
470  for j in range(len(cluster2)):
471  if data is None:
472  distance_cluster2 += euclidean_distance_square(cluster2[j], member_cluster2)
473  distance_general += euclidean_distance_square(cluster2[j], member_cluster_general)
474 
475  else:
476  distance_cluster2 += euclidean_distance_square(data[ cluster2[j]], member_cluster2)
477  distance_general += euclidean_distance_square(data[ cluster2[j]], member_cluster_general)
478 
479  return distance_general - distance_cluster1 - distance_cluster2
480 
481 
482 def calculate_ellipse_description(covariance, scale = 2.0):
483  """!
484  @brief Calculates description of ellipse using covariance matrix.
485 
486  @param[in] covariance (numpy.array): Covariance matrix for which ellipse area should be calculated.
487  @param[in] scale (float): Scale of the ellipse.
488 
489  @return (float, float, float) Return ellipse description: angle, width, height.
490 
491  """
492 
493  eigh_values, eigh_vectors = numpy.linalg.eigh(covariance)
494  order = eigh_values.argsort()[::-1]
495 
496  values, vectors = eigh_values[order], eigh_vectors[order]
497  angle = numpy.degrees(numpy.arctan2(*vectors[:,0][::-1]))
498 
499  if 0.0 in values:
500  return 0, 0, 0
501 
502  width, height = 2.0 * scale * numpy.sqrt(values)
503  return angle, width, height
504 
505 
506 def data_corners(data, data_filter = None):
507  """!
508  @brief Finds maximum and minimum corner in each dimension of the specified data.
509 
510  @param[in] data (list): List of points that should be analysed.
511  @param[in] data_filter (list): List of indexes of the data that should be analysed,
512  if it is 'None' then whole 'data' is analysed to obtain corners.
513 
514  @return (list) Tuple of two points that corresponds to minimum and maximum corner (min_corner, max_corner).
515 
516  """
517 
518  dimensions = len(data[0])
519 
520  bypass = data_filter
521  if bypass is None:
522  bypass = range(len(data))
523 
524  maximum_corner = list(data[bypass[0]][:])
525  minimum_corner = list(data[bypass[0]][:])
526 
527  for index_point in bypass:
528  for index_dimension in range(dimensions):
529  if data[index_point][index_dimension] > maximum_corner[index_dimension]:
530  maximum_corner[index_dimension] = data[index_point][index_dimension]
531 
532  if data[index_point][index_dimension] < minimum_corner[index_dimension]:
533  minimum_corner[index_dimension] = data[index_point][index_dimension]
534 
535  return minimum_corner, maximum_corner
536 
537 
538 def norm_vector(vector):
539  """!
540  @brief Calculates norm of an input vector that is known as a vector length.
541 
542  @param[in] vector (list): The input vector whose length is calculated.
543 
544  @return (double) vector norm known as vector length.
545 
546  """
547 
548  length = 0.0
549  for component in vector:
550  length += component * component
551 
552  length = length ** 0.5
553 
554  return length
555 
556 
557 def heaviside(value):
558  """!
559  @brief Calculates Heaviside function that represents step function.
560  @details If input value is greater than 0 then returns 1, otherwise returns 0.
561 
562  @param[in] value (double): Argument of Heaviside function.
563 
564  @return (double) Value of Heaviside function.
565 
566  """
567  if (value > 0.0):
568  return 1.0;
569 
570  return 0.0;
571 
572 
573 def timedcall(executable_function, *args, **kwargs):
574  """!
575  @brief Executes specified method or function with measuring of execution time.
576 
577  @param[in] executable_function (pointer): Pointer to a function or method that should be called.
578  @param[in] *args: Arguments of the called function or method.
579  @param[in] **kwargs: Arbitrary keyword arguments of the called function or method.
580 
581  @return (tuple) Execution time and result of execution of function or method (execution_time, result_execution).
582 
583  """
584 
585  time_start = time.perf_counter()
586  result = executable_function(*args, **kwargs)
587  time_end = time.perf_counter()
588 
589  return time_end - time_start, result
590 
591 
592 def extract_number_oscillations(osc_dyn, index = 0, amplitude_threshold = 1.0):
593  """!
594  @brief Extracts number of oscillations of specified oscillator.
595 
596  @param[in] osc_dyn (list): Dynamic of oscillators.
597  @param[in] index (uint): Index of oscillator in dynamic.
598  @param[in] amplitude_threshold (double): Amplitude threshold when oscillation is taken into account, for example,
599  when oscillator amplitude is greater than threshold then oscillation is incremented.
600 
601  @return (uint) Number of oscillations of specified oscillator.
602 
603  """
604 
605  number_oscillations = 0;
606  waiting_differential = False;
607  threshold_passed = False;
608  high_level_trigger = True if (osc_dyn[0][index] > amplitude_threshold) else False;
609 
610  for values in osc_dyn:
611  if ( (values[index] >= amplitude_threshold) and (high_level_trigger is False) ):
612  high_level_trigger = True;
613  threshold_passed = True;
614 
615  elif ( (values[index] < amplitude_threshold) and (high_level_trigger is True) ):
616  high_level_trigger = False;
617  threshold_passed = True;
618 
619  if (threshold_passed is True):
620  threshold_passed = False;
621  if (waiting_differential is True and high_level_trigger is False):
622  number_oscillations += 1;
623  waiting_differential = False;
624 
625  else:
626  waiting_differential = True;
627 
628  return number_oscillations;
629 
630 
631 def allocate_sync_ensembles(dynamic, tolerance = 0.1, threshold = 1.0, ignore = None):
632  """!
633  @brief Allocate clusters in line with ensembles of synchronous oscillators where each
634  synchronous ensemble corresponds to only one cluster.
635 
636  @param[in] dynamic (dynamic): Dynamic of each oscillator.
637  @param[in] tolerance (double): Maximum error for allocation of synchronous ensemble oscillators.
638  @param[in] threshold (double): Amlitude trigger when spike is taken into account.
639  @param[in] ignore (bool): Set of indexes that shouldn't be taken into account.
640 
641  @return (list) Grours (lists) of indexes of synchronous oscillators, for example,
642  [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].
643 
644  """
645 
646  descriptors = [ [] for _ in range(len(dynamic[0])) ];
647 
648  # Check from the end for obtaining result
649  for index_dyn in range(0, len(dynamic[0]), 1):
650  if ((ignore is not None) and (index_dyn in ignore)):
651  continue;
652 
653  time_stop_simulation = len(dynamic) - 1;
654  active_state = False;
655 
656  if (dynamic[time_stop_simulation][index_dyn] > threshold):
657  active_state = True;
658 
659  # if active state is detected, it means we don't have whole oscillatory period for the considered oscillator, should be skipped.
660  if (active_state is True):
661  while ( (dynamic[time_stop_simulation][index_dyn] > threshold) and (time_stop_simulation > 0) ):
662  time_stop_simulation -= 1;
663 
664  # if there are no any oscillation than let's consider it like noise
665  if (time_stop_simulation == 0):
666  continue;
667 
668  # reset
669  active_state = False;
670 
671  desc = [0, 0, 0]; # end, start, average time of oscillation
672  for t in range(time_stop_simulation, 0, -1):
673  if ( (dynamic[t][index_dyn] > threshold) and (active_state is False) ):
674  desc[0] = t;
675  active_state = True;
676  elif ( (dynamic[t][index_dyn] < threshold) and (active_state is True) ):
677  desc[1] = t;
678  active_state = False;
679 
680  break;
681 
682  if (desc == [0, 0, 0]):
683  continue;
684 
685  desc[2] = desc[1] + (desc[0] - desc[1]) / 2.0;
686  descriptors[index_dyn] = desc;
687 
688 
689  # Cluster allocation
690  sync_ensembles = [];
691  desc_sync_ensembles = [];
692 
693  for index_desc in range(0, len(descriptors), 1):
694  if (descriptors[index_desc] == []):
695  continue;
696 
697  if (len(sync_ensembles) == 0):
698  desc_ensemble = descriptors[index_desc];
699  reducer = (desc_ensemble[0] - desc_ensemble[1]) * tolerance;
700 
701  desc_ensemble[0] = desc_ensemble[2] + reducer;
702  desc_ensemble[1] = desc_ensemble[2] - reducer;
703 
704  desc_sync_ensembles.append(desc_ensemble);
705  sync_ensembles.append([ index_desc ]);
706  else:
707  oscillator_captured = False;
708  for index_ensemble in range(0, len(sync_ensembles), 1):
709  if ( (desc_sync_ensembles[index_ensemble][0] > descriptors[index_desc][2]) and (desc_sync_ensembles[index_ensemble][1] < descriptors[index_desc][2])):
710  sync_ensembles[index_ensemble].append(index_desc);
711  oscillator_captured = True;
712  break;
713 
714  if (oscillator_captured is False):
715  desc_ensemble = descriptors[index_desc];
716  reducer = (desc_ensemble[0] - desc_ensemble[1]) * tolerance;
717 
718  desc_ensemble[0] = desc_ensemble[2] + reducer;
719  desc_ensemble[1] = desc_ensemble[2] - reducer;
720 
721  desc_sync_ensembles.append(desc_ensemble);
722  sync_ensembles.append([ index_desc ]);
723 
724  return sync_ensembles;
725 
726 
727 def draw_clusters(data, clusters, noise = [], marker_descr = '.', hide_axes = False, axes = None, display_result = True):
728  """!
729  @brief Displays clusters for data in 2D or 3D.
730 
731  @param[in] data (list): Points that are described by coordinates represented.
732  @param[in] clusters (list): Clusters that are represented by lists of indexes where each index corresponds to point in data.
733  @param[in] noise (list): Points that are regarded to noise.
734  @param[in] marker_descr (string): Marker for displaying points.
735  @param[in] hide_axes (bool): If True - axes is not displayed.
736  @param[in] axes (ax) Matplotlib axes where clusters should be drawn, if it is not specified (None) then new plot will be created.
737  @param[in] display_result (bool): If specified then matplotlib axes will be used for drawing and plot will not be shown.
738 
739  @return (ax) Matplotlib axes where drawn clusters are presented.
740 
741  """
742  # Get dimension
743  dimension = 0;
744  if ( (data is not None) and (clusters is not None) ):
745  dimension = len(data[0]);
746  elif ( (data is None) and (clusters is not None) ):
747  dimension = len(clusters[0][0]);
748  else:
749  raise NameError('Data or clusters should be specified exactly.');
750 
751  "Draw clusters"
752  colors = [ 'red', 'blue', 'darkgreen', 'brown', 'violet',
753  'deepskyblue', 'darkgrey', 'lightsalmon', 'deeppink', 'yellow',
754  'black', 'mediumspringgreen', 'orange', 'darkviolet', 'darkblue',
755  'silver', 'lime', 'pink', 'gold', 'bisque' ];
756 
757  if (len(clusters) > len(colors)):
758  raise NameError('Impossible to represent clusters due to number of specified colors.');
759 
760  fig = plt.figure();
761 
762  if (axes is None):
763  # Check for dimensions
764  if ((dimension) == 1 or (dimension == 2)):
765  axes = fig.add_subplot(111);
766  elif (dimension == 3):
767  axes = fig.gca(projection='3d');
768  else:
769  raise NameError('Drawer supports only 2d and 3d data representation');
770 
771  color_index = 0;
772  for cluster in clusters:
773  color = colors[color_index];
774  for item in cluster:
775  if (dimension == 1):
776  if (data is None):
777  axes.plot(item[0], 0.0, color = color, marker = marker_descr);
778  else:
779  axes.plot(data[item][0], 0.0, color = color, marker = marker_descr);
780 
781  if (dimension == 2):
782  if (data is None):
783  axes.plot(item[0], item[1], color = color, marker = marker_descr);
784  else:
785  axes.plot(data[item][0], data[item][1], color = color, marker = marker_descr);
786 
787  elif (dimension == 3):
788  if (data is None):
789  axes.scatter(item[0], item[1], item[2], c = color, marker = marker_descr);
790  else:
791  axes.scatter(data[item][0], data[item][1], data[item][2], c = color, marker = marker_descr);
792 
793  color_index += 1;
794 
795  for item in noise:
796  if (dimension == 1):
797  if (data is None):
798  axes.plot(item[0], 0.0, 'w' + marker_descr);
799  else:
800  axes.plot(data[item][0], 0.0, 'w' + marker_descr);
801 
802  if (dimension == 2):
803  if (data is None):
804  axes.plot(item[0], item[1], 'w' + marker_descr);
805  else:
806  axes.plot(data[item][0], data[item][1], 'w' + marker_descr);
807 
808  elif (dimension == 3):
809  if (data is None):
810  axes.scatter(item[0], item[1], item[2], c = 'w', marker = marker_descr);
811  else:
812  axes.scatter(data[item][0], data[item][1], data[item][2], c = 'w', marker = marker_descr);
813 
814  axes.grid(True);
815 
816  if (hide_axes is True):
817  axes.xaxis.set_ticklabels([]);
818  axes.yaxis.set_ticklabels([]);
819 
820  if (dimension == 3):
821  axes.zaxis.set_ticklabels([]);
822 
823  if (display_result is True):
824  plt.show();
825 
826  return axes;
827 
828 
829 def draw_dynamics(t, dyn, x_title = None, y_title = None, x_lim = None, y_lim = None, x_labels = True, y_labels = True, separate = False, axes = None):
830  """!
831  @brief Draw dynamics of neurons (oscillators) in the network.
832  @details It draws if matplotlib is not specified (None), othewise it should be performed manually.
833 
834  @param[in] t (list): Values of time (used by x axis).
835  @param[in] dyn (list): Values of output of oscillators (used by y axis).
836  @param[in] x_title (string): Title for Y.
837  @param[in] y_title (string): Title for X.
838  @param[in] x_lim (double): X limit.
839  @param[in] y_lim (double): Y limit.
840  @param[in] x_labels (bool): If True - shows X labels.
841  @param[in] y_labels (bool): If True - shows Y labels.
842  @param[in] separate (list): Consists of lists of oscillators where each such list consists of oscillator indexes that will be shown on separated stage.
843  @param[in] axes (ax): If specified then matplotlib axes will be used for drawing and plot will not be shown.
844 
845  @return (ax) Axes of matplotlib.
846 
847  """
848 
849  number_lines = 0;
850 
851  stage_xlim = None;
852  if (x_lim is not None):
853  stage_xlim = x_lim;
854  elif (len(t) > 0):
855  stage_xlim = [0, t[len(t) - 1]];
856 
857  if ( (isinstance(separate, bool) is True) and (separate is True) ):
858  if (isinstance(dyn[0], list) is True):
859  number_lines = len(dyn[0]);
860  else:
861  number_lines = 1;
862 
863  elif (isinstance(separate, list) is True):
864  number_lines = len(separate);
865 
866  else:
867  number_lines = 1;
868 
869  dysplay_result = False;
870  if (axes is None):
871  dysplay_result = True;
872  (fig, axes) = plt.subplots(number_lines, 1);
873 
874  # Check if we have more than one dynamic
875  if (isinstance(dyn[0], list) is True):
876  num_items = len(dyn[0]);
877  for index in range(0, num_items, 1):
878  y = [item[index] for item in dyn];
879 
880  if (number_lines > 1):
881  index_stage = -1;
882 
883  # Find required axes for the y
884  if (isinstance(separate, bool) is True):
885  index_stage = index;
886 
887  elif (isinstance(separate, list) is True):
888  for index_group in range(0, len(separate), 1):
889  if (index in separate[index_group]):
890  index_stage = index_group;
891  break;
892 
893  if (index_stage != -1):
894  if (index_stage != number_lines - 1):
895  axes[index_stage].get_xaxis().set_visible(False);
896 
897  axes[index_stage].plot(t, y, 'b-', linewidth = 0.5);
898  set_ax_param(axes[index_stage], x_title, y_title, stage_xlim, y_lim, x_labels, y_labels, True);
899 
900  else:
901  axes.plot(t, y, 'b-', linewidth = 0.5);
902  set_ax_param(axes, x_title, y_title, stage_xlim, y_lim, x_labels, y_labels, True);
903  else:
904  axes.plot(t, dyn, 'b-', linewidth = 0.5);
905  set_ax_param(axes, x_title, y_title, stage_xlim, y_lim, x_labels, y_labels, True);
906 
907  if (dysplay_result is True):
908  plt.show();
909 
910  return axes;
911 
912 
913 def set_ax_param(ax, x_title = None, y_title = None, x_lim = None, y_lim = None, x_labels = True, y_labels = True, grid = True):
914  """!
915  @brief Sets parameters for matplotlib ax.
916 
917  @param[in] ax (Axes): Axes for which parameters should applied.
918  @param[in] x_title (string): Title for Y.
919  @param[in] y_title (string): Title for X.
920  @param[in] x_lim (double): X limit.
921  @param[in] y_lim (double): Y limit.
922  @param[in] x_labels (bool): If True - shows X labels.
923  @param[in] y_labels (bool): If True - shows Y labels.
924  @param[in] grid (bool): If True - shows grid.
925 
926  """
927  from matplotlib.font_manager import FontProperties;
928  from matplotlib import rcParams;
929 
930  if (_platform == "linux") or (_platform == "linux2"):
931  rcParams['font.sans-serif'] = ['Liberation Serif'];
932  else:
933  rcParams['font.sans-serif'] = ['Arial'];
934 
935  rcParams['font.size'] = 12;
936 
937  surface_font = FontProperties();
938  if (_platform == "linux") or (_platform == "linux2"):
939  surface_font.set_name('Liberation Serif');
940  else:
941  surface_font.set_name('Arial');
942 
943  surface_font.set_size('12');
944 
945  if (y_title is not None): ax.set_ylabel(y_title, fontproperties = surface_font);
946  if (x_title is not None): ax.set_xlabel(x_title, fontproperties = surface_font);
947 
948  if (x_lim is not None): ax.set_xlim(x_lim[0], x_lim[1]);
949  if (y_lim is not None): ax.set_ylim(y_lim[0], y_lim[1]);
950 
951  if (x_labels is False): ax.xaxis.set_ticklabels([]);
952  if (y_labels is False): ax.yaxis.set_ticklabels([]);
953 
954  ax.grid(grid);
955 
956 
957 def draw_dynamics_set(dynamics, xtitle = None, ytitle = None, xlim = None, ylim = None, xlabels = False, ylabels = False):
958  """!
959  @brief Draw lists of dynamics of neurons (oscillators) in the network.
960 
961  @param[in] dynamics (list): List of network outputs that are represented by values of output of oscillators (used by y axis).
962  @param[in] xtitle (string): Title for Y.
963  @param[in] ytitle (string): Title for X.
964  @param[in] xlim (double): X limit.
965  @param[in] ylim (double): Y limit.
966  @param[in] xlabels (bool): If True - shows X labels.
967  @param[in] ylabels (bool): If True - shows Y labels.
968 
969  """
970  # Calculate edge for confortable representation.
971  number_dynamics = len(dynamics);
972  if (number_dynamics == 1):
973  draw_dynamics(dynamics[0][0], dynamics[0][1], xtitle, ytitle, xlim, ylim, xlabels, ylabels);
974  return;
975 
976  number_cols = int(numpy.ceil(number_dynamics ** 0.5));
977  number_rows = int(numpy.ceil(number_dynamics / number_cols));
978 
979  real_index = 0, 0;
980  double_indexer = True;
981  if ( (number_cols == 1) or (number_rows == 1) ):
982  real_index = 0;
983  double_indexer = False;
984 
985  (_, axarr) = plt.subplots(number_rows, number_cols);
986  #plt.setp([ax for ax in axarr], visible = False);
987 
988  for dynamic in dynamics:
989  axarr[real_index] = draw_dynamics(dynamic[0], dynamic[1], xtitle, ytitle, xlim, ylim, xlabels, ylabels, axes = axarr[real_index]);
990  #plt.setp(axarr[real_index], visible = True);
991 
992  if (double_indexer is True):
993  real_index = real_index[0], real_index[1] + 1;
994  if (real_index[1] >= number_cols):
995  real_index = real_index[0] + 1, 0;
996  else:
997  real_index += 1;
998 
999  plt.show();
1000 
1001 
1002 def draw_image_color_segments(source, clusters, hide_axes = True):
1003  """!
1004  @brief Shows image segments using colored image.
1005  @details Each color on result image represents allocated segment. The first image is initial and other is result of segmentation.
1006 
1007  @param[in] source (string): Path to image.
1008  @param[in] clusters (list): List of clusters (allocated segments of image) where each cluster
1009  consists of indexes of pixel from source image.
1010  @param[in] hide_axes (bool): If True then axes will not be displayed.
1011 
1012  """
1013 
1014  image_source = Image.open(source);
1015  image_size = image_source.size;
1016 
1017  (fig, axarr) = plt.subplots(1, 2);
1018 
1019  plt.setp([ax for ax in axarr], visible = False);
1020 
1021  available_colors = [ (0, 162, 232), (34, 177, 76), (237, 28, 36),
1022  (255, 242, 0), (0, 0, 0), (237, 28, 36),
1023  (255, 174, 201), (127, 127, 127), (185, 122, 87),
1024  (200, 191, 231), (136, 0, 21), (255, 127, 39),
1025  (63, 72, 204), (195, 195, 195), (255, 201, 14),
1026  (239, 228, 176), (181, 230, 29), (153, 217, 234),
1027  (112, 146, 180) ];
1028 
1029  image_color_segments = [(255, 255, 255)] * (image_size[0] * image_size[1]);
1030 
1031  for index_segment in range(len(clusters)):
1032  for index_pixel in clusters[index_segment]:
1033  image_color_segments[index_pixel] = available_colors[index_segment];
1034 
1035  stage = array(image_color_segments, numpy.uint8);
1036  stage = numpy.reshape(stage, (image_size[1], image_size[0]) + ((3),)); # ((3),) it's size of RGB - third dimension.
1037  image_cluster = Image.fromarray(stage, 'RGB');
1038 
1039  axarr[0].imshow(image_source, interpolation = 'none');
1040  axarr[1].imshow(image_cluster, interpolation = 'none');
1041 
1042  for i in range(2):
1043  plt.setp(axarr[i], visible = True);
1044 
1045  if (hide_axes is True):
1046  axarr[i].xaxis.set_ticklabels([]);
1047  axarr[i].yaxis.set_ticklabels([]);
1048  axarr[i].xaxis.set_ticks_position('none');
1049  axarr[i].yaxis.set_ticks_position('none');
1050 
1051  plt.show();
1052 
1053 
1054 def draw_image_mask_segments(source, clusters, hide_axes = True):
1055  """!
1056  @brief Shows image segments using black masks.
1057  @details Each black mask of allocated segment is presented on separate plot.
1058  The first image is initial and others are black masks of segments.
1059 
1060  @param[in] source (string): Path to image.
1061  @param[in] clusters (list): List of clusters (allocated segments of image) where each cluster
1062  consists of indexes of pixel from source image.
1063  @param[in] hide_axes (bool): If True then axes will not be displayed.
1064 
1065  """
1066  if len(clusters) == 0:
1067  print("Warning: Nothing to draw - list of clusters is empty.")
1068  return
1069 
1070  image_source = Image.open(source)
1071  image_size = image_source.size
1072 
1073  # Calculate edge for confortable representation.
1074  number_clusters = len(clusters) + 1 # show with the source image
1075 
1076  number_cols = int(numpy.ceil(number_clusters ** 0.5))
1077  number_rows = int(numpy.ceil(number_clusters / number_cols))
1078 
1079  real_index = 0, 0
1080  double_indexer = True
1081  if (number_cols == 1) or (number_rows == 1):
1082  real_index = 0
1083  double_indexer = False
1084 
1085  (fig, axarr) = plt.subplots(number_rows, number_cols)
1086  plt.setp([ax for ax in axarr], visible=False)
1087 
1088  axarr[real_index].imshow(image_source, interpolation='none')
1089  plt.setp(axarr[real_index], visible=True)
1090 
1091  if hide_axes is True:
1092  axarr[real_index].xaxis.set_ticklabels([])
1093  axarr[real_index].yaxis.set_ticklabels([])
1094  axarr[real_index].xaxis.set_ticks_position('none')
1095  axarr[real_index].yaxis.set_ticks_position('none')
1096 
1097  if double_indexer is True:
1098  real_index = 0, 1
1099  else:
1100  real_index += 1
1101 
1102  for cluster in clusters:
1103  stage_cluster = [(255, 255, 255)] * (image_size[0] * image_size[1])
1104  for index in cluster:
1105  stage_cluster[index] = (0, 0, 0)
1106 
1107  stage = array(stage_cluster, numpy.uint8)
1108  stage = numpy.reshape(stage, (image_size[1], image_size[0]) + ((3),)) # ((3),) it's size of RGB - 3rd dimension.
1109 
1110  image_cluster = Image.fromarray(stage, 'RGB')
1111 
1112  axarr[real_index].imshow(image_cluster, interpolation = 'none')
1113  plt.setp(axarr[real_index], visible = True)
1114 
1115  if hide_axes is True:
1116  axarr[real_index].xaxis.set_ticklabels([])
1117  axarr[real_index].yaxis.set_ticklabels([])
1118 
1119  axarr[real_index].xaxis.set_ticks_position('none')
1120  axarr[real_index].yaxis.set_ticks_position('none')
1121 
1122  if double_indexer is True:
1123  real_index = real_index[0], real_index[1] + 1
1124  if real_index[1] >= number_cols:
1125  real_index = real_index[0] + 1, 0
1126  else:
1127  real_index += 1
1128 
1129  plt.show()
1130 
1131 
1132 def find_left_element(sorted_data, right, comparator):
1133  """!
1134  @brief Returns the element's index at the left side from the right border with the same value as the
1135  last element in the range `sorted_data`.
1136 
1137  @details The element at the right is considered as target to search. `sorted_data` must
1138  be sorted collection. The complexity of the algorithm is `O(log(n))`. The
1139  algorithm is based on the binary search algorithm.
1140 
1141  @param[in] sorted_data: input data to find the element.
1142  @param[in] right: the index of the right element from that search is started.
1143  @param[in] comparator: comparison function object which returns `True` if the first argument
1144  is less than the second.
1145 
1146  @return The element's index at the left side from the right border with the same value as the
1147  last element in the range `sorted_data`.
1148 
1149  """
1150  if len(sorted_data) == 0:
1151  raise ValueError("Input data is empty.")
1152 
1153  left = 0
1154  middle = (right - left) // 2
1155  target = sorted_data[right]
1156 
1157  while left < right:
1158  if comparator(sorted_data[middle], target):
1159  left = middle + 1
1160  else:
1161  right = middle
1162 
1163  offset = (right - left) // 2
1164  middle = left + offset
1165 
1166  return left
1167 
1168 
1169 def linear_sum(list_vector):
1170  """!
1171  @brief Calculates linear sum of vector that is represented by list, each element can be represented by list - multidimensional elements.
1172 
1173  @param[in] list_vector (list): Input vector.
1174 
1175  @return (list|double) Linear sum of vector that can be represented by list in case of multidimensional elements.
1176 
1177  """
1178  dimension = 1
1179  linear_sum = 0.0
1180  list_representation = (type(list_vector[0]) == list)
1181 
1182  if list_representation is True:
1183  dimension = len(list_vector[0])
1184  linear_sum = [0] * dimension
1185 
1186  for index_element in range(0, len(list_vector)):
1187  if list_representation is True:
1188  for index_dimension in range(0, dimension):
1189  linear_sum[index_dimension] += list_vector[index_element][index_dimension]
1190  else:
1191  linear_sum += list_vector[index_element]
1192 
1193  return linear_sum
1194 
1195 
1196 def square_sum(list_vector):
1197  """!
1198  @brief Calculates square sum of vector that is represented by list, each element can be represented by list - multidimensional elements.
1199 
1200  @param[in] list_vector (list): Input vector.
1201 
1202  @return (double) Square sum of vector.
1203 
1204  """
1205 
1206  square_sum = 0.0
1207  list_representation = (type(list_vector[0]) == list)
1208 
1209  for index_element in range(0, len(list_vector)):
1210  if list_representation is True:
1211  square_sum += sum(list_math_multiplication(list_vector[index_element], list_vector[index_element]))
1212  else:
1213  square_sum += list_vector[index_element] * list_vector[index_element]
1214 
1215  return square_sum
1216 
1217 
1219  """!
1220  @brief Calculates subtraction of two lists.
1221  @details Each element from list 'a' is subtracted by element from list 'b' accordingly.
1222 
1223  @param[in] a (list): List of elements that supports mathematical subtraction.
1224  @param[in] b (list): List of elements that supports mathematical subtraction.
1225 
1226  @return (list) Results of subtraction of two lists.
1227 
1228  """
1229  return [a[i] - b[i] for i in range(len(a))]
1230 
1231 
1233  """!
1234  @brief Calculates subtraction between list and number.
1235  @details Each element from list 'a' is subtracted by number 'b'.
1236 
1237  @param[in] a (list): List of elements that supports mathematical subtraction.
1238  @param[in] b (list): Value that supports mathematical subtraction.
1239 
1240  @return (list) Results of subtraction between list and number.
1241 
1242  """
1243  return [a[i] - b for i in range(len(a))]
1244 
1245 
1247  """!
1248  @brief Addition of two lists.
1249  @details Each element from list 'a' is added to element from list 'b' accordingly.
1250 
1251  @param[in] a (list): List of elements that supports mathematic addition..
1252  @param[in] b (list): List of elements that supports mathematic addition..
1253 
1254  @return (list) Results of addtion of two lists.
1255 
1256  """
1257  return [a[i] + b[i] for i in range(len(a))]
1258 
1259 
1261  """!
1262  @brief Addition between list and number.
1263  @details Each element from list 'a' is added to number 'b'.
1264 
1265  @param[in] a (list): List of elements that supports mathematic addition.
1266  @param[in] b (double): Value that supports mathematic addition.
1267 
1268  @return (list) Result of addtion of two lists.
1269 
1270  """
1271  return [a[i] + b for i in range(len(a))]
1272 
1273 
1275  """!
1276  @brief Division between list and number.
1277  @details Each element from list 'a' is divided by number 'b'.
1278 
1279  @param[in] a (list): List of elements that supports mathematic division.
1280  @param[in] b (double): Value that supports mathematic division.
1281 
1282  @return (list) Result of division between list and number.
1283 
1284  """
1285  return [a[i] / b for i in range(len(a))]
1286 
1287 
1289  """!
1290  @brief Division of two lists.
1291  @details Each element from list 'a' is divided by element from list 'b' accordingly.
1292 
1293  @param[in] a (list): List of elements that supports mathematic division.
1294  @param[in] b (list): List of elements that supports mathematic division.
1295 
1296  @return (list) Result of division of two lists.
1297 
1298  """
1299  return [a[i] / b[i] for i in range(len(a))]
1300 
1301 
1303  """!
1304  @brief Multiplication between list and number.
1305  @details Each element from list 'a' is multiplied by number 'b'.
1306 
1307  @param[in] a (list): List of elements that supports mathematic division.
1308  @param[in] b (double): Number that supports mathematic division.
1309 
1310  @return (list) Result of division between list and number.
1311 
1312  """
1313  return [a[i] * b for i in range(len(a))]
1314 
1315 
1317  """!
1318  @brief Multiplication of two lists.
1319  @details Each element from list 'a' is multiplied by element from list 'b' accordingly.
1320 
1321  @param[in] a (list): List of elements that supports mathematic multiplication.
1322  @param[in] b (list): List of elements that supports mathematic multiplication.
1323 
1324  @return (list) Result of multiplication of elements in two lists.
1325 
1326  """
1327  return [a[i] * b[i] for i in range(len(a))]
pyclustering.utils.norm_vector
def norm_vector(vector)
Calculates norm of an input vector that is known as a vector length.
Definition: __init__.py:538
pyclustering.utils.average_intra_cluster_distance
def average_intra_cluster_distance(cluster1, cluster2, data=None)
Calculates average intra-cluster distance between two clusters.
Definition: __init__.py:362
pyclustering.utils.square_sum
def square_sum(list_vector)
Calculates square sum of vector that is represented by list, each element can be represented by list ...
Definition: __init__.py:1196
pyclustering.utils.medoid
def medoid(data, indexes=None, **kwargs)
Calculate medoid for input points.
Definition: __init__.py:213
pyclustering.utils.draw_dynamics_set
def draw_dynamics_set(dynamics, xtitle=None, ytitle=None, xlim=None, ylim=None, xlabels=False, ylabels=False)
Draw lists of dynamics of neurons (oscillators) in the network.
Definition: __init__.py:957
pyclustering.utils.data_corners
def data_corners(data, data_filter=None)
Finds maximum and minimum corner in each dimension of the specified data.
Definition: __init__.py:506
pyclustering.utils.list_math_subtraction
def list_math_subtraction(a, b)
Calculates subtraction of two lists.
Definition: __init__.py:1218
pyclustering.utils.draw_image_mask_segments
def draw_image_mask_segments(source, clusters, hide_axes=True)
Shows image segments using black masks.
Definition: __init__.py:1054
pyclustering.utils.list_math_addition
def list_math_addition(a, b)
Addition of two lists.
Definition: __init__.py:1246
pyclustering.utils.average_inter_cluster_distance
def average_inter_cluster_distance(cluster1, cluster2, data=None)
Calculates average inter-cluster distance between two clusters.
Definition: __init__.py:331
pyclustering.utils.extract_number_oscillations
def extract_number_oscillations(osc_dyn, index=0, amplitude_threshold=1.0)
Extracts number of oscillations of specified oscillator.
Definition: __init__.py:592
pyclustering.utils.manhattan_distance
def manhattan_distance(a, b)
Calculate Manhattan distance between vector a and b.
Definition: __init__.py:308
pyclustering.utils.read_image
def read_image(filename)
Returns image as N-dimension (depends on the input image) matrix, where one element of list describes...
Definition: __init__.py:69
pyclustering.utils.allocate_sync_ensembles
def allocate_sync_ensembles(dynamic, tolerance=0.1, threshold=1.0, ignore=None)
Allocate clusters in line with ensembles of synchronous oscillators where each synchronous ensemble c...
Definition: __init__.py:631
pyclustering.utils.variance_increase_distance
def variance_increase_distance(cluster1, cluster2, data=None)
Calculates variance increase distance between two clusters.
Definition: __init__.py:413
pyclustering.utils.find_left_element
def find_left_element(sorted_data, right, comparator)
Returns the element's index at the left side from the right border with the same value as the last el...
Definition: __init__.py:1132
pyclustering.utils.draw_image_color_segments
def draw_image_color_segments(source, clusters, hide_axes=True)
Shows image segments using colored image.
Definition: __init__.py:1002
pyclustering.utils.gray_pattern_borders
def gray_pattern_borders(image)
Returns coordinates of gray image content on the input image.
Definition: __init__.py:138
pyclustering.utils.draw_dynamics
def draw_dynamics(t, dyn, x_title=None, y_title=None, x_lim=None, y_lim=None, x_labels=True, y_labels=True, separate=False, axes=None)
Draw dynamics of neurons (oscillators) in the network.
Definition: __init__.py:829
pyclustering.utils.stretch_pattern
def stretch_pattern(image_source)
Returns stretched content as 1-dimension (gray colored) matrix with size of input image.
Definition: __init__.py:113
pyclustering.utils.calculate_distance_matrix
def calculate_distance_matrix(sample, metric=distance_metric(type_metric.EUCLIDEAN))
Calculates distance matrix for data sample (sequence of points) using specified metric (by default Eu...
Definition: __init__.py:54
pyclustering.utils.set_ax_param
def set_ax_param(ax, x_title=None, y_title=None, x_lim=None, y_lim=None, x_labels=True, y_labels=True, grid=True)
Sets parameters for matplotlib ax.
Definition: __init__.py:913
pyclustering.utils.list_math_addition_number
def list_math_addition_number(a, b)
Addition between list and number.
Definition: __init__.py:1260
pyclustering.utils.timedcall
def timedcall(executable_function, *args, **kwargs)
Executes specified method or function with measuring of execution time.
Definition: __init__.py:573
pyclustering.utils.list_math_multiplication
def list_math_multiplication(a, b)
Multiplication of two lists.
Definition: __init__.py:1316
pyclustering.utils.linear_sum
def linear_sum(list_vector)
Calculates linear sum of vector that is represented by list, each element can be represented by list ...
Definition: __init__.py:1169
pyclustering.utils.list_math_substraction_number
def list_math_substraction_number(a, b)
Calculates subtraction between list and number.
Definition: __init__.py:1232
pyclustering.utils.euclidean_distance
def euclidean_distance(a, b)
Calculate Euclidean distance between vector a and b.
Definition: __init__.py:263
pyclustering.utils.euclidean_distance_square
def euclidean_distance_square(a, b)
Calculate square Euclidian distance between vector a and b.
Definition: __init__.py:287
pyclustering.utils.list_math_multiplication_number
def list_math_multiplication_number(a, b)
Multiplication between list and number.
Definition: __init__.py:1302
pyclustering.utils.rgb2gray
def rgb2gray(image_rgb_array)
Returns image as 1-dimension (gray colored) matrix, where one element of list describes pixel.
Definition: __init__.py:84
pyclustering.utils.list_math_division
def list_math_division(a, b)
Division of two lists.
Definition: __init__.py:1288
pyclustering.utils.list_math_division_number
def list_math_division_number(a, b)
Division between list and number.
Definition: __init__.py:1274
pyclustering.utils.average_neighbor_distance
def average_neighbor_distance(points, num_neigh)
Returns average distance for establish links between specified number of nearest neighbors.
Definition: __init__.py:180
pyclustering.utils.read_sample
def read_sample(filename)
Returns data sample from simple text file.
Definition: __init__.py:30
pyclustering.utils.calculate_ellipse_description
def calculate_ellipse_description(covariance, scale=2.0)
Calculates description of ellipse using covariance matrix.
Definition: __init__.py:482
pyclustering.utils.metric
Module provides various distance metrics - abstraction of the notion of distance in a metric space.
Definition: metric.py:1
pyclustering.utils.draw_clusters
def draw_clusters(data, clusters, noise=[], marker_descr='.', hide_axes=False, axes=None, display_result=True)
Displays clusters for data in 2D or 3D.
Definition: __init__.py:727
pyclustering.utils.heaviside
def heaviside(value)
Calculates Heaviside function that represents step function.
Definition: __init__.py:557