def _phase_kuramoto(self, teta, t, argv):

index = argv;<EOL>phase = <NUM_LIT:0.0>;<EOL>term = <NUM_LIT:0.0>;<EOL>for k in range(<NUM_LIT:0>, self._num_osc):<EOL><INDENT>if (k != index):<EOL><INDENT>phase_delta = self._phases[k] - teta;<EOL>phase += self._coupling[index][k] * math.sin(phase_delta);<EOL>term1 = self._increase_strength1 * math.sin(<NUM_LIT> * phase_delta);<EOL>term2 = self._increase_strength2 * math.sin(<NUM_LIT> * phase_delta);<EOL>term += (term1 - term2);<EOL><DEDENT><DEDENT>return ( phase + term / len(self) )<EOL>

!
        @brief Returns result of phase calculation for specified oscillator in the network.

        @param[in] teta (double): Phase of the oscillator that is differentiated.
        @param[in] t (double): Current time of simulation.
        @param[in] argv (tuple): Index of the oscillator in the list.

        @return (double) New phase for specified oscillator (don't assign it here).


if (len(pattern) != len(self)):<EOL><INDENT>raise NameError('<STR_LIT>' + len(pattern) + '<STR_LIT>');<EOL><DEDENT>for feature in pattern:<EOL><INDENT>if ( (feature != -<NUM_LIT:1.0>) and (feature != <NUM_LIT:1.0>) ):<EOL><INDENT>raise NameError('<STR_LIT>' + feature + '<STR_LIT>');<EOL><DEDENT><DEDENT>

!
        @brief Validates pattern.
        @details Throws exception if length of pattern is not equal to size of the network or if it consists feature with value that are not equal to [-1; 1].

        @param[in] pattern (list): Pattern for recognition represented by list of features that are equal to [-1; 1].


def __init__(self, output=None, time=None):

<EOL>self.output = output or []<EOL>self.time = time or []<EOL>

!
        @brief Costructor of the chaotic neural network output dynamic.

        @param[in] output (list): Dynamic of oscillators on each step of simulation.
        @param[in] time (list): Simulation time.


return len(self.output)<EOL>

!
        @brief (uint) Returns amount of simulation steps that are stored.


number_neurons = len(self.output[<NUM_LIT:0>])<EOL>observation_matrix = []<EOL>for iteration in range(len(self.output)):<EOL><INDENT>obervation_column = []<EOL>for index_neuron in range(number_neurons):<EOL><INDENT>obervation_column.append(heaviside(self.output[iteration][index_neuron]))<EOL><DEDENT>observation_matrix.append(obervation_column)<EOL><DEDENT>return observation_matrix<EOL>

!
        @brief Allocates observation matrix in line with output dynamic of the network.
        @details Matrix where state of each neuron is denoted by zero/one in line with Heaviside function on each iteration.

        @return (list) Observation matrix of the network dynamic.


def __allocate_neuron_patterns(self, start_iteration, stop_iteration):

pattern_matrix = []<EOL>for index_neuron in range(len(self.output[<NUM_LIT:0>])):<EOL><INDENT>pattern_neuron = []<EOL>for iteration in range(start_iteration, stop_iteration):<EOL><INDENT>pattern_neuron.append(heaviside(self.output[iteration][index_neuron]))<EOL><DEDENT>pattern_matrix.append(pattern_neuron)<EOL><DEDENT>return pattern_matrix<EOL>

!
        @brief Allocates observation transposed matrix of neurons that is limited by specified periods of simulation.
        @details Matrix where state of each neuron is denoted by zero/one in line with Heaviside function on each iteration.

        @return (list) Transposed observation matrix that is limited by specified periods of simulation.


iterations = steps<EOL>if iterations >= len(self.output):<EOL><INDENT>iterations = len(self.output)<EOL><DEDENT>ensembles = []<EOL>start_iteration = len(self.output) - iterations<EOL>end_iteration = len(self.output)<EOL>pattern_matrix = self.__allocate_neuron_patterns(start_iteration, end_iteration)<EOL>ensembles.append( [<NUM_LIT:0>] )<EOL>for index_neuron in range(<NUM_LIT:1>, len(self.output[<NUM_LIT:0>])):<EOL><INDENT>neuron_pattern = pattern_matrix[index_neuron][:]<EOL>neuron_assigned = False<EOL>for ensemble in ensembles:<EOL><INDENT>ensemble_pattern = pattern_matrix[ensemble[<NUM_LIT:0>]][:]<EOL>if neuron_pattern == ensemble_pattern:<EOL><INDENT>ensemble.append(index_neuron)<EOL>neuron_assigned = True<EOL>break<EOL><DEDENT><DEDENT>if neuron_assigned is False:<EOL><INDENT>ensembles.append( [index_neuron] )<EOL><DEDENT><DEDENT>return ensembles<EOL>

!
        @brief Allocate clusters in line with ensembles of synchronous neurons where each synchronous ensemble corresponds to only one cluster.

        @param[in] steps (double): Amount of steps from the end that is used for analysis. During specified period chaotic neural network should have stable output
                    otherwise inccorect results are allocated.

        @return (list) Grours (lists) of indexes of synchronous oscillators.
                For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].


draw_dynamics(cnn_output_dynamic.time, cnn_output_dynamic.output, x_title = "<STR_LIT:t>", y_title = "<STR_LIT:x>")<EOL>

!
        @brief Shows output dynamic (output of each neuron) during simulation.

        @param[in] cnn_output_dynamic (cnn_dynamic): Output dynamic of the chaotic neural network.

        @see show_dynamic_matrix
        @see show_observation_matrix


network_dynamic = numpy.array(cnn_output_dynamic.output)<EOL>plt.imshow(network_dynamic.T, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT:None>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT:1.0>)<EOL>plt.show()<EOL>

!
        @brief Shows output dynamic as matrix in grey colors.
        @details This type of visualization is convenient for observing allocated clusters.

        @param[in] cnn_output_dynamic (cnn_dynamic): Output dynamic of the chaotic neural network.

        @see show_output_dynamic
        @see show_observation_matrix


observation_matrix = numpy.array(cnn_output_dynamic.allocate_observation_matrix())<EOL>plt.imshow(observation_matrix.T, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT:None>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT:1.0>)<EOL>plt.show()<EOL>

!
        @brief Shows observation matrix as black/white blocks.
        @details This type of visualization is convenient for observing allocated clusters.

        @param[in] cnn_output_dynamic (cnn_dynamic): Output dynamic of the chaotic neural network.

        @see show_output_dynamic
        @see show_dynamic_matrix


def __init__(self, num_osc, conn_type = type_conn.ALL_TO_ALL, amount_neighbors = <NUM_LIT:3>):

self.__num_osc = num_osc<EOL>self.__conn_type = conn_type<EOL>self.__amount_neighbors = amount_neighbors<EOL>self.__average_distance = <NUM_LIT:0.0><EOL>self.__weights = None<EOL>self.__weights_summary = None<EOL>self.__location = None     <EOL>random.seed()<EOL>self.__output = [ random.random() for _ in range(num_osc) ]<EOL>

!
        @brief Constructor of chaotic neural network.

        @param[in] num_osc (uint): Amount of neurons in the chaotic neural network.
        @param[in] conn_type (type_conn): CNN type connection for the network.
        @param[in] amount_neighbors (uint): k-nearest neighbors for calculation scaling constant of weights.


return self.__num_osc<EOL>

!
        @brief Returns size of the chaotic neural network that is defined by amount of neurons.


self.__create_weights(stimulus)<EOL>self.__location = stimulus<EOL>dynamic = cnn_dynamic([], [])<EOL>dynamic.output.append(self.__output)<EOL>dynamic.time.append(<NUM_LIT:0>)<EOL>for step in range(<NUM_LIT:1>, steps, <NUM_LIT:1>):<EOL><INDENT>self.__output = self.__calculate_states()<EOL>dynamic.output.append(self.__output)<EOL>dynamic.time.append(step)<EOL><DEDENT>return dynamic<EOL>

!
        @brief Simulates chaotic neural network with extrnal stimulus during specified steps.
        @details Stimulus are considered as a coordinates of neurons and in line with that weights
                 are initialized.

        @param[in] steps (uint): Amount of steps for simulation.
        @param[in] stimulus (list): Stimulus that are used for simulation.

        @return (cnn_dynamic) Output dynamic of the chaotic neural network.


output = [ <NUM_LIT:0.0> for _ in range(self.__num_osc) ]<EOL>for i in range(self.__num_osc):<EOL><INDENT>output[i] = self.__neuron_evolution(i)<EOL><DEDENT>return output<EOL>

!
        @brief Calculates new state of each neuron.
        @detail There is no any assignment.

        @return (list) Returns new states (output).


value = <NUM_LIT:0.0><EOL>for index_neighbor in range(self.__num_osc):<EOL><INDENT>value += self.__weights[index][index_neighbor] * (<NUM_LIT:1.0> - <NUM_LIT> * (self.__output[index_neighbor] ** <NUM_LIT:2>))<EOL><DEDENT>return value / self.__weights_summary[index]<EOL>

!
        @brief Calculates state of the neuron with specified index.

        @param[in] index (uint): Index of neuron in the network.

        @return (double) New output of the specified neuron.


self.__average_distance = average_neighbor_distance(stimulus, self.__amount_neighbors)<EOL>self.__weights = [ [ <NUM_LIT:0.0> for _ in range(len(stimulus)) ] for _ in range(len(stimulus)) ]<EOL>self.__weights_summary = [ <NUM_LIT:0.0> for _ in range(self.__num_osc) ]<EOL>if self.__conn_type == type_conn.ALL_TO_ALL:<EOL><INDENT>self.__create_weights_all_to_all(stimulus)<EOL><DEDENT>elif self.__conn_type == type_conn.TRIANGULATION_DELAUNAY:<EOL><INDENT>self.__create_weights_delaunay_triangulation(stimulus)<EOL><DEDENT>

!
        @brief Create weights between neurons in line with stimulus.

        @param[in] stimulus (list): External stimulus for the chaotic neural network.


for i in range(len(stimulus)):<EOL><INDENT>for j in range(i + <NUM_LIT:1>, len(stimulus)):<EOL><INDENT>weight = self.__calculate_weight(stimulus[i], stimulus[j])<EOL>self.__weights[i][j] = weight<EOL>self.__weights[j][i] = weight<EOL>self.__weights_summary[i] += weight<EOL>self.__weights_summary[j] += weight<EOL><DEDENT><DEDENT>

!
        @brief Create weight all-to-all structure between neurons in line with stimulus.

        @param[in] stimulus (list): External stimulus for the chaotic neural network.


points = numpy.array(stimulus)<EOL>triangulation = Delaunay(points)<EOL>for triangle in triangulation.simplices:<EOL><INDENT>for index_tri_point1 in range(len(triangle)):<EOL><INDENT>for index_tri_point2 in range(index_tri_point1 + <NUM_LIT:1>, len(triangle)):<EOL><INDENT>index_point1 = triangle[index_tri_point1]<EOL>index_point2 = triangle[index_tri_point2]<EOL>weight = self.__calculate_weight(stimulus[index_point1], stimulus[index_point2])<EOL>self.__weights[index_point1][index_point2] = weight<EOL>self.__weights[index_point2][index_point1] = weight<EOL>self.__weights_summary[index_point1] += weight<EOL>self.__weights_summary[index_point2] += weight<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Create weight Denlauny triangulation structure between neurons in line with stimulus.

        @param[in] stimulus (list): External stimulus for the chaotic neural network.


def __calculate_weight(self, stimulus1, stimulus2):

distance = euclidean_distance_square(stimulus1, stimulus2)<EOL>return math.exp(-distance / (<NUM_LIT> * self.__average_distance))<EOL>

!
        @brief Calculate weight between neurons that have external stimulus1 and stimulus2.

        @param[in] stimulus1 (list): External stimulus of the first neuron.
        @param[in] stimulus2 (list): External stimulus of the second neuron.

        @return (double) Weight between neurons that are under specified stimulus.


dimension = len(self.__location[<NUM_LIT:0>])<EOL>if (dimension != <NUM_LIT:3>) and (dimension != <NUM_LIT:2>):<EOL><INDENT>raise NameError('<STR_LIT>')<EOL><DEDENT>(fig, axes) = self.__create_surface(dimension)<EOL>for i in range(<NUM_LIT:0>, self.__num_osc, <NUM_LIT:1>):<EOL><INDENT>if dimension == <NUM_LIT:2>:<EOL><INDENT>axes.plot(self.__location[i][<NUM_LIT:0>], self.__location[i][<NUM_LIT:1>], '<STR_LIT>')<EOL>for j in range(i, self.__num_osc, <NUM_LIT:1>):    <EOL><INDENT>if self.__weights[i][j] > <NUM_LIT:0.0>:<EOL><INDENT>axes.plot([self.__location[i][<NUM_LIT:0>], self.__location[j][<NUM_LIT:0>]], [self.__location[i][<NUM_LIT:1>], self.__location[j][<NUM_LIT:1>]], '<STR_LIT>', linewidth = <NUM_LIT:0.5>)<EOL><DEDENT><DEDENT><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>axes.scatter(self.__location[i][<NUM_LIT:0>], self.__location[i][<NUM_LIT:1>], self.__location[i][<NUM_LIT:2>], c = '<STR_LIT:b>', marker = '<STR_LIT:o>')<EOL>for j in range(i, self.__num_osc, <NUM_LIT:1>):    <EOL><INDENT>if self.__weights[i][j] > <NUM_LIT:0.0>:<EOL><INDENT>axes.plot([self.__location[i][<NUM_LIT:0>], self.__location[j][<NUM_LIT:0>]], [self.__location[i][<NUM_LIT:1>], self.__location[j][<NUM_LIT:1>]], [self.__location[i][<NUM_LIT:2>], self.__location[j][<NUM_LIT:2>]], '<STR_LIT>', linewidth = <NUM_LIT:0.5>)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>plt.grid()<EOL>plt.show()<EOL>

!
        @brief Shows structure of the network: neurons and connections between them.


rcParams['<STR_LIT>'] = ['<STR_LIT>']<EOL>rcParams['<STR_LIT>'] = <NUM_LIT:12><EOL>fig = plt.figure()<EOL>axes = None<EOL>if dimension == <NUM_LIT:2>:<EOL><INDENT>axes = fig.add_subplot(<NUM_LIT>)<EOL><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>axes = fig.gca(projection='<STR_LIT>')<EOL><DEDENT>surface_font = FontProperties()<EOL>surface_font.set_name('<STR_LIT>')<EOL>surface_font.set_size('<STR_LIT>')<EOL>return (fig, axes)<EOL>

!
        @brief Prepares surface for showing network structure in line with specified dimension.

        @param[in] dimension (uint): Dimension of processed data (external stimulus).

        @return (tuple) Description of surface for drawing network structure.


<EOL>self.init_type = type_init.uniform_grid<EOL>self.init_radius = None<EOL>self.init_learn_rate = <NUM_LIT:0.1><EOL>self.adaptation_threshold = <NUM_LIT><EOL>

!
        @brief Constructor container of SOM parameters.


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._size = wrapper.som_get_size(self.__ccore_som_pointer)<EOL><DEDENT>return self._size<EOL>

!
        @brief Return size of self-organized map that is defined by total number of neurons.

        @return (uint) Size of self-organized map (number of neurons).


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._weights = wrapper.som_get_weights(self.__ccore_som_pointer)<EOL><DEDENT>return self._weights<EOL>

!
        @brief Return weight of each neuron.

        @return (list) Weights of each neuron.


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._award = wrapper.som_get_awards(self.__ccore_som_pointer)<EOL><DEDENT>return self._award<EOL>

!
        @brief Return amount of captured objects by each neuron after training.

        @return (list) Amount of captured objects by each neuron.

        @see train()


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._capture_objects = wrapper.som_get_capture_objects(self.__ccore_som_pointer)<EOL><DEDENT>return self._capture_objects<EOL>

!
        @brief Returns indexes of captured objects by each neuron.
        @details For example, network with size 2x2 has been trained on 5 sample, we neuron #1 has won one object with
                  index '1', neuron #2 - objects with indexes '0', '3', '4', neuron #3 - nothing, neuron #4 - object
                  with index '2'. Thus, output is [ [1], [0, 3, 4], [], [2] ].

        @return (list) Indexes of captured objects by each neuron.


def __init__(self, rows, cols, conn_type = type_conn.grid_eight, parameters = None, ccore = True):

<EOL>self._cols = cols<EOL>self._rows = rows<EOL>self._size = cols * rows<EOL>self._conn_type = conn_type<EOL>self._data = None<EOL>self._neighbors = None<EOL>self._local_radius = <NUM_LIT:0.0><EOL>self._learn_rate = <NUM_LIT:0.0><EOL>self.__ccore_som_pointer = None<EOL>if parameters is not None:<EOL><INDENT>self._params = parameters<EOL><DEDENT>else:<EOL><INDENT>self._params = som_parameters()<EOL><DEDENT>if self._params.init_radius is None:<EOL><INDENT>self._params.init_radius = self.__initialize_initial_radius(rows, cols)<EOL><DEDENT>if (ccore is True) and ccore_library.workable():<EOL><INDENT>self.__ccore_som_pointer = wrapper.som_create(rows, cols, conn_type, self._params)<EOL><DEDENT>else:<EOL><INDENT>self._location = self.__initialize_locations(rows, cols)<EOL>self._weights = [ [<NUM_LIT:0.0>] ] * self._size<EOL>self._award = [<NUM_LIT:0>] * self._size<EOL>self._capture_objects = [ [] for i in range(self._size) ]<EOL>self._sqrt_distances = None<EOL>if conn_type != type_conn.func_neighbor:<EOL><INDENT>self._create_connections(conn_type)<EOL><DEDENT><DEDENT>

!
        @brief Constructor of self-organized map.

        @param[in] rows (uint): Number of neurons in the column (number of rows).
        @param[in] cols (uint): Number of neurons in the row (number of columns).
        @param[in] conn_type (type_conn): Type of connection between oscillators in the network (grid four, grid eight, honeycomb, function neighbour).
        @param[in] parameters (som_parameters): Other specific parameters.
        @param[in] ccore (bool): If True simulation is performed by CCORE library (C++ implementation of pyclustering).


if self.__ccore_som_pointer is not None:<EOL><INDENT>wrapper.som_destroy(self.__ccore_som_pointer)<EOL><DEDENT>

!
        @brief Destructor of the self-organized feature map.


return self._size<EOL>

!
        @brief Returns size of the network that defines by amount of neuron in it.

        @return (uint) Size of self-organized map (amount of neurons).


if self.__ccore_som_pointer is not None:<EOL><INDENT>self.__download_dump_from_ccore()<EOL>return self.__get_dump_from_python(True)<EOL><DEDENT>return self.__get_dump_from_python(False)<EOL>

@brief Returns state of SOM network that can be used to store network.


if som_state['<STR_LIT>'] is True and ccore_library.workable():<EOL><INDENT>self.__upload_dump_to_ccore(som_state['<STR_LIT:state>'])<EOL><DEDENT>else:<EOL><INDENT>self.__upload_dump_to_python(som_state['<STR_LIT:state>'])<EOL><DEDENT>

@brief Set state of SOM network that can be used to load network.


def __initialize_initial_radius(self, rows, cols):

if (cols + rows) / <NUM_LIT> > <NUM_LIT:1.0>:<EOL><INDENT>return <NUM_LIT><EOL><DEDENT>elif (cols > <NUM_LIT:1>) and (rows > <NUM_LIT:1>):<EOL><INDENT>return <NUM_LIT><EOL><DEDENT>else: <EOL><INDENT>return <NUM_LIT:1.0><EOL><DEDENT>

!
        @brief Initialize initial radius using map sizes.

        @param[in] rows (uint): Number of neurons in the column (number of rows).
        @param[in] cols (uint): Number of neurons in the row (number of columns).

        @return (list) Value of initial radius.


def __initialize_locations(self, rows, cols):

location = list()<EOL>for i in range(rows):<EOL><INDENT>for j in range(cols):<EOL><INDENT>location.append([float(i), float(j)])<EOL><DEDENT><DEDENT>return location<EOL>

!
        @brief Initialize locations (coordinates in SOM grid) of each neurons in the map.

        @param[in] rows (uint): Number of neurons in the column (number of rows).
        @param[in] cols (uint): Number of neurons in the row (number of columns).

        @return (list) List of coordinates of each neuron in map.


def __initialize_distances(self, size, location):

sqrt_distances = [ [ [] for i in range(size) ] for j in range(size) ]<EOL>for i in range(size):<EOL><INDENT>for j in range(i, size, <NUM_LIT:1>):<EOL><INDENT>dist = euclidean_distance_square(location[i], location[j])<EOL>sqrt_distances[i][j] = dist<EOL>sqrt_distances[j][i] = dist<EOL><DEDENT><DEDENT>return sqrt_distances<EOL>

!
        @brief Initialize distance matrix in SOM grid.

        @param[in] size (uint): Amount of neurons in the network.
        @param[in] location (list): List of coordinates of each neuron in the network.

        @return (list) Distance matrix between neurons in the network.


dim_info = dimension_info(self._data)<EOL>step_x = dim_info.get_center()[<NUM_LIT:0>]<EOL>if self._rows > <NUM_LIT:1>: step_x = dim_info.get_width()[<NUM_LIT:0>] / (self._rows - <NUM_LIT:1>);<EOL>step_y = <NUM_LIT:0.0><EOL>if dim_info.get_dimensions() > <NUM_LIT:1>:<EOL><INDENT>step_y = dim_info.get_center()[<NUM_LIT:1>]<EOL>if self._cols > <NUM_LIT:1>: step_y = dim_info.get_width()[<NUM_LIT:1>] / (self._cols - <NUM_LIT:1>);<EOL><DEDENT>random.seed()<EOL>if init_type == type_init.uniform_grid:<EOL><INDENT>self._weights = [ [ [] for i in range(dim_info.get_dimensions()) ] for j in range(self._size)]<EOL>for i in range(self._size):<EOL><INDENT>location = self._location[i]<EOL>for dim in range(dim_info.get_dimensions()):<EOL><INDENT>if dim == <NUM_LIT:0>:<EOL><INDENT>if self._rows > <NUM_LIT:1>:<EOL><INDENT>self._weights[i][dim] = dim_info.get_minimum_coordinate()[dim] + step_x * location[dim]<EOL><DEDENT>else:<EOL><INDENT>self._weights[i][dim] = dim_info.get_center()[dim]<EOL><DEDENT><DEDENT>elif dim == <NUM_LIT:1>:<EOL><INDENT>if self._cols > <NUM_LIT:1>:<EOL><INDENT>self._weights[i][dim] = dim_info.get_minimum_coordinate()[dim] + step_y * location[dim]<EOL><DEDENT>else:<EOL><INDENT>self._weights[i][dim] = dim_info.get_center()[dim]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._weights[i][dim] = dim_info.get_center()[dim]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif init_type == type_init.random_surface:<EOL><INDENT>self._weights = [[random.uniform(dim_info.get_minimum_coordinate()[i], dim_info.get_maximum_coordinate()[i]) for i in range(dim_info.get_dimensions())] for _ in range(self._size)]<EOL><DEDENT>elif init_type == type_init.random_centroid:<EOL><INDENT>self._weights = [[(random.random() + dim_info.get_center()[i])  for i in range(dim_info.get_dimensions())] for _ in range(self._size)]<EOL><DEDENT>else:<EOL><INDENT>self._weights = [[random.random() for i in range(dim_info.get_dimensions())] for _ in range(self._size)]<EOL><DEDENT>

!
        @brief Creates initial weights for neurons in line with the specified initialization.

        @param[in] init_type (type_init): Type of initialization of initial neuron weights (random, random in center of the input data, random distributed in data, ditributed in line with uniform grid).


self._neighbors = [[] for index in range(self._size)]<EOL>for index in range(<NUM_LIT:0>, self._size, <NUM_LIT:1>):<EOL><INDENT>upper_index = index - self._cols<EOL>upper_left_index = index - self._cols - <NUM_LIT:1><EOL>upper_right_index = index - self._cols + <NUM_LIT:1><EOL>lower_index = index + self._cols<EOL>lower_left_index = index + self._cols - <NUM_LIT:1><EOL>lower_right_index = index + self._cols + <NUM_LIT:1><EOL>left_index = index - <NUM_LIT:1><EOL>right_index = index + <NUM_LIT:1><EOL>node_row_index = math.floor(index / self._cols)<EOL>upper_row_index = node_row_index - <NUM_LIT:1><EOL>lower_row_index = node_row_index + <NUM_LIT:1><EOL>if (conn_type == type_conn.grid_eight) or (conn_type == type_conn.grid_four):<EOL><INDENT>if upper_index >= <NUM_LIT:0>:<EOL><INDENT>self._neighbors[index].append(upper_index)<EOL><DEDENT>if lower_index < self._size:<EOL><INDENT>self._neighbors[index].append(lower_index)<EOL><DEDENT><DEDENT>if (conn_type == type_conn.grid_eight) or (conn_type == type_conn.grid_four) or (conn_type == type_conn.honeycomb):<EOL><INDENT>if (left_index >= <NUM_LIT:0>) and (math.floor(left_index / self._cols) == node_row_index):<EOL><INDENT>self._neighbors[index].append(left_index)<EOL><DEDENT>if (right_index < self._size) and (math.floor(right_index / self._cols) == node_row_index):<EOL><INDENT>self._neighbors[index].append(right_index)<EOL><DEDENT><DEDENT>if conn_type == type_conn.grid_eight:<EOL><INDENT>if (upper_left_index >= <NUM_LIT:0>) and (math.floor(upper_left_index / self._cols) == upper_row_index):<EOL><INDENT>self._neighbors[index].append(upper_left_index)<EOL><DEDENT>if (upper_right_index >= <NUM_LIT:0>) and (math.floor(upper_right_index / self._cols) == upper_row_index):<EOL><INDENT>self._neighbors[index].append(upper_right_index)<EOL><DEDENT>if (lower_left_index < self._size) and (math.floor(lower_left_index / self._cols) == lower_row_index):<EOL><INDENT>self._neighbors[index].append(lower_left_index)<EOL><DEDENT>if (lower_right_index < self._size) and (math.floor(lower_right_index / self._cols) == lower_row_index):<EOL><INDENT>self._neighbors[index].append(lower_right_index)<EOL><DEDENT><DEDENT>if conn_type == type_conn.honeycomb:<EOL><INDENT>if (node_row_index % <NUM_LIT:2>) == <NUM_LIT:0>:<EOL><INDENT>upper_left_index = index - self._cols<EOL>upper_right_index = index - self._cols + <NUM_LIT:1><EOL>lower_left_index = index + self._cols<EOL>lower_right_index = index + self._cols + <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>upper_left_index = index - self._cols - <NUM_LIT:1><EOL>upper_right_index = index - self._cols<EOL>lower_left_index = index + self._cols - <NUM_LIT:1><EOL>lower_right_index = index + self._cols<EOL><DEDENT>if (upper_left_index >= <NUM_LIT:0>) and (math.floor(upper_left_index / self._cols) == upper_row_index):<EOL><INDENT>self._neighbors[index].append(upper_left_index)<EOL><DEDENT>if (upper_right_index >= <NUM_LIT:0>) and (math.floor(upper_right_index / self._cols) == upper_row_index):<EOL><INDENT>self._neighbors[index].append(upper_right_index)<EOL><DEDENT>if (lower_left_index < self._size) and (math.floor(lower_left_index / self._cols) == lower_row_index):<EOL><INDENT>self._neighbors[index].append(lower_left_index)<EOL><DEDENT>if (lower_right_index < self._size) and (math.floor(lower_right_index / self._cols) == lower_row_index):<EOL><INDENT>self._neighbors[index].append(lower_right_index)<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Create connections in line with input rule (grid four, grid eight, honeycomb, function neighbour).

        @param[in] conn_type (type_conn): Type of connection between oscillators in the network.


index = <NUM_LIT:0><EOL>minimum = euclidean_distance_square(self._weights[<NUM_LIT:0>], x)<EOL>for i in range(<NUM_LIT:1>, self._size, <NUM_LIT:1>):<EOL><INDENT>candidate = euclidean_distance_square(self._weights[i], x)<EOL>if candidate < minimum:<EOL><INDENT>index = i<EOL>minimum = candidate<EOL><DEDENT><DEDENT>return index<EOL>

!
        @brief Calculates neuron winner (distance, neuron index).

        @param[in] x (list): Input pattern from the input data set, for example it can be coordinates of point.

        @return (uint) Returns index of neuron that is winner.


dimension = len(self._weights[<NUM_LIT:0>])<EOL>if self._conn_type == type_conn.func_neighbor:<EOL><INDENT>for neuron_index in range(self._size):<EOL><INDENT>distance = self._sqrt_distances[index][neuron_index]<EOL>if distance < self._local_radius:<EOL><INDENT>influence = math.exp(-(distance / (<NUM_LIT> * self._local_radius)))<EOL>for i in range(dimension):<EOL><INDENT>self._weights[neuron_index][i] = self._weights[neuron_index][i] + self._learn_rate * influence * (x[i] - self._weights[neuron_index][i])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for i in range(dimension):<EOL><INDENT>self._weights[index][i] = self._weights[index][i] + self._learn_rate * (x[i] - self._weights[index][i])<EOL><DEDENT>for neighbor_index in self._neighbors[index]: <EOL><INDENT>distance = self._sqrt_distances[index][neighbor_index]<EOL>if distance < self._local_radius:<EOL><INDENT>influence = math.exp(-(distance / (<NUM_LIT> * self._local_radius)))<EOL>for i in range(dimension):       <EOL><INDENT>self._weights[neighbor_index][i] = self._weights[neighbor_index][i] + self._learn_rate * influence * (x[i] - self._weights[neighbor_index][i])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

!
        @brief Change weight of neurons in line with won neuron.

        @param[in] index (uint): Index of neuron-winner.
        @param[in] x (list): Input pattern from the input data set.


def train(self, data, epochs, autostop=False):

self._data = data<EOL>if self.__ccore_som_pointer is not None:<EOL><INDENT>return wrapper.som_train(self.__ccore_som_pointer, data, epochs, autostop)<EOL><DEDENT>self._sqrt_distances = self.__initialize_distances(self._size, self._location)<EOL>for i in range(self._size):<EOL><INDENT>self._award[i] = <NUM_LIT:0><EOL>self._capture_objects[i].clear()<EOL><DEDENT>self._create_initial_weights(self._params.init_type)<EOL>previous_weights = None<EOL>for epoch in range(<NUM_LIT:1>, epochs + <NUM_LIT:1>):<EOL><INDENT>self._local_radius = (self._params.init_radius * math.exp(-(epoch / epochs))) ** <NUM_LIT:2><EOL>self._learn_rate = self._params.init_learn_rate * math.exp(-(epoch / epochs))<EOL>if autostop:<EOL><INDENT>for i in range(self._size):<EOL><INDENT>self._award[i] = <NUM_LIT:0><EOL>self._capture_objects[i].clear()<EOL><DEDENT><DEDENT>for i in range(len(self._data)):<EOL><INDENT>index = self._competition(self._data[i])<EOL>self._adaptation(index, self._data[i])<EOL>if (autostop == True) or (epoch == epochs):<EOL><INDENT>self._award[index] += <NUM_LIT:1><EOL>self._capture_objects[index].append(i)<EOL><DEDENT><DEDENT>if autostop:<EOL><INDENT>if previous_weights is not None:<EOL><INDENT>maximal_adaptation = self._get_maximal_adaptation(previous_weights)<EOL>if maximal_adaptation < self._params.adaptation_threshold:<EOL><INDENT>return epoch<EOL><DEDENT><DEDENT>previous_weights = [item[:] for item in self._weights]<EOL><DEDENT><DEDENT>return epochs<EOL>

!
        @brief Trains self-organized feature map (SOM).

        @param[in] data (list): Input data - list of points where each point is represented by list of features, for example coordinates.
        @param[in] epochs (uint): Number of epochs for training.
        @param[in] autostop (bool): Automatic termination of learining process when adaptation is not occurred.

        @return (uint) Number of learining iterations.


if self.__ccore_som_pointer is not None:<EOL><INDENT>return wrapper.som_simulate(self.__ccore_som_pointer, input_pattern)<EOL><DEDENT>return self._competition(input_pattern)<EOL>

!
        @brief Processes input pattern (no learining) and returns index of neuron-winner.
               Using index of neuron winner catched object can be obtained using property capture_objects.

        @param[in] input_pattern (list): Input pattern.

        @return (uint) Returns index of neuron-winner.

        @see capture_objects


dimension = len(self._data[<NUM_LIT:0>])<EOL>maximal_adaptation = <NUM_LIT:0.0><EOL>for neuron_index in range(self._size):<EOL><INDENT>for dim in range(dimension):<EOL><INDENT>current_adaptation = previous_weights[neuron_index][dim] - self._weights[neuron_index][dim]<EOL>if current_adaptation < <NUM_LIT:0>:<EOL><INDENT>current_adaptation = -current_adaptation<EOL><DEDENT>if maximal_adaptation < current_adaptation:<EOL><INDENT>maximal_adaptation = current_adaptation<EOL><DEDENT><DEDENT><DEDENT>return maximal_adaptation<EOL>

!
        @brief Calculates maximum changes of weight in line with comparison between previous weights and current weights.

        @param[in] previous_weights (list): Weights from the previous step of learning process.

        @return (double) Value that represents maximum changes of weight after adaptation process.


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._award = wrapper.som_get_awards(self.__ccore_som_pointer)<EOL><DEDENT>winner_number = <NUM_LIT:0><EOL>for i in range(self._size):<EOL><INDENT>if self._award[i] > <NUM_LIT:0>:<EOL><INDENT>winner_number += <NUM_LIT:1><EOL><DEDENT><DEDENT>return winner_number<EOL>

!
        @brief Calculates number of winner at the last step of learning process.

        @return (uint) Number of winner.


distance_matrix = self.get_distance_matrix()<EOL>plt.imshow(distance_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT>')<EOL>plt.title("<STR_LIT>")<EOL>plt.colorbar()<EOL>plt.show()<EOL>

!
        @brief Shows gray visualization of U-matrix (distance matrix).

        @see get_distance_matrix()


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._weights = wrapper.som_get_weights(self.__ccore_som_pointer)<EOL>if self._conn_type != type_conn.func_neighbor:<EOL><INDENT>self._neighbors = wrapper.som_get_neighbors(self.__ccore_som_pointer)<EOL><DEDENT><DEDENT>distance_matrix = [[<NUM_LIT:0.0>] * self._cols for i in range(self._rows)]<EOL>for i in range(self._rows):<EOL><INDENT>for j in range(self._cols):<EOL><INDENT>neuron_index = i * self._cols + j<EOL>if self._conn_type == type_conn.func_neighbor:<EOL><INDENT>self._create_connections(type_conn.grid_eight)<EOL><DEDENT>for neighbor_index in self._neighbors[neuron_index]:<EOL><INDENT>distance_matrix[i][j] += euclidean_distance_square(self._weights[neuron_index], self._weights[neighbor_index])<EOL><DEDENT>distance_matrix[i][j] /= len(self._neighbors[neuron_index])<EOL><DEDENT><DEDENT>return distance_matrix<EOL>

!
        @brief Calculates distance matrix (U-matrix).
        @details The U-Matrix visualizes based on the distance in input space between a weight vector and its neighbors on map.

        @return (list) Distance matrix (U-matrix).

        @see show_distance_matrix()
        @see get_density_matrix()


def show_density_matrix(self, surface_divider = <NUM_LIT>):

density_matrix = self.get_density_matrix(surface_divider)<EOL>plt.imshow(density_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT>')<EOL>plt.title("<STR_LIT>")<EOL>plt.colorbar()<EOL>plt.show()<EOL>

!
        @brief Show density matrix (P-matrix) using kernel density estimation.

        @param[in] surface_divider (double): Divider in each dimension that affect radius for density measurement.

        @see show_distance_matrix()


def get_density_matrix(self, surface_divider = <NUM_LIT>):

if self.__ccore_som_pointer is not None:<EOL><INDENT>self._weights = wrapper.som_get_weights(self.__ccore_som_pointer)<EOL><DEDENT>density_matrix = [[<NUM_LIT:0>] * self._cols for i in range(self._rows)]<EOL>dimension = len(self._weights[<NUM_LIT:0>])<EOL>dim_max = [ float('<STR_LIT>') ] * dimension<EOL>dim_min = [ float('<STR_LIT>') ] * dimension<EOL>for weight in self._weights:<EOL><INDENT>for index_dim in range(dimension):<EOL><INDENT>if weight[index_dim] > dim_max[index_dim]:<EOL><INDENT>dim_max[index_dim] = weight[index_dim]<EOL><DEDENT>if weight[index_dim] < dim_min[index_dim]:<EOL><INDENT>dim_min[index_dim] = weight[index_dim]<EOL><DEDENT><DEDENT><DEDENT>radius = [<NUM_LIT:0.0>] * len(self._weights[<NUM_LIT:0>])<EOL>for index_dim in range(dimension):<EOL><INDENT>radius[index_dim] = ( dim_max[index_dim] - dim_min[index_dim] ) / surface_divider<EOL><DEDENT>for point in self._data:<EOL><INDENT>for index_neuron in range(len(self)):<EOL><INDENT>point_covered = True<EOL>for index_dim in range(dimension):<EOL><INDENT>if abs(point[index_dim] - self._weights[index_neuron][index_dim]) > radius[index_dim]:<EOL><INDENT>point_covered = False<EOL>break<EOL><DEDENT><DEDENT>row = int(math.floor(index_neuron / self._cols))<EOL>col = index_neuron - row * self._cols<EOL>if point_covered is True:<EOL><INDENT>density_matrix[row][col] += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>return density_matrix<EOL>

!
        @brief Calculates density matrix (P-Matrix).

        @param[in] surface_divider (double): Divider in each dimension that affect radius for density measurement.

        @return (list) Density matrix (P-Matrix).

        @see get_distance_matrix()


if self.__ccore_som_pointer is not None:<EOL><INDENT>self._award = wrapper.som_get_awards(self.__ccore_som_pointer)<EOL><DEDENT>(fig, ax) = plt.subplots()<EOL>winner_matrix = [[<NUM_LIT:0>] * self._cols for i in range(self._rows)]<EOL>for i in range(self._rows):<EOL><INDENT>for j in range(self._cols):<EOL><INDENT>neuron_index = i * self._cols + j<EOL>winner_matrix[i][j] = self._award[neuron_index]<EOL>ax.text(i, j, str(winner_matrix[i][j]), va='<STR_LIT>', ha='<STR_LIT>')<EOL><DEDENT><DEDENT>ax.imshow(winner_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT:none>')<EOL>ax.grid(True)<EOL>plt.title("<STR_LIT>")<EOL>plt.show()<EOL>

!
        @brief Show winner matrix where each element corresponds to neuron and value represents
               amount of won objects from input dataspace at the last training iteration.

        @see show_distance_matrix()


def show_network(self, awards = False, belongs = False, coupling = True, dataset = True, marker_type = '<STR_LIT:o>'):

if self.__ccore_som_pointer is not None:<EOL><INDENT>self._size = wrapper.som_get_size(self.__ccore_som_pointer)<EOL>self._weights = wrapper.som_get_weights(self.__ccore_som_pointer)<EOL>self._neighbors = wrapper.som_get_neighbors(self.__ccore_som_pointer)<EOL>self._award = wrapper.som_get_awards(self.__ccore_som_pointer)<EOL><DEDENT>dimension = len(self._weights[<NUM_LIT:0>])<EOL>fig = plt.figure()<EOL>if (dimension == <NUM_LIT:1>) or (dimension == <NUM_LIT:2>):<EOL><INDENT>axes = fig.add_subplot(<NUM_LIT>)<EOL><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>axes = fig.gca(projection='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError('<STR_LIT>')<EOL><DEDENT>if (self._data is not None) and (dataset is True):<EOL><INDENT>for x in self._data:<EOL><INDENT>if dimension == <NUM_LIT:1>:<EOL><INDENT>axes.plot(x[<NUM_LIT:0>], <NUM_LIT:0.0>, '<STR_LIT>', ms = <NUM_LIT:30>)<EOL><DEDENT>elif dimension == <NUM_LIT:2>:<EOL><INDENT>axes.plot(x[<NUM_LIT:0>], x[<NUM_LIT:1>], '<STR_LIT>')<EOL><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>axes.scatter(x[<NUM_LIT:0>], x[<NUM_LIT:1>], x[<NUM_LIT:2>], c = '<STR_LIT:b>', marker = '<STR_LIT:.>')<EOL><DEDENT><DEDENT><DEDENT>for index in range(self._size):<EOL><INDENT>color = '<STR_LIT:g>'<EOL>if self._award[index] == <NUM_LIT:0>:<EOL><INDENT>color = '<STR_LIT:y>'<EOL><DEDENT>if dimension == <NUM_LIT:1>:<EOL><INDENT>axes.plot(self._weights[index][<NUM_LIT:0>], <NUM_LIT:0.0>, color + marker_type)<EOL>if awards:<EOL><INDENT>location = '<STR_LIT>'.format(self._award[index])<EOL>axes.text(self._weights[index][<NUM_LIT:0>], <NUM_LIT:0.0>, location, color='<STR_LIT>', fontsize = <NUM_LIT:10>)<EOL><DEDENT>if belongs and self._data is not None:<EOL><INDENT>location = '<STR_LIT>'.format(index)<EOL>axes.text(self._weights[index][<NUM_LIT:0>], <NUM_LIT:0.0>, location, color='<STR_LIT>', fontsize = <NUM_LIT:12>)<EOL>for k in range(len(self._capture_objects[index])):<EOL><INDENT>point = self._data[self._capture_objects[index][k]]<EOL>axes.text(point[<NUM_LIT:0>], <NUM_LIT:0.0>, location, color='<STR_LIT>', fontsize = <NUM_LIT:10>)<EOL><DEDENT><DEDENT><DEDENT>if dimension == <NUM_LIT:2>:<EOL><INDENT>axes.plot(self._weights[index][<NUM_LIT:0>], self._weights[index][<NUM_LIT:1>], color + marker_type)<EOL>if awards:<EOL><INDENT>location = '<STR_LIT>'.format(self._award[index])<EOL>axes.text(self._weights[index][<NUM_LIT:0>], self._weights[index][<NUM_LIT:1>], location, color='<STR_LIT>', fontsize=<NUM_LIT:10>)<EOL><DEDENT>if belongs and self._data is not None:<EOL><INDENT>location = '<STR_LIT>'.format(index)<EOL>axes.text(self._weights[index][<NUM_LIT:0>], self._weights[index][<NUM_LIT:1>], location, color='<STR_LIT>', fontsize=<NUM_LIT:12>)<EOL>for k in range(len(self._capture_objects[index])):<EOL><INDENT>point = self._data[self._capture_objects[index][k]]<EOL>axes.text(point[<NUM_LIT:0>], point[<NUM_LIT:1>], location, color='<STR_LIT>', fontsize=<NUM_LIT:10>)<EOL><DEDENT><DEDENT>if (self._conn_type != type_conn.func_neighbor) and (coupling != False):<EOL><INDENT>for neighbor in self._neighbors[index]:<EOL><INDENT>if neighbor > index:<EOL><INDENT>axes.plot([self._weights[index][<NUM_LIT:0>], self._weights[neighbor][<NUM_LIT:0>]],<EOL>[self._weights[index][<NUM_LIT:1>], self._weights[neighbor][<NUM_LIT:1>]],<EOL>'<STR_LIT:g>', linewidth=<NUM_LIT:0.5>)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>axes.scatter(self._weights[index][<NUM_LIT:0>], self._weights[index][<NUM_LIT:1>], self._weights[index][<NUM_LIT:2>], c=color, marker=marker_type)<EOL>if (self._conn_type != type_conn.func_neighbor) and (coupling != False):<EOL><INDENT>for neighbor in self._neighbors[index]:<EOL><INDENT>if neighbor > index:<EOL><INDENT>axes.plot([self._weights[index][<NUM_LIT:0>], self._weights[neighbor][<NUM_LIT:0>]],<EOL>[self._weights[index][<NUM_LIT:1>], self._weights[neighbor][<NUM_LIT:1>]],<EOL>[self._weights[index][<NUM_LIT:2>], self._weights[neighbor][<NUM_LIT:2>]],<EOL>'<STR_LIT>', linewidth=<NUM_LIT:0.5>)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>plt.title("<STR_LIT>")<EOL>plt.grid()<EOL>plt.show()<EOL>

!
        @brief Shows neurons in the dimension of data.

        @param[in] awards (bool): If True - displays how many objects won each neuron.
        @param[in] belongs (bool): If True - marks each won object by according index of neuron-winner (only when dataset is displayed too).
        @param[in] coupling (bool): If True - displays connections between neurons (except case when function neighbor is used).
        @param[in] dataset (bool): If True - displays inputs data set.
        @param[in] marker_type (string): Defines marker that is used for dispaying neurons in the network.


parameters = legion_parameters();<EOL>parameters.eps = <NUM_LIT>;<EOL>parameters.alpha = <NUM_LIT>;<EOL>parameters.betta = <NUM_LIT:0.1>;<EOL>parameters.gamma = <NUM_LIT>;<EOL>parameters.teta = <NUM_LIT>;<EOL>parameters.lamda = <NUM_LIT:0.1>;<EOL>parameters.teta_x = -<NUM_LIT:0.5>;<EOL>parameters.teta_p = <NUM_LIT>;<EOL>parameters.Wz = <NUM_LIT>;<EOL>parameters.mu = <NUM_LIT>;<EOL>parameters.fi = <NUM_LIT>;<EOL>parameters.teta_xz = <NUM_LIT:0.1>;<EOL>parameters.teta_zx = <NUM_LIT:0.1>;<EOL>parameters.ENABLE_POTENTIONAL = False;<EOL>template_segmentation_image(IMAGE_SIMPLE_SAMPLES.IMAGE_SIMPLE12, parameters, <NUM_LIT>, <NUM_LIT>, True)<EOL>


images = [];<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_M;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_I;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_N;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_D;<EOL>template_recognition_image(images, <NUM_LIT:100>, <NUM_LIT:10>, <NUM_LIT>)<EOL>

!
    @brief Trains network using letters 'M', 'I', 'N', 'D' and recognize each of them with and without noise.


images = [];<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_A;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_B;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_C;<EOL>template_recognition_image(images, <NUM_LIT>, <NUM_LIT>)<EOL>

!
    @brief Trains network using letters 'A', 'B', 'C', and recognize each of them with and without noise.


images = [];<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_F;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_T;<EOL>images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_K;<EOL>template_recognition_image(images, <NUM_LIT:100>, <NUM_LIT:10>, <NUM_LIT>)<EOL>

!
    @brief Trains network using letters 'F', 'T', 'K' and recognize each of them with and without noise.


template_dynamic(<NUM_LIT:2>, -<NUM_LIT:4>, <NUM_LIT:1>, [<NUM_LIT:1>, <NUM_LIT:0>], [<NUM_LIT:1>, <NUM_LIT:1>])<EOL>

Comment: Different initial state - state of sync. will be reached.


template_dynamic(<NUM_LIT:2>, -<NUM_LIT:4>, -<NUM_LIT:1>, [<NUM_LIT:1>, <NUM_LIT:0>], [<NUM_LIT:1>, <NUM_LIT:1>])<EOL>

Note: if initial state is the same for both oscillators then desync. will not be exist. It is very important to set different values if desync. is required.


template_dynamic(<NUM_LIT:5>, -<NUM_LIT:4>, <NUM_LIT:1>, [<NUM_LIT:1>, <NUM_LIT:0.5>, <NUM_LIT:0>, -<NUM_LIT:0.5>, -<NUM_LIT:1>], [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>]);<EOL>template_dynamic(<NUM_LIT:5>, -<NUM_LIT:4>, <NUM_LIT:1>, [<NUM_LIT:1>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>], [-<NUM_LIT:1>, -<NUM_LIT:1>, -<NUM_LIT:1>, -<NUM_LIT:1>, -<NUM_LIT:1>])<EOL>

Note: Oscillations are dead in this case (sync. should be in ideal case)


template_dynamic(<NUM_LIT:5>, -<NUM_LIT:4>, -<NUM_LIT:1>, [<NUM_LIT:1>, <NUM_LIT:0.5>, <NUM_LIT:0>, -<NUM_LIT:0.5>, -<NUM_LIT:1>], [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>])<EOL>


template_dynamic_sync(<NUM_LIT:10>, -<NUM_LIT:3>)<EOL>

Comment: It is not full desynchronization


_ = template_dynamic_sync(<NUM_LIT:9>, -<NUM_LIT:2>, conn = conn_type.GRID_FOUR)<EOL>


_ = template_dynamic_sync(<NUM_LIT:16>, -<NUM_LIT:3>, conn = conn_type.GRID_FOUR)<EOL>


"<STR_LIT>"<EOL>parameters = legion_parameters();<EOL>parameters.Wt = <NUM_LIT>;<EOL>parameters.fi = <NUM_LIT>;<EOL>template_dynamic_legion(<NUM_LIT:15>, <NUM_LIT:1000>, <NUM_LIT:1000>, conn_type = conn_type.LIST_BIDIR, stimulus = [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>], params = parameters, separate_repr = [ [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>], [<NUM_LIT:3>, <NUM_LIT:4>, <NUM_LIT:5>, <NUM_LIT:9>, <NUM_LIT:10>], [<NUM_LIT:6>, <NUM_LIT:7>, <NUM_LIT:8>], [<NUM_LIT:11>, <NUM_LIT:12>, <NUM_LIT>, <NUM_LIT>] ])<EOL>

Good example of three synchronous ensembels


"<STR_LIT>"<EOL>parameters = legion_parameters();<EOL>parameters.Wt = <NUM_LIT>;<EOL>parameters.fi = <NUM_LIT>;<EOL>parameters.ENABLE_POTENTIONAL = False;<EOL>template_dynamic_legion(<NUM_LIT:15>, <NUM_LIT:1000>, <NUM_LIT:1000>, conn_type = conn_type.LIST_BIDIR, <EOL>stimulus = [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>], <EOL>params = parameters, <EOL>separate_repr = [ [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>], [<NUM_LIT:3>, <NUM_LIT:4>, <NUM_LIT:5>, <NUM_LIT:9>, <NUM_LIT:10>], [<NUM_LIT:6>, <NUM_LIT:7>, <NUM_LIT:8>], [<NUM_LIT:11>, <NUM_LIT:12>, <NUM_LIT>, <NUM_LIT>] ])<EOL>


parameters = legion_parameters();<EOL>parameters.teta_x = -<NUM_LIT>;<EOL>template_dynamic_legion(<NUM_LIT:16>, <NUM_LIT>, <NUM_LIT>, conn_type = conn_type.GRID_FOUR, params = parameters, stimulus = [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>])<EOL>

Not accurate false due to spikes are observed


parameters = legion_parameters();<EOL>parameters.eps = <NUM_LIT>;<EOL>parameters.alpha = <NUM_LIT>;<EOL>parameters.betta = <NUM_LIT:0.1>;<EOL>parameters.gamma = <NUM_LIT>;<EOL>parameters.teta = <NUM_LIT>;<EOL>parameters.lamda = <NUM_LIT:0.1>;<EOL>parameters.teta_x = -<NUM_LIT:0.5>;<EOL>parameters.teta_p = <NUM_LIT>;<EOL>parameters.Wz = <NUM_LIT>;<EOL>parameters.mu = <NUM_LIT>;<EOL>parameters.fi = <NUM_LIT>;<EOL>parameters.teta_xz = <NUM_LIT:0.1>;<EOL>parameters.teta_zx = <NUM_LIT:0.1>;<EOL>parameters.ENABLE_POTENTIONAL = False;<EOL>template_dynamic_legion(<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <EOL>conn_type = conn_type.GRID_FOUR, <EOL>params = parameters, <EOL>stimulus = [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>,<EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>,<EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>],<EOL>separate_repr = [ [<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:9>, <NUM_LIT:10>, <NUM_LIT:11>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT:20>], <EOL>[<NUM_LIT>, <NUM_LIT:15>, <NUM_LIT:16>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>], <EOL>[<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT:64>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>] ])<EOL>


params = pcnn_parameters();<EOL>template_dynamic_pcnn(<NUM_LIT:9>, <NUM_LIT:100>, [<NUM_LIT:1.0>] * <NUM_LIT:9>, params, conn_type.GRID_FOUR)<EOL>


template_dynamic_pcnn(<NUM_LIT:9>, <NUM_LIT:100>, [<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <EOL><NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>], None, conn_type.GRID_FOUR)<EOL>


"<STR_LIT>"<EOL>params = pcnn_parameters();<EOL>params.AF = <NUM_LIT:0.1>;<EOL>params.AL = <NUM_LIT:0.0>;<EOL>params.AT = <NUM_LIT>;<EOL>params.VF = <NUM_LIT:1.0>;<EOL>params.VL = <NUM_LIT:1.0>;<EOL>params.VT = <NUM_LIT>;<EOL>params.M = <NUM_LIT:0.0>;<EOL>template_dynamic_pcnn(<NUM_LIT>, <NUM_LIT:100>, [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>], params, conn_type.GRID_FOUR, False)<EOL>


params = pcnn_parameters();<EOL>params.AF = <NUM_LIT:0.1>;<EOL>params.AL = <NUM_LIT:0.1>;<EOL>params.AT = <NUM_LIT>;<EOL>params.VF = <NUM_LIT:1.0>;<EOL>params.VL = <NUM_LIT:1.0>;<EOL>params.VT = <NUM_LIT>;<EOL>params.W = <NUM_LIT:1.0>;<EOL>params.M = <NUM_LIT:1.0>;<EOL>template_dynamic_pcnn(<NUM_LIT:100>, <NUM_LIT:50>,  [<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>,<EOL><NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>], params, conn_type.GRID_EIGHT, False)<EOL>

Allocate several clusters: the first contains borders (indexes of oscillators) and the second objects (indexes of oscillators)


template_segmentation_image(IMAGE_SIMPLE_SAMPLES.IMAGE_SIMPLE_BUILDING, None, <NUM_LIT>, None, True, False, True)<EOL>


return self.__height<EOL>

!
        @brief Height of the network grid (that is defined by amout of oscillators in each column), this value is zero in case of non-grid structure.

        @note This property returns valid value only for network with grid structure.


return self.__width<EOL>

!
        @brief Width of the network grid, this value is zero in case of non-grid structure.

        @note This property returns valid value only for network with grid structure.


return self.__conn_type<EOL>

!
        @brief Type of network structure that is used for connecting oscillators.


def __init__(self, num_osc, type_conn = conn_type.ALL_TO_ALL, conn_repr = conn_represent.MATRIX, height = None, width = None):

self._num_osc = num_osc;<EOL>self._conn_represent = conn_repr;<EOL>self.__conn_type = type_conn;<EOL>if (conn_repr is None):<EOL><INDENT>self._conn_represent = conn_represent.MATRIX;<EOL><DEDENT>if ( (type_conn == conn_type.GRID_EIGHT) or (type_conn == conn_type.GRID_FOUR) ):<EOL><INDENT>if ( (height is not None) and (width is not None) ):<EOL><INDENT>self.__height = height;<EOL>self.__width = width;<EOL><DEDENT>else:<EOL><INDENT>side_size = self._num_osc ** (<NUM_LIT:0.5>);<EOL>if (side_size - math.floor(side_size) > <NUM_LIT:0>):<EOL><INDENT>raise NameError("<STR_LIT>" + str(num_osc) + "<STR_LIT>");<EOL><DEDENT>self.__height = int(side_size);<EOL>self.__width = self.__height;<EOL><DEDENT>if (self.__height * self.__width != self._num_osc):<EOL><INDENT>raise NameError('<STR_LIT>' + str(self.__width) + '<STR_LIT>' + str(self.__height) + '<STR_LIT>' + str(self._num_osc) + '<STR_LIT>');<EOL><DEDENT><DEDENT>self._create_structure(type_conn)<EOL>

!
        @brief Constructor of the network.

        @param[in] num_osc (uint): Number of oscillators in the network that defines size of the network.
        @param[in] type_conn (conn_type): Type of connections that are used in the network between oscillators.
        @param[in] conn_repr (conn_represent): Type of representation of connections.
        @param[in] height (uint): Number of oscillators in column of the network, this argument is used
                    only for network with grid structure (GRID_FOUR, GRID_EIGHT), for other types this argument is ignored.
        @param[in] width (uint): Number of oscillotors in row of the network, this argument is used only
                    for network with grid structure (GRID_FOUR, GRID_EIGHT), for other types this argument is ignored.


return self._num_osc<EOL>

!
        @brief Returns size of the network that is defined by amount of oscillators.


if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._osc_conn.append([True] * self._num_osc);<EOL>self._osc_conn[index][index] = False;<EOL><DEDENT><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._osc_conn.append([neigh for neigh in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>) if index != neigh]);<EOL><DEDENT><DEDENT>

!
        @brief Creates connections between all oscillators.


side_size = self.__width;<EOL>if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>self._osc_conn = [[<NUM_LIT:0>] * self._num_osc for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>)];<EOL><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>self._osc_conn = [[] for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>)];<EOL><DEDENT>else:<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>upper_index = index - side_size;<EOL>lower_index = index + side_size;<EOL>left_index = index - <NUM_LIT:1>;<EOL>right_index = index + <NUM_LIT:1>;<EOL>node_row_index = math.ceil(index / side_size);<EOL>if (upper_index >= <NUM_LIT:0>):<EOL><INDENT>self.__create_connection(index, upper_index);<EOL><DEDENT>if (lower_index < self._num_osc):<EOL><INDENT>self.__create_connection(index, lower_index);<EOL><DEDENT>if ( (left_index >= <NUM_LIT:0>) and (math.ceil(left_index / side_size) == node_row_index) ):<EOL><INDENT>self.__create_connection(index, left_index);<EOL><DEDENT>if ( (right_index < self._num_osc) and (math.ceil(right_index / side_size) == node_row_index) ):<EOL><INDENT>self.__create_connection(index, right_index);<EOL><DEDENT><DEDENT>

!
        @brief Creates network with connections that make up four grid structure.
        @details Each oscillator may be connected with four neighbors in line with 'grid' structure: right, upper, left, lower.


self.__create_grid_four_connections();     <EOL>side_size = self.__width;<EOL>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>upper_left_index = index - side_size - <NUM_LIT:1>;<EOL>upper_right_index = index - side_size + <NUM_LIT:1>;<EOL>lower_left_index = index + side_size - <NUM_LIT:1>;<EOL>lower_right_index = index + side_size + <NUM_LIT:1>;<EOL>node_row_index = math.floor(index / side_size);<EOL>upper_row_index = node_row_index - <NUM_LIT:1>;<EOL>lower_row_index = node_row_index + <NUM_LIT:1>;<EOL>if ( (upper_left_index >= <NUM_LIT:0>) and (math.floor(upper_left_index / side_size) == upper_row_index) ):<EOL><INDENT>self.__create_connection(index, upper_left_index);<EOL><DEDENT>if ( (upper_right_index >= <NUM_LIT:0>) and (math.floor(upper_right_index / side_size) == upper_row_index) ):<EOL><INDENT>self.__create_connection(index, upper_right_index);<EOL><DEDENT>if ( (lower_left_index < self._num_osc) and (math.floor(lower_left_index / side_size) == lower_row_index) ):<EOL><INDENT>self.__create_connection(index, lower_left_index);<EOL><DEDENT>if ( (lower_right_index < self._num_osc) and (math.floor(lower_right_index / side_size) == lower_row_index) ):<EOL><INDENT>self.__create_connection(index, lower_right_index);<EOL><DEDENT><DEDENT>

!
        @brief Creates network with connections that make up eight grid structure.
        @details Each oscillator may be connected with eight neighbors in line with grid structure: right, right-upper, upper, upper-left, left, left-lower, lower, lower-right.


if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._osc_conn.append([<NUM_LIT:0>] * self._num_osc);<EOL>self._osc_conn[index][index] = False;<EOL>if (index > <NUM_LIT:0>):<EOL><INDENT>self._osc_conn[index][index - <NUM_LIT:1>] = True;<EOL><DEDENT>if (index < (self._num_osc - <NUM_LIT:1>)):<EOL><INDENT>self._osc_conn[index][index + <NUM_LIT:1>] = True;<EOL><DEDENT><DEDENT><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>for index in range(self._num_osc):<EOL><INDENT>self._osc_conn.append([]);<EOL>if (index > <NUM_LIT:0>):<EOL><INDENT>self._osc_conn[index].append(index - <NUM_LIT:1>);<EOL><DEDENT>if (index < (self._num_osc - <NUM_LIT:1>)):<EOL><INDENT>self._osc_conn[index].append(index + <NUM_LIT:1>);<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Creates network as bidirectional list.
        @details Each oscillator may be conneted with two neighbors in line with classical list structure: right, left.


if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>for _ in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._osc_conn.append([False] * self._num_osc);<EOL><DEDENT><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>self._osc_conn = [[] for _ in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>)];<EOL><DEDENT>

!
        @brief Creates network without connections.


if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>for _ in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._osc_conn.append([False] * self._num_osc);   <EOL><DEDENT><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>self._osc_conn = [[] for _ in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>)];<EOL><DEDENT>

!
        @brief Prepare storage for dynamic connections.


def _create_structure(self, type_conn = conn_type.ALL_TO_ALL):

self._osc_conn = list();<EOL>if (type_conn == conn_type.NONE):<EOL><INDENT>self.__create_none_connections();<EOL><DEDENT>elif (type_conn == conn_type.ALL_TO_ALL):<EOL><INDENT>self.__create_all_to_all_connections();<EOL><DEDENT>elif (type_conn == conn_type.GRID_FOUR):<EOL><INDENT>self.__create_grid_four_connections();<EOL><DEDENT>elif (type_conn == conn_type.GRID_EIGHT):<EOL><INDENT>self.__create_grid_eight_connections();<EOL><DEDENT>elif (type_conn == conn_type.LIST_BIDIR):<EOL><INDENT>self.__create_list_bidir_connections();<EOL><DEDENT>elif (type_conn == conn_type.DYNAMIC):<EOL><INDENT>self.__create_dynamic_connection();<EOL><DEDENT>else:<EOL><INDENT>raise NameError('<STR_LIT>');<EOL><DEDENT>

!
        @brief Creates connection in line with representation of matrix connections [NunOsc x NumOsc].

        @param[in] type_conn (conn_type): Connection type (all-to-all, bidirectional list, grid structure, etc.) that is used by the network.


if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>return (self._osc_conn[i][j]);<EOL><DEDENT>elif (self._conn_represent == conn_represent.LIST):<EOL><INDENT>for neigh_index in range(<NUM_LIT:0>, len(self._osc_conn[i]), <NUM_LIT:1>):<EOL><INDENT>if (self._osc_conn[i][neigh_index] == j):<EOL><INDENT>return True;<EOL><DEDENT><DEDENT>return False;<EOL><DEDENT>else:<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>

!
        @brief Returns True if there is connection between i and j oscillators and False - if connection doesn't exist.

        @param[in] i (uint): index of an oscillator in the network.
        @param[in] j (uint): index of an oscillator in the network.


if (self.structure != conn_type.DYNAMIC):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>if (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>self._osc_conn[i][j] = True;<EOL>self._osc_conn[j][i] = True;<EOL><DEDENT>else:<EOL><INDENT>self._osc_conn[i].append(j);<EOL>self._osc_conn[j].append(i);<EOL><DEDENT>

!
        @brief Couples two specified oscillators in the network with dynamic connections.

        @param[in] i (uint): index of an oscillator that should be coupled with oscillator 'j' in the network.
        @param[in] j (uint): index of an oscillator that should be coupled with oscillator 'i' in the network.

        @note This method can be used only in case of DYNAMIC connections, otherwise it throws expection.


if (self._conn_represent == conn_represent.LIST):<EOL><INDENT>return self._osc_conn[index];      <EOL><DEDENT>elif (self._conn_represent == conn_represent.MATRIX):<EOL><INDENT>return [neigh_index for neigh_index in range(self._num_osc) if self._osc_conn[index][neigh_index] == True];<EOL><DEDENT>else:<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>

!
        @brief Finds neighbors of the oscillator with specified index.

        @param[in] index (uint): index of oscillator for which neighbors should be found in the network.

        @return (list) Indexes of neighbors of the specified oscillator.


<EOL>self.eps         = <NUM_LIT>;<EOL>self.alpha       = <NUM_LIT>;<EOL>self.gamma       = <NUM_LIT>;<EOL>self.betta       = <NUM_LIT:0.1>;<EOL>self.lamda       = <NUM_LIT:0.1>;<EOL>self.teta        = <NUM_LIT>;<EOL>self.teta_x      = -<NUM_LIT>;<EOL>self.teta_p      = <NUM_LIT>;<EOL>self.teta_xz     = <NUM_LIT:0.1>;<EOL>self.teta_zx     = <NUM_LIT:0.1>;<EOL>self.T           = <NUM_LIT>;<EOL>self.mu          = <NUM_LIT>;<EOL>self.Wz          = <NUM_LIT>;<EOL>self.Wt          = <NUM_LIT>;<EOL>self.fi          = <NUM_LIT>;<EOL>self.ro          = <NUM_LIT>;<EOL>self.I           = <NUM_LIT>;<EOL>self.ENABLE_POTENTIONAL = True<EOL>

!
        @brief    Default constructor of parameters for LEGION (local excitatory global inhibitory oscillatory network).
        @details  Constructor initializes parameters by default non-zero values that can be
                  used for simple simulation.


if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>return wrapper.legion_dynamic_get_output(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>return self.__output<EOL>

!
        @brief Returns output dynamic of the network.


if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>return wrapper.legion_dynamic_get_inhibitory_output(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>return self.__inhibitor<EOL>

!
        @brief Returns output dynamic of the global inhibitor of the network.


if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>return wrapper.legion_dynamic_get_time(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>return list(range(len(self)))<EOL>

!
        @brief Returns simulation time.


def __init__(self, output, inhibitor, time, ccore = None):

self.__output = output;<EOL>self.__inhibitor = inhibitor;<EOL>self._time = time;<EOL>self.__ccore_legion_dynamic_pointer = ccore<EOL>

!
        @brief Constructor of legion dynamic.

        @param[in] output (list): Output dynamic of the network represented by excitatory values of oscillators.
        @param[in] inhibitor (list): Output dynamic of the global inhibitor of the network.
        @param[in] time (list): Simulation time.
        @param[in] ccore (POINTER): Pointer to CCORE legion_dynamic. If it is specified then others arguments can be omitted.


if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>wrapper.legion_dynamic_destroy(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>

!
        @brief Destructor of the dynamic of the legion network.


if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>return wrapper.legion_dynamic_get_size(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>return len(self._time)<EOL>

!
        @brief Returns length of output dynamic.


def allocate_sync_ensembles(self, tolerance = <NUM_LIT:0.1>):

if (self.__ccore_legion_dynamic_pointer is not None):<EOL><INDENT>self.__output = wrapper.legion_dynamic_get_output(self.__ccore_legion_dynamic_pointer);<EOL><DEDENT>return allocate_sync_ensembles(self.__output, tolerance)<EOL>

!
        @brief Allocate clusters in line with ensembles of synchronous oscillators where each synchronous ensemble corresponds to only one cluster.

        @param[in] tolerance (double): Maximum error for allocation of synchronous ensemble oscillators.

        @return (list) Grours of indexes of synchronous oscillators, for example, [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].


def __init__(self, num_osc, parameters = None, type_conn = conn_type.ALL_TO_ALL, type_conn_represent = conn_represent.MATRIX, ccore = True):

self._params = None;                 <EOL>self.__ccore_legion_pointer = None;<EOL>self._params = parameters;<EOL>if (self._params is None):<EOL><INDENT>self._params = legion_parameters();<EOL><DEDENT>if ( (ccore is True) and ccore_library.workable() ):<EOL><INDENT>self.__ccore_legion_pointer = wrapper.legion_create(num_osc, type_conn, self._params);<EOL><DEDENT>else: <EOL><INDENT>super().__init__(num_osc, type_conn, type_conn_represent);<EOL>self._excitatory = [ random.random() for _ in range(self._num_osc) ];<EOL>self._inhibitory = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._potential = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._coupling_term = None;      <EOL>self._global_inhibitor = <NUM_LIT:0>;      <EOL>self._stimulus = None;           <EOL>self._dynamic_coupling = None;   <EOL>self._coupling_term = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._buffer_coupling_term = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._noise = [random.random() * self._params.ro for i in range(self._num_osc)];<EOL><DEDENT>

!
        @brief Constructor of oscillatory network LEGION (local excitatory global inhibitory oscillatory network).

        @param[in] num_osc (uint): Number of oscillators in the network.
        @param[in] parameters (legion_parameters): Parameters of the network that are defined by structure 'legion_parameters'.
        @param[in] type_conn (conn_type): Type of connection between oscillators in the network.
        @param[in] type_conn_represent (conn_represent): Internal representation of connection in the network: matrix or list.
        @param[in] ccore (bool): If True then all interaction with object will be performed via CCORE library (C++ implementation of pyclustering).


if (self.__ccore_legion_pointer is not None):<EOL><INDENT>wrapper.legion_destroy(self.__ccore_legion_pointer);<EOL>self.__ccore_legion_pointer = None;<EOL><DEDENT>

!
        @brief Default destructor of LEGION.


if (self.__ccore_legion_pointer is not None):<EOL><INDENT>return wrapper.legion_get_size(self.__ccore_legion_pointer);<EOL><DEDENT>return self._num_osc<EOL>

!
        @brief (uint) Returns size of LEGION.


if (len(stimulus) != self._num_osc):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>else:<EOL><INDENT>self._stimulus = [];<EOL>for val in stimulus:<EOL><INDENT>if (val > <NUM_LIT:0>): self._stimulus.append(self._params.I);<EOL>else: self._stimulus.append(<NUM_LIT:0>);<EOL><DEDENT><DEDENT>

!
        @brief Create stimulus for oscillators in line with stimulus map and parameters.

        @param[in] stimulus (list): Stimulus for oscillators that is represented by list, number of stimulus should be equal number of oscillators.


if (self._stimulus is None):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>self._dynamic_coupling = [ [<NUM_LIT:0>] * self._num_osc for i in range(self._num_osc)];<EOL>for i in range(self._num_osc):<EOL><INDENT>neighbors = self.get_neighbors(i);<EOL>if ( (len(neighbors) > <NUM_LIT:0>) and (self._stimulus[i] > <NUM_LIT:0>) ):<EOL><INDENT>number_stimulated_neighbors = <NUM_LIT:0.0>;<EOL>for j in neighbors:<EOL><INDENT>if (self._stimulus[j] > <NUM_LIT:0>):<EOL><INDENT>number_stimulated_neighbors += <NUM_LIT:1.0>;<EOL><DEDENT><DEDENT>if (number_stimulated_neighbors > <NUM_LIT:0>):<EOL><INDENT>dynamic_weight = self._params.Wt / number_stimulated_neighbors;<EOL>for j in neighbors:<EOL><INDENT>self._dynamic_coupling[i][j] = dynamic_weight;<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

!
        @brief Create dynamic connection in line with input stimulus.


def simulate(self, steps, time, stimulus, solution = solve_type.RK4, collect_dynamic = True):

if (self.__ccore_legion_pointer is not None):<EOL><INDENT>pointer_dynamic = wrapper.legion_simulate(self.__ccore_legion_pointer, steps, time, solution, collect_dynamic, stimulus);<EOL>return legion_dynamic(None, None, None, pointer_dynamic);<EOL><DEDENT>if (solution == solve_type.FAST):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>elif (solution == solve_type.RKF45):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>self.__create_stimulus(stimulus);<EOL>self.__create_dynamic_connections();<EOL>dyn_exc = None;<EOL>dyn_time = None;<EOL>dyn_ginh = None;<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_exc = [];<EOL>dyn_time = [];<EOL>dyn_ginh = [];<EOL><DEDENT>step = time / steps;<EOL>int_step = step / <NUM_LIT>;<EOL>for t in numpy.arange(step, time + step, step):<EOL><INDENT>self._calculate_states(solution, t, step, int_step);<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_exc.append(self._excitatory);<EOL>dyn_time.append(t);<EOL>dyn_ginh.append(self._global_inhibitor);<EOL><DEDENT>else:<EOL><INDENT>dyn_exc = self._excitatory;<EOL>dyn_time = t;<EOL>dyn_ginh = self._global_inhibitor;<EOL><DEDENT><DEDENT>return legion_dynamic(dyn_exc, dyn_ginh, dyn_time)<EOL>

!
        @brief Performs static simulation of LEGION oscillatory network.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] stimulus (list): Stimulus for oscillators, number of stimulus should be equal to number of oscillators,
                   example of stimulus for 5 oscillators [0, 0, 1, 1, 0], value of stimulus is defined by parameter 'I'.
        @param[in] solution (solve_type): Method that is used for differential equation.
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.

        @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time,
                otherwise returns only last values (last step of simulation) of dynamic.


def _calculate_states(self, solution, t, step, int_step):

next_excitatory = [<NUM_LIT:0.0>] * self._num_osc;<EOL>next_inhibitory = [<NUM_LIT:0.0>] * self._num_osc;<EOL>next_potential = [];<EOL>if (self._params.ENABLE_POTENTIONAL is True):<EOL><INDENT>next_potential = [<NUM_LIT:0.0>] * self._num_osc;<EOL><DEDENT>for index in range (<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>if (self._params.ENABLE_POTENTIONAL is True):<EOL><INDENT>result = odeint(self._legion_state, [self._excitatory[index], self._inhibitory[index], self._potential[index]], numpy.arange(t - step, t, int_step), (index , ));<EOL>[ next_excitatory[index], next_inhibitory[index], next_potential[index] ] = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>:<NUM_LIT:3>];<EOL><DEDENT>else:<EOL><INDENT>result = odeint(self._legion_state_simplify, [self._excitatory[index], self._inhibitory[index] ], numpy.arange(t - step, t, int_step), (index , ));<EOL>[ next_excitatory[index], next_inhibitory[index] ] = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>:<NUM_LIT:2>];<EOL><DEDENT>neighbors = self.get_neighbors(index);<EOL>coupling = <NUM_LIT:0><EOL>for index_neighbor in neighbors:<EOL><INDENT>coupling += self._dynamic_coupling[index][index_neighbor] * heaviside(self._excitatory[index_neighbor] - self._params.teta_x);<EOL><DEDENT>self._buffer_coupling_term[index] = coupling - self._params.Wz * heaviside(self._global_inhibitor - self._params.teta_xz);<EOL><DEDENT>result = odeint(self._global_inhibitor_state, self._global_inhibitor, numpy.arange(t - step, t, int_step), (None, ));<EOL>self._global_inhibitor = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>];<EOL>self._noise = [random.random() * self._params.ro for i in range(self._num_osc)];<EOL>self._coupling_term = self._buffer_coupling_term[:];<EOL>self._inhibitory = next_inhibitory[:];<EOL>self._excitatory = next_excitatory[:];<EOL>if (self._params.ENABLE_POTENTIONAL is True):<EOL><INDENT>self._potential = next_potential[:];<EOL><DEDENT>

!
        @brief Calculates new state of each oscillator in the network.

        @param[in] solution (solve_type): Type solver of the differential equation.
        @param[in] t (double): Current time of simulation.
        @param[in] step (double): Step of solution at the end of which states of oscillators should be calculated.
        @param[in] int_step (double): Step differentiation that is used for solving differential equation.


def _global_inhibitor_state(self, z, t, argv):

sigma = <NUM_LIT:0.0>;<EOL>for x in self._excitatory:<EOL><INDENT>if (x > self._params.teta_zx):<EOL><INDENT>sigma = <NUM_LIT:1.0>;<EOL>break;<EOL><DEDENT><DEDENT>return self._params.fi * (sigma - z)<EOL>

!
        @brief Returns new value of global inhibitory

        @param[in] z (dobule): Current value of inhibitory.
        @param[in] t (double): Current time of simulation.
        @param[in] argv (tuple): It's not used, can be ignored.

        @return (double) New value if global inhibitory (not assign).


def _legion_state_simplify(self, inputs, t, argv):

index = argv;<EOL>x = inputs[<NUM_LIT:0>];  <EOL>y = inputs[<NUM_LIT:1>];  <EOL>dx = <NUM_LIT> * x - x ** <NUM_LIT> + <NUM_LIT> - y + self._stimulus[index] + self._coupling_term[index] + self._noise[index];<EOL>dy = self._params.eps * (self._params.gamma * (<NUM_LIT:1.0> + math.tanh(x / self._params.betta)) - y);<EOL>neighbors = self.get_neighbors(index);<EOL>potential = <NUM_LIT:0.0>;<EOL>for index_neighbor in neighbors:<EOL><INDENT>potential += self._params.T * heaviside(self._excitatory[index_neighbor] - self._params.teta_x);<EOL><DEDENT>return [dx, dy]<EOL>

!
        @brief Returns new values of excitatory and inhibitory parts of oscillator of oscillator.
        @details Simplify model doesn't consider oscillator potential.

        @param[in] inputs (list): Initial values (current) of oscillator [excitatory, inhibitory].
        @param[in] t (double): Current time of simulation.
        @param[in] argv (uint): Extra arguments that are not used for integration - index of oscillator.

        @return (list) New values of excitatoty and inhibitory part of oscillator (not assign).


def _legion_state(self, inputs, t, argv):

index = argv;<EOL>x = inputs[<NUM_LIT:0>];  <EOL>y = inputs[<NUM_LIT:1>];  <EOL>p = inputs[<NUM_LIT:2>];  <EOL>potential_influence = heaviside(p + math.exp(-self._params.alpha * t) - self._params.teta);<EOL>dx = <NUM_LIT> * x - x ** <NUM_LIT> + <NUM_LIT> - y + self._stimulus[index] * potential_influence + self._coupling_term[index] + self._noise[index];<EOL>dy = self._params.eps * (self._params.gamma * (<NUM_LIT:1.0> + math.tanh(x / self._params.betta)) - y);<EOL>neighbors = self.get_neighbors(index);<EOL>potential = <NUM_LIT:0.0>;<EOL>for index_neighbor in neighbors:<EOL><INDENT>potential += self._params.T * heaviside(self._excitatory[index_neighbor] - self._params.teta_x);<EOL><DEDENT>dp = self._params.lamda * (<NUM_LIT:1.0> - p) * heaviside(potential - self._params.teta_p) - self._params.mu * p;<EOL>return [dx, dy, dp]<EOL>

!
        @brief Returns new values of excitatory and inhibitory parts of oscillator and potential of oscillator.

        @param[in] inputs (list): Initial values (current) of oscillator [excitatory, inhibitory, potential].
        @param[in] t (double): Current time of simulation.
        @param[in] argv (uint): Extra arguments that are not used for integration - index of oscillator.

        @return (list) New values of excitatoty and inhibitory part of oscillator and new value of potential (not assign).


sync_visualizer.show_output_dynamic(analyser.get_first_layer_analyser())<EOL>

!
        @brief Shows output dynamic of the first layer.

        @param[in] analyser (syncsegm_analyser): Analyser of output dynamic of the 'syncsegm' oscillatory network.


second_layer_analysers = analyser.get_second_layer_analysers();<EOL>analysers_sequence = [ object_segment_analyser['<STR_LIT>'] for object_segment_analyser in second_layer_analysers ]<EOL>sync_visualizer.show_output_dynamics(analysers_sequence)<EOL>

!
        @brief Shows output dynamic of the second layer.

        @param[in] analyser (syncsegm_analyser): Analyser of output dynamic of the 'syncsegm' oscillatory network.


def __init__(self, color_analyser, object_segment_analysers = None):

self.__color_analyser = color_analyser;<EOL>self.__object_segment_analysers = object_segment_analysers<EOL>

!
        @brief Constructor of the analyser.

        @param[in] color_analyser (list): Analyser of coloring segmentation results of the first layer.
        @param[in] object_segment_analysers (list): Analysers of objects on image segments - results of the second layer.


return self.__color_analyser<EOL>

!
        @brief Returns analyser of coloring segmentation of the first layer.


return self.__object_segment_analysers<EOL>

!
        @brief Returns analysers of object segmentation of the second layer.


def allocate_colors(self, eps = <NUM_LIT>, noise_size = <NUM_LIT:1>):

segments = self.__color_analyser.allocate_clusters(eps);<EOL>real_segments = [cluster for cluster in segments if len(cluster) > noise_size];<EOL>return real_segments<EOL>

!
        @brief Allocates color segments.

        @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one segment.
        @param[in] noise_size (uint): Threshold that defines noise - segments size (in pixels) that is less then the threshold is considered as a noise.

        @return (list) Color segments where each color segment consists of indexes of pixels that forms color segment.


def allocate_objects(self, eps = <NUM_LIT>, noise_size = <NUM_LIT:1>):

if (self.__object_segment_analysers is None):<EOL><INDENT>return [];<EOL><DEDENT>segments = [];<EOL>for object_segment_analyser in self.__object_segment_analysers:<EOL><INDENT>indexes = object_segment_analyser['<STR_LIT>'];<EOL>analyser = object_segment_analyser['<STR_LIT>'];<EOL>segments += analyser.allocate_clusters(eps, indexes);<EOL><DEDENT>real_segments = [segment for segment in segments if len(segment) > noise_size];<EOL>return real_segments<EOL>

!
        @brief Allocates object segments.

        @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one segment.
        @param[in] noise_size (uint): Threshold that defines noise - segments size (in pixels) that is less then the threshold is considered as a noise.

        @return (list) Object segments where each object segment consists of indexes of pixels that forms object segment.


def __init__(self, color_radius, object_radius, noise_size = <NUM_LIT:0>, ccore = True):

self.__color_radius     = color_radius;<EOL>self.__object_radius    = object_radius;<EOL>self.__noise_size       = noise_size;<EOL>self.__order_color      = <NUM_LIT>;<EOL>self.__order_object     = <NUM_LIT>;<EOL>self.__network  = None;<EOL>self.__ccore    = ccore<EOL>

!
        @brief Contructor of the oscillatory network SYNC for cluster analysis.

        @param[in] color_radius (double): Radius of color connectivity (color similarity) for the first layer.
        @param[in] object_radius (double): Radius of object connectivity (object similarity) for the second layer,
                   if 'None' then object segmentation is not performed (only color segmentation).
        @param[in] noise_size (double): Size of segment that should be considered as a noise and ignored by the second layer.
        @param[in] ccore (bool): If 'True' then C/C++ implementation is used to increase performance.


def process(self, image_source, collect_dynamic = False, order_color = <NUM_LIT>, order_object = <NUM_LIT>):

self.__order_color  = order_color<EOL>self.__order_object = order_object<EOL>data = read_image(image_source)<EOL>color_analyser = self.__analyse_colors(data, collect_dynamic)<EOL>if self.__object_radius is None:<EOL><INDENT>return syncsegm_analyser(color_analyser, None)<EOL><DEDENT>object_segment_analysers = self.__analyse_objects(image_source, color_analyser, collect_dynamic)<EOL>return syncsegm_analyser(color_analyser, object_segment_analysers)<EOL>

!
        @brief Performs image segmentation.

        @param[in] image_source (string): Path to image file that should be processed.
        @param[in] collect_dynamic (bool): If 'True' then whole dynamic of each layer of the network is collected.
        @param[in] order_color (double): Local synchronization order for the first layer - coloring segmentation.
        @param[in] order_object (double): Local synchronization order for the second layer - object segmentation.

        @return (syncsegm_analyser) Analyser of segmentation results by the network.


def __analyse_colors(self, image_data, collect_dynamic):

network = syncnet(image_data, self.__color_radius, initial_phases = initial_type.RANDOM_GAUSSIAN, ccore = self.__ccore);<EOL>analyser = network.process(self.__order_color, solve_type.FAST, collect_dynamic);<EOL>return analyser<EOL>

!
        @brief Performs color segmentation by the first layer.

        @param[in] image_data (array_like): Image sample as a array-like structure.
        @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the first layer of the network is collected.

        @return (syncnet_analyser) Analyser of color segmentation results of the first layer.


def __analyse_objects(self, image_source, color_analyser, collect_dynamic):

<EOL>pointer_image = Image.open(image_source);<EOL>image_size = pointer_image.size;<EOL>object_analysers = [];<EOL>color_segments = color_analyser.allocate_clusters();<EOL>for segment in color_segments:<EOL><INDENT>object_analyser = self.__analyse_color_segment(image_size, segment, collect_dynamic);<EOL>if (object_analyser is not None):<EOL><INDENT>object_analysers.append( { '<STR_LIT>': segment, '<STR_LIT>': object_analyser } );<EOL><DEDENT><DEDENT>pointer_image.close();<EOL>return object_analysers<EOL>

!
        @brief Performs object segmentation by the second layer.

        @param[in] image_source (string): Path to image file that should be processed.
        @param[in] color_analyser (syncnet_analyser): Analyser of color segmentation results.
        @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the first layer of the network is collected.

        @return (map) Analysers of object segments.


def __analyse_color_segment(self, image_size, color_segment, collect_dynamic):

coordinates = self.__extract_location_coordinates(image_size, color_segment);<EOL>if (len(coordinates) < self.__noise_size):<EOL><INDENT>return None;<EOL><DEDENT>network = syncnet(coordinates, self.__object_radius, initial_phases = initial_type.EQUIPARTITION, ccore = True);<EOL>analyser = network.process(self.__order_object, solve_type.FAST, collect_dynamic);<EOL>return analyser<EOL>

!
        @brief Performs object segmentation of separate segment.

        @param[in] image_size (list): Image size presented as a [width x height].
        @param[in] color_segment (list): Image segment that should be processed.
        @param[in] collect_dynamic (bool): If 'True' then whole dynamic of the second layer of the network is collected.

        @return (syncnet_analyser) Analyser of object segmentation results of the second layer.


def __extract_location_coordinates(self, image_size, color_segment):

coordinates = [];<EOL>for index in color_segment:<EOL><INDENT>y = floor(index / image_size[<NUM_LIT:0>]);<EOL>x = index - y * image_size[<NUM_LIT:0>];<EOL>coordinates.append([x, y]);<EOL><DEDENT>return coordinates<EOL>

!
        @brief Extracts coordinates of specified image segment.

        @param[in] image_size (list): Image size presented as a [width x height].
        @param[in] color_segment (list): Image segment whose coordinates should be extracted.

        @return (list) Coordinates of each pixel.


file = open(filename, '<STR_LIT:r>')<EOL>sample = [[float(val) for val in line.split()] for line in file if len(line.strip()) > <NUM_LIT:0>]<EOL>file.close()<EOL>return sample<EOL>

!
    @brief Returns data sample from simple text file.
    @details This function should be used for text file with following format:
    @code
    point_1_coord_1 point_1_coord_2 ... point_1_coord_n
    point_2_coord_1 point_2_coord_2 ... point_2_coord_n
    ... ...
    @endcode

    @param[in] filename (string): Path to file with data.

    @return (list) Points where each point represented by list of coordinates.


amount_rows = len(sample);<EOL>return [ [ euclidean_distance(sample[i], sample[j]) for j in range(amount_rows) ] for i in range(amount_rows) ]<EOL>

!
    @brief Calculates distance matrix for data sample (sequence of points) using Euclidean distance as a metric.

    @param[in] sample (array_like): Data points that are used for distance calculation.

    @return (list) Matrix distance between data points.


with Image.open(filename) as image_source:<EOL><INDENT>data = [list(pixel) for pixel in image_source.getdata()]<EOL>return data<EOL><DEDENT>

!
    @brief Returns image as N-dimension (depends on the input image) matrix, where one element of list describes pixel.

    @param[in] filename (string): Path to image.

    @return (list) Pixels where each pixel described by list of RGB-values.


image_gray_array = [<NUM_LIT:0.0>] * len(image_rgb_array);<EOL>for index in range(<NUM_LIT:0>, len(image_rgb_array), <NUM_LIT:1>):<EOL><INDENT>image_gray_array[index] = float(image_rgb_array[index][<NUM_LIT:0>]) * <NUM_LIT> + float(image_rgb_array[index][<NUM_LIT:1>]) * <NUM_LIT> + float(image_rgb_array[index][<NUM_LIT:2>]) * <NUM_LIT>;<EOL><DEDENT>return image_gray_array<EOL>

!
    @brief Returns image as 1-dimension (gray colored) matrix, where one element of list describes pixel.
    @details Luma coding is used for transformation and that is calculated directly from gamma-compressed primary intensities as a weighted sum:

    \f[Y = 0.2989R + 0.587G + 0.114B\f]

    @param[in] image_rgb_array (list): Image represented by RGB list.

    @return (list) Image as gray colored matrix, where one element of list describes pixel.

    @code
        colored_image = read_image(file_name);
        gray_image = rgb2gray(colored_image);
    @endcode

    @see read_image()


wsize, hsize = image_source.size;<EOL>(ws, hs, we, he) = gray_pattern_borders(image_source);<EOL>image_source = image_source.crop((ws, hs, we, he));<EOL>image_source = image_source.resize((wsize, hsize), Image.ANTIALIAS);<EOL>data = [pixel for pixel in image_source.getdata()];<EOL>image_pattern = rgb2gray(data);<EOL>return (image_pattern, image_source)<EOL>

!
    @brief Returns stretched content as 1-dimension (gray colored) matrix with size of input image.

    @param[in] image_source (Image): PIL Image instance.

    @return (list, Image) Stretched image as gray colored matrix and source image.


width, height = image.size;<EOL>width_start = width;<EOL>width_end = <NUM_LIT:0>;<EOL>height_start = height;<EOL>height_end = <NUM_LIT:0>;<EOL>row, col = <NUM_LIT:0>, <NUM_LIT:0>;<EOL>for pixel in image.getdata():<EOL><INDENT>value = float(pixel[<NUM_LIT:0>]) * <NUM_LIT> + float(pixel[<NUM_LIT:1>]) * <NUM_LIT> + float(pixel[<NUM_LIT:2>]) * <NUM_LIT>;<EOL>if (value < <NUM_LIT>):<EOL><INDENT>if (width_end < col): <EOL><INDENT>width_end = col;<EOL><DEDENT>if (height_end < row):<EOL><INDENT>height_end = row;<EOL><DEDENT>if (width_start > col):<EOL><INDENT>width_start = col;<EOL><DEDENT>if (height_start > row):<EOL><INDENT>height_start = row;<EOL><DEDENT><DEDENT>col += <NUM_LIT:1>;<EOL>if (col >= width):<EOL><INDENT>col = <NUM_LIT:0>;<EOL>row += <NUM_LIT:1>;<EOL><DEDENT><DEDENT>return (width_start, height_start, width_end + <NUM_LIT:1>, height_end + <NUM_LIT:1>)<EOL>

!
    @brief Returns coordinates of gray image content on the input image.

    @param[in] image (Image): PIL Image instance that is processed.

    @return (tuple) Returns coordinates of gray image content as (width_start, height_start, width_end, height_end).


if num_neigh > len(points) - <NUM_LIT:1>:<EOL><INDENT>raise NameError('<STR_LIT>');<EOL><DEDENT>dist_matrix = [ [ <NUM_LIT:0.0> for i in range(len(points)) ] for j in range(len(points)) ];<EOL>for i in range(<NUM_LIT:0>, len(points), <NUM_LIT:1>):<EOL><INDENT>for j in range(i + <NUM_LIT:1>, len(points), <NUM_LIT:1>):<EOL><INDENT>distance = euclidean_distance(points[i], points[j]);<EOL>dist_matrix[i][j] = distance;<EOL>dist_matrix[j][i] = distance;<EOL><DEDENT>dist_matrix[i] = sorted(dist_matrix[i]);<EOL><DEDENT>total_distance = <NUM_LIT:0>;<EOL>for i in range(<NUM_LIT:0>, len(points), <NUM_LIT:1>):<EOL><INDENT>for j in range(<NUM_LIT:0>, num_neigh, <NUM_LIT:1>):<EOL><INDENT>total_distance += dist_matrix[i][j + <NUM_LIT:1>];<EOL><DEDENT><DEDENT>return ( total_distance / (num_neigh * len(points)) )<EOL>

!
    @brief Returns average distance for establish links between specified number of nearest neighbors.

    @param[in] points (list): Input data, list of points where each point represented by list.
    @param[in] num_neigh (uint): Number of neighbors that should be used for distance calculation.

    @return (double) Average distance for establish links between 'num_neigh' in data set 'points'.


def medoid(data, indexes=None, **kwargs):

index_median = None<EOL>distance = float('<STR_LIT>')<EOL>metric = kwargs.get('<STR_LIT>', type_metric.EUCLIDEAN_SQUARE)<EOL>data_type = kwargs.get('<STR_LIT>', '<STR_LIT>')<EOL>if data_type == '<STR_LIT>':<EOL><INDENT>calculator = lambda index1, index2: metric(data[index1], data[index2])<EOL><DEDENT>elif data_type == '<STR_LIT>':<EOL><INDENT>if isinstance(data, numpy.matrix):<EOL><INDENT>calculator = lambda index1, index2: data.item(index1, index2)<EOL><DEDENT>else:<EOL><INDENT>calculator = lambda index1, index2: data[index1][index2]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>" % data_type)<EOL><DEDENT>if indexes is None:<EOL><INDENT>range_points = range(len(data))<EOL><DEDENT>else:<EOL><INDENT>range_points = indexes<EOL><DEDENT>for index_candidate in range_points:<EOL><INDENT>distance_candidate = <NUM_LIT:0.0><EOL>for index in range_points:<EOL><INDENT>distance_candidate += calculator(index_candidate, index)<EOL><DEDENT>if distance_candidate < distance:<EOL><INDENT>distance = distance_candidate<EOL>index_median = index_candidate<EOL><DEDENT><DEDENT>return index_median<EOL>

!
    @brief Calculate medoid for input points using Euclidean distance.

    @param[in] data (list): Set of points for that median should be calculated.
    @param[in] indexes (list): Indexes of input set of points that will be taken into account during median calculation.
    @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'metric', 'data_type').

    Keyword Args:

        - metric (distance_metric): Metric that is used for distance calculation between two points.
        - data_type (string): Data type of input sample 'data' (available values: 'points', 'distance_matrix').

    @return (uint) index of point in input set that corresponds to median.


distance = euclidean_distance_square(a, b);<EOL>return distance**(<NUM_LIT:0.5>)<EOL>

!
    @brief Calculate Euclidean distance between vector a and b.
    @details The Euclidean between vectors (points) a and b is calculated by following formula:

    \f[
    dist(a, b) = \sqrt{ \sum_{i=0}^{N}(b_{i} - a_{i})^{2}) };
    \f]

    Where N is a length of each vector.

    @param[in] a (list): The first vector.
    @param[in] b (list): The second vector.

    @return (double) Euclidian distance between two vectors.

    @note This function for calculation is faster then standard function in ~100 times!


if ( ((type(a) == float) and (type(b) == float)) or ((type(a) == int) and (type(b) == int)) ):<EOL><INDENT>return (a - b)**<NUM_LIT>;<EOL><DEDENT>distance = <NUM_LIT:0.0>;<EOL>for i in range(<NUM_LIT:0>, len(a)):<EOL><INDENT>distance += (a[i] - b[i])**<NUM_LIT>;<EOL><DEDENT>return distance<EOL>

!
    @brief Calculate square Euclidian distance between vector a and b.

    @param[in] a (list): The first vector.
    @param[in] b (list): The second vector.

    @return (double) Square Euclidian distance between two vectors.


if ( ((type(a) == float) and (type(b) == float)) or ((type(a) == int) and (type(b) == int)) ):<EOL><INDENT>return abs(a - b);<EOL><DEDENT>distance = <NUM_LIT:0.0>;<EOL>dimension = len(a);<EOL>for i in range(<NUM_LIT:0>, dimension):<EOL><INDENT>distance += abs(a[i] - b[i]);<EOL><DEDENT>return distance<EOL>

!
    @brief Calculate Manhattan distance between vector a and b.

    @param[in] a (list): The first cluster.
    @param[in] b (list): The second cluster.

    @return (double) Manhattan distance between two vectors.


def average_inter_cluster_distance(cluster1, cluster2, data = None):

distance = <NUM_LIT:0.0>;<EOL>if (data is None):<EOL><INDENT>for i in range(len(cluster1)):<EOL><INDENT>for j in range(len(cluster2)):<EOL><INDENT>distance += euclidean_distance_square(cluster1[i], cluster2[j]);<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for i in range(len(cluster1)):<EOL><INDENT>for j in range(len(cluster2)):<EOL><INDENT>distance += euclidean_distance_square(data[ cluster1[i]], data[ cluster2[j]]);<EOL><DEDENT><DEDENT><DEDENT>distance /= float(len(cluster1) * len(cluster2));<EOL>return distance ** <NUM_LIT:0.5><EOL>

!
    @brief Calculates average inter-cluster distance between two clusters.
    @details Clusters can be represented by list of coordinates (in this case data shouldn't be specified),
             or by list of indexes of points from the data (represented by list of points), in this case
             data should be specified.

    @param[in] cluster1 (list): The first cluster where each element can represent index from the data or object itself.
    @param[in] cluster2 (list): The second cluster where each element can represent index from the data or object itself.
    @param[in] data (list): If specified than elements of clusters will be used as indexes,
               otherwise elements of cluster will be considered as points.

    @return (double) Average inter-cluster distance between two clusters.


def average_intra_cluster_distance(cluster1, cluster2, data=None):

distance = <NUM_LIT:0.0><EOL>for i in range(len(cluster1) + len(cluster2)):<EOL><INDENT>for j in range(len(cluster1) + len(cluster2)):<EOL><INDENT>if data is None:<EOL><INDENT>if i < len(cluster1):<EOL><INDENT>first_point = cluster1[i]<EOL><DEDENT>else:<EOL><INDENT>first_point = cluster2[i - len(cluster1)]<EOL><DEDENT>if j < len(cluster1):<EOL><INDENT>second_point = cluster1[j]<EOL><DEDENT>else:<EOL><INDENT>second_point = cluster2[j - len(cluster1)]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if i < len(cluster1):<EOL><INDENT>first_point = data[cluster1[i]]<EOL><DEDENT>else:<EOL><INDENT>first_point = data[cluster2[i - len(cluster1)]]<EOL><DEDENT>if j < len(cluster1):<EOL><INDENT>second_point = data[cluster1[j]]<EOL><DEDENT>else:<EOL><INDENT>second_point = data[cluster2[j - len(cluster1)]]<EOL><DEDENT><DEDENT>distance += euclidean_distance_square(first_point, second_point)<EOL><DEDENT><DEDENT>distance /= float((len(cluster1) + len(cluster2)) * (len(cluster1) + len(cluster2) - <NUM_LIT:1.0>))<EOL>return distance ** <NUM_LIT:0.5><EOL>

!
    @brief Calculates average intra-cluster distance between two clusters.
    @details Clusters can be represented by list of coordinates (in this case data shouldn't be specified),
             or by list of indexes of points from the data (represented by list of points), in this case
             data should be specified.

    @param[in] cluster1 (list): The first cluster.
    @param[in] cluster2 (list): The second cluster.
    @param[in] data (list): If specified than elements of clusters will be used as indexes,
               otherwise elements of cluster will be considered as points.

    @return (double) Average intra-cluster distance between two clusters.