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