def allocate_phase_matrix(self, grid_width = None, grid_height = None, iteration = None):

output_dynamic = self.output;<EOL>if ( (output_dynamic is None) or (len(output_dynamic) == <NUM_LIT:0>) ):<EOL><INDENT>return [];<EOL><DEDENT>current_dynamic = output_dynamic[len(output_dynamic) - <NUM_LIT:1>];<EOL>if (iteration is not None):<EOL><INDENT>current_dynamic = output_dynamic[iteration];<EOL><DEDENT>width_matrix = grid_width;<EOL>height_matrix = grid_height;<EOL>number_oscillators = len(current_dynamic);<EOL>if ( (width_matrix is None) or (height_matrix is None) ):<EOL><INDENT>width_matrix = int(math.ceil(math.sqrt(number_oscillators)));<EOL>height_matrix = width_matrix;<EOL><DEDENT>if (number_oscillators != width_matrix * height_matrix):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>phase_matrix = [ [ <NUM_LIT:0.0> for i in range(width_matrix) ] for j in range(height_matrix) ];<EOL>for i in range(height_matrix):<EOL><INDENT>for j in range(width_matrix):<EOL><INDENT>phase_matrix[i][j] = current_dynamic[j + i * width_matrix];<EOL><DEDENT><DEDENT>return phase_matrix<EOL>

!
        @brief Returns 2D matrix of phase values of oscillators at the specified iteration of simulation.
        @details User should ensure correct matrix sizes in line with following expression grid_width x grid_height that should be equal to
                  amount of oscillators otherwise exception is thrown. If grid_width or grid_height are not specified than phase matrix size
                  will by calculated automatically by square root.

        @param[in] grid_width (uint): Width of the allocated matrix.
        @param[in] grid_height (uint): Height of the allocated matrix.
        @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated.
                    If iternation number is not specified, the last step of simulation is used for the matrix allocation.

        @return (list) Phase value matrix of oscillators with size [number_oscillators x number_oscillators].


def allocate_correlation_matrix(self, iteration = None):

if (self._ccore_sync_dynamic_pointer is not None):<EOL><INDENT>return wrapper.sync_dynamic_allocate_correlation_matrix(self._ccore_sync_dynamic_pointer, iteration);<EOL><DEDENT>if ( (self._dynamic is None) or (len(self._dynamic) == <NUM_LIT:0>) ):<EOL><INDENT>return [];<EOL><DEDENT>dynamic = self._dynamic;<EOL>current_dynamic = dynamic[len(dynamic) - <NUM_LIT:1>];<EOL>if (iteration is not None):<EOL><INDENT>current_dynamic = dynamic[iteration];<EOL><DEDENT>number_oscillators = len(dynamic[<NUM_LIT:0>]);<EOL>affinity_matrix = [ [ <NUM_LIT:0.0> for i in range(number_oscillators) ] for j in range(number_oscillators) ];<EOL>for i in range(number_oscillators):<EOL><INDENT>for j in range(number_oscillators):<EOL><INDENT>phase1 = current_dynamic[i];<EOL>phase2 = current_dynamic[j];<EOL>affinity_matrix[i][j] = abs(math.sin(phase1 - phase2));<EOL><DEDENT><DEDENT>return affinity_matrix<EOL>

!
        @brief Allocate correlation matrix between oscillators at the specified step of simulation.

        @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated.
                    If iternation number is not specified, the last step of simulation is used for the matrix allocation.

        @return (list) Correlation matrix between oscillators with size [number_oscillators x number_oscillators].


def calculate_order_parameter(self, start_iteration = None, stop_iteration = None):

(start_iteration, stop_iteration) = self.__get_start_stop_iterations(start_iteration, stop_iteration);<EOL>if (self._ccore_sync_dynamic_pointer is not None):<EOL><INDENT>return wrapper.sync_dynamic_calculate_order(self._ccore_sync_dynamic_pointer, start_iteration, stop_iteration);<EOL><DEDENT>sequence_order = [];<EOL>for index in range(start_iteration, stop_iteration):<EOL><INDENT>sequence_order.append(order_estimator.calculate_sync_order(self.output[index]));<EOL><DEDENT>return sequence_order<EOL>

!
        @brief Calculates level of global synchorization (order parameter).
        @details This parameter is tend 1.0 when the oscillatory network close to global synchronization and it tend to 0.0 when
                  desynchronization is observed in the network. Order parameter is calculated using following equation:

                  \f[
                  r_{c}=\frac{1}{Ne^{i\varphi }}\sum_{j=0}^{N}e^{i\theta_{j}};
                  \f]

                  where \f$\varphi\f$ is a average phase coordinate in the network, \f$N\f$ is an amount of oscillators in the network.

        @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the last iteration is used.
        @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then 'start_iteration' + 1 is used.

        Example:
        @code
            oscillatory_network = sync(16, type_conn = conn_type.ALL_TO_ALL);
            output_dynamic = oscillatory_network.simulate_static(100, 10);

            print("Order parameter at the last step: ", output_dynamic.calculate_order_parameter());
            print("Order parameter at the first step:", output_dynamic.calculate_order_parameter(0));
            print("Order parameter evolution between 40 and 50 steps:", output_dynamic.calculate_order_parameter(40, 50));
        @endcode

        @return (list) List of levels of global synchronization (order parameter evolution).

        @see order_estimator


def calculate_local_order_parameter(self, oscillatory_network, start_iteration = None, stop_iteration = None):

(start_iteration, stop_iteration) = self.__get_start_stop_iterations(start_iteration, stop_iteration);<EOL>if (self._ccore_sync_dynamic_pointer is not None):<EOL><INDENT>network_pointer = oscillatory_network._ccore_network_pointer;<EOL>return wrapper.sync_dynamic_calculate_local_order(self._ccore_sync_dynamic_pointer, network_pointer, start_iteration, stop_iteration);<EOL><DEDENT>sequence_local_order = [];<EOL>for index in range(start_iteration, stop_iteration):<EOL><INDENT>sequence_local_order.append(order_estimator.calculate_local_sync_order(self.output[index], oscillatory_network));<EOL><DEDENT>return sequence_local_order<EOL>

!
        @brief Calculates local order parameter.
        @details Local order parameter or so-called level of local or partial synchronization is calculated by following expression:

        \f[
        r_{c}=\left | \sum_{i=0}^{N} \frac{1}{N_{i}} \sum_{j=0}e^{ \theta_{j} - \theta_{i} } \right |;
        \f]

        where N - total amount of oscillators in the network and \f$N_{i}\f$ - amount of neighbors of oscillator with index \f$i\f$.

        @param[in] oscillatory_network (sync): Sync oscillatory network whose structure of connections is required for calculation.
        @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the last iteration is used.
        @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then 'start_iteration' + 1 is used.

        @return (list) List of levels of local (partial) synchronization (local order parameter evolution).


def __get_start_stop_iterations(self, start_iteration, stop_iteration):

if (start_iteration is None):<EOL><INDENT>start_iteration = len(self) - <NUM_LIT:1>;<EOL><DEDENT>if (stop_iteration is None):<EOL><INDENT>stop_iteration = start_iteration + <NUM_LIT:1>;<EOL><DEDENT>return (start_iteration, stop_iteration)<EOL>

!
        @brief Aplly rules for start_iteration and stop_iteration parameters.

        @param[in] start_iteration (uint): The first iteration that is used for calculation.
        @param[in] stop_iteration (uint): The last iteration that is used for calculation.

        @return (tuple) New the first iteration and the last.


draw_dynamics(sync_output_dynamic.time, sync_output_dynamic.output, x_title = "<STR_LIT:t>", y_title = "<STR_LIT>", y_lim = [<NUM_LIT:0>, <NUM_LIT:2> * <NUM_LIT>])<EOL>

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

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.

        @see show_output_dynamics


draw_dynamics_set(sync_output_dynamics, "<STR_LIT:t>", "<STR_LIT>", None, [<NUM_LIT:0>, <NUM_LIT:2> * <NUM_LIT>], False, False)<EOL>

!
        @brief Shows several output dynamics (output of each oscillator) during simulation.
        @details Each dynamic is presented on separate plot.

        @param[in] sync_output_dynamics (list): list of output dynamics 'sync_dynamic' of the Sync network.

        @see show_output_dynamic


@staticmethod<EOL><INDENT>def show_correlation_matrix(sync_output_dynamic, iteration = None):<DEDENT>

_ = plt.figure();<EOL>correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(iteration);<EOL>plt.imshow(correlation_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT:1.0>); <EOL>plt.show()<EOL>

!
        @brief Shows correlation matrix between oscillators at the specified iteration.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] iteration (uint): Number of interation of simulation for which correlation matrix should be allocated.
                                      If iternation number is not specified, the last step of simulation is used for the matrix allocation.


@staticmethod<EOL><INDENT>def show_phase_matrix(sync_output_dynamic, grid_width = None, grid_height = None, iteration = None):<DEDENT>

_ = plt.figure();<EOL>phase_matrix = sync_output_dynamic.allocate_phase_matrix(grid_width, grid_height, iteration);<EOL>plt.imshow(phase_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT> * math.pi); <EOL>plt.show()<EOL>

!
        @brief Shows 2D matrix of phase values of oscillators at the specified iteration.
        @details User should ensure correct matrix sizes in line with following expression grid_width x grid_height that should be equal to
                  amount of oscillators otherwise exception is thrown. If grid_width or grid_height are not specified than phase matrix size
                  will by calculated automatically by square root.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose phase matrix should be shown.
        @param[in] grid_width (uint): Width of the phase matrix.
        @param[in] grid_height (uint): Height of the phase matrix.
        @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated.
                    If iternation number is not specified, the last step of simulation is used for the matrix allocation.


@staticmethod<EOL><INDENT>def show_order_parameter(sync_output_dynamic, start_iteration = None, stop_iteration = None):<DEDENT>

(start_iteration, stop_iteration) = sync_visualizer.__get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration);<EOL>order_parameter = sync_output_dynamic.calculate_order_parameter(start_iteration, stop_iteration);<EOL>axis = plt.subplot(<NUM_LIT>);<EOL>plt.plot(sync_output_dynamic.time[start_iteration:stop_iteration], order_parameter, '<STR_LIT>', linewidth = <NUM_LIT>);<EOL>set_ax_param(axis, "<STR_LIT:t>", "<STR_LIT>", None, [<NUM_LIT:0.0>, <NUM_LIT>]);<EOL>plt.show()<EOL>

!
        @brief Shows evolution of order parameter (level of global synchronization in the network).

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose evolution of global synchronization should be visualized.
        @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the first is used
        @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then the last is used.


@staticmethod<EOL><INDENT>def show_local_order_parameter(sync_output_dynamic, oscillatory_network, start_iteration = None, stop_iteration = None):<DEDENT>

(start_iteration, stop_iteration) = sync_visualizer.__get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration);<EOL>order_parameter = sync_output_dynamic.calculate_local_order_parameter(oscillatory_network, start_iteration, stop_iteration);<EOL>axis = plt.subplot(<NUM_LIT>);<EOL>plt.plot(sync_output_dynamic.time[start_iteration:stop_iteration], order_parameter, '<STR_LIT>', linewidth = <NUM_LIT>);<EOL>set_ax_param(axis, "<STR_LIT:t>", "<STR_LIT>", None, [<NUM_LIT:0.0>, <NUM_LIT>]);<EOL>plt.show()<EOL>

!
        @brief Shows evolution of local order parameter (level of local synchronization in the network).

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose evolution of global synchronization should be visualized.
        @param[in] oscillatory_network (sync): Sync oscillatory network whose structure of connections is required for calculation.
        @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the first is used
        @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then the last is used.


@staticmethod<EOL><INDENT>def animate_output_dynamic(sync_output_dynamic, animation_velocity = <NUM_LIT>, save_movie = None):<DEDENT>

figure = plt.figure();<EOL>dynamic = sync_output_dynamic.output[<NUM_LIT:0>];<EOL>artist, = plt.polar(dynamic, [<NUM_LIT:1.0>] * len(dynamic), '<STR_LIT:o>', color = '<STR_LIT>');<EOL>def init_frame():<EOL><INDENT>return [ artist ];<EOL><DEDENT>def frame_generation(index_dynamic):<EOL><INDENT>dynamic = sync_output_dynamic.output[index_dynamic];<EOL>artist.set_data(dynamic, [<NUM_LIT:1.0>] * len(dynamic));<EOL>return [ artist ];<EOL><DEDENT>phase_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), interval = animation_velocity, init_func = init_frame, repeat_delay = <NUM_LIT>);<EOL>if (save_movie is not None):<EOL><INDENT>phase_animation.save(save_movie, writer = '<STR_LIT>', fps = <NUM_LIT:15>, bitrate = <NUM_LIT>);<EOL><DEDENT>else:<EOL><INDENT>plt.show();<EOL><DEDENT>

!
        @brief Shows animation of output dynamic (output of each oscillator) during simulation on a circle from [0; 2pi].

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds.
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.


@staticmethod<EOL><INDENT>def animate_correlation_matrix(sync_output_dynamic, animation_velocity = <NUM_LIT>, colormap = '<STR_LIT>', save_movie = None):<DEDENT>

figure = plt.figure()<EOL>correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(<NUM_LIT:0>)<EOL>artist = plt.imshow(correlation_matrix, cmap = plt.get_cmap(colormap), interpolation='<STR_LIT>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT:1.0>)<EOL>def init_frame(): <EOL><INDENT>return [ artist ]<EOL><DEDENT>def frame_generation(index_dynamic):<EOL><INDENT>correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(index_dynamic)<EOL>artist.set_data(correlation_matrix)<EOL>return [ artist ]<EOL><DEDENT>correlation_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), init_func = init_frame, interval = animation_velocity , repeat_delay = <NUM_LIT:1000>, blit = True)<EOL>if (save_movie is not None):<EOL><INDENT>correlation_animation.save(save_movie, writer = '<STR_LIT>', fps = <NUM_LIT:15>, bitrate = <NUM_LIT>)<EOL><DEDENT>else:<EOL><INDENT>plt.show()<EOL><DEDENT>

!
        @brief Shows animation of correlation matrix between oscillators during simulation.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds.
        @param[in] colormap (string): Name of colormap that is used by matplotlib ('gray', 'pink', 'cool', spring', etc.).
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.


@staticmethod<EOL><INDENT>def animate_phase_matrix(sync_output_dynamic, grid_width = None, grid_height = None, animation_velocity = <NUM_LIT>, colormap = '<STR_LIT>', save_movie = None):<DEDENT>

figure = plt.figure();<EOL>def init_frame(): <EOL><INDENT>return frame_generation(<NUM_LIT:0>);<EOL><DEDENT>def frame_generation(index_dynamic):<EOL><INDENT>figure.clf();<EOL>axis = figure.add_subplot(<NUM_LIT>);<EOL>phase_matrix = sync_output_dynamic.allocate_phase_matrix(grid_width, grid_height, index_dynamic);<EOL>axis.imshow(phase_matrix, cmap = plt.get_cmap(colormap), interpolation='<STR_LIT>', vmin = <NUM_LIT:0.0>, vmax = <NUM_LIT> * math.pi);<EOL>artist = figure.gca();<EOL>return [ artist ];<EOL><DEDENT>phase_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), init_func = init_frame, interval = animation_velocity , repeat_delay = <NUM_LIT:1000>);<EOL>if (save_movie is not None):<EOL><INDENT>phase_animation.save(save_movie, writer = '<STR_LIT>', fps = <NUM_LIT:15>, bitrate = <NUM_LIT>);<EOL><DEDENT>else:<EOL><INDENT>plt.show();<EOL><DEDENT>

!
        @brief Shows animation of phase matrix between oscillators during simulation on 2D stage.
        @details If grid_width or grid_height are not specified than phase matrix size will by calculated automatically by square root.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] grid_width (uint): Width of the phase matrix.
        @param[in] grid_height (uint): Height of the phase matrix.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds.
        @param[in] colormap (string): Name of colormap that is used by matplotlib ('gray', 'pink', 'cool', spring', etc.).
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.


@staticmethod<EOL><INDENT>def __get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration):<DEDENT>

if (start_iteration is None):<EOL><INDENT>start_iteration = <NUM_LIT:0>;<EOL><DEDENT>if (stop_iteration is None):<EOL><INDENT>stop_iteration = len(sync_output_dynamic);<EOL><DEDENT>return (start_iteration, stop_iteration)<EOL>

!
        @brief Apply rule of preparation for start iteration and stop iteration values.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] start_iteration (uint): The first iteration that is used for calculation.
        @param[in] stop_iteration (uint): The last iteration that is used for calculation.

        @return (tuple) New values of start and stop iterations.


@staticmethod<EOL><INDENT>def animate(sync_output_dynamic, title = None, save_movie = None):<DEDENT>

dynamic = sync_output_dynamic.output[<NUM_LIT:0>];<EOL>correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(<NUM_LIT:0>);<EOL>figure = plt.figure(<NUM_LIT:1>);<EOL>if (title is not None):<EOL><INDENT>figure.suptitle(title, fontsize = <NUM_LIT>, fontweight = '<STR_LIT>')<EOL><DEDENT>ax1 = figure.add_subplot(<NUM_LIT>, projection='<STR_LIT>');<EOL>ax2 = figure.add_subplot(<NUM_LIT>);<EOL>artist1, = ax1.plot(dynamic, [<NUM_LIT:1.0>] * len(dynamic), marker = '<STR_LIT:o>', color = '<STR_LIT>', ls = '<STR_LIT>');<EOL>artist2 = ax2.imshow(correlation_matrix, cmap = plt.get_cmap('<STR_LIT>'), interpolation='<STR_LIT>');<EOL>def init_frame():<EOL><INDENT>return [ artist1, artist2 ];<EOL><DEDENT>def frame_generation(index_dynamic):<EOL><INDENT>dynamic = sync_output_dynamic.output[index_dynamic];<EOL>artist1.set_data(dynamic, [<NUM_LIT:1.0>] * len(dynamic));<EOL>correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(index_dynamic);<EOL>artist2.set_data(correlation_matrix);<EOL>return [ artist1, artist2 ];<EOL><DEDENT>dynamic_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), interval = <NUM_LIT>, init_func = init_frame, repeat_delay = <NUM_LIT>);<EOL>if (save_movie is not None):<EOL><INDENT>dynamic_animation.save(save_movie, writer = '<STR_LIT>', fps = <NUM_LIT:15>, bitrate = <NUM_LIT>);<EOL><DEDENT>else:<EOL><INDENT>plt.show();<EOL><DEDENT>

!
        @brief Shows animation of phase coordinates and animation of correlation matrix together for the Sync dynamic output on the same figure.

        @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network.
        @param[in] title (string): Title of the animation that is displayed on a figure if it is specified.
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.


def __init__(self, num_osc, weight = <NUM_LIT:1>, frequency = <NUM_LIT:0>, type_conn = conn_type.ALL_TO_ALL, representation = conn_represent.MATRIX, initial_phases = initial_type.RANDOM_GAUSSIAN, ccore = True):

self._ccore_network_pointer = None;      <EOL>if ( (ccore is True) and ccore_library.workable() ):<EOL><INDENT>self._ccore_network_pointer = wrapper.sync_create_network(num_osc, weight, frequency, type_conn, initial_phases);<EOL>self._num_osc = num_osc;<EOL>self._conn_represent = conn_represent.MATRIX;<EOL><DEDENT>else:   <EOL><INDENT>super().__init__(num_osc, type_conn, representation);<EOL>self._weight = weight;<EOL>self._phases = list();<EOL>self._freq = list();<EOL>random.seed();<EOL>for index in range(<NUM_LIT:0>, num_osc, <NUM_LIT:1>):<EOL><INDENT>if (initial_phases == initial_type.RANDOM_GAUSSIAN):<EOL><INDENT>self._phases.append(random.random() * <NUM_LIT:2> * pi);<EOL><DEDENT>elif (initial_phases == initial_type.EQUIPARTITION):<EOL><INDENT>self._phases.append( pi / num_osc * index);<EOL><DEDENT>self._freq.append(random.random() * frequency);<EOL><DEDENT><DEDENT>

!
        @brief Constructor of oscillatory network is based on Kuramoto model.

        @param[in] num_osc (uint): Number of oscillators in the network.
        @param[in] weight (double): Coupling strength of the links between oscillators.
        @param[in] frequency (double): Multiplier of internal frequency of the oscillators.
        @param[in] type_conn (conn_type): Type of connection between oscillators in the network (all-to-all, grid, bidirectional list, etc.).
        @param[in] representation (conn_represent): Internal representation of connection in the network: matrix or list.
        @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.).
        @param[in] ccore (bool): If True simulation is performed by CCORE library (C++ implementation of pyclustering).


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

!
        @brief Destructor of oscillatory network is based on Kuramoto model.


if (self._ccore_network_pointer is not None):<EOL><INDENT>return wrapper.sync_order(self._ccore_network_pointer);<EOL><DEDENT>return order_estimator.calculate_sync_order(self._phases)<EOL>

!
        @brief Calculates current level of global synchorization (order parameter) in the network.
        @details This parameter is tend 1.0 when the oscillatory network close to global synchronization and it tend to 0.0 when
                  desynchronization is observed in the network. Order parameter is calculated using following equation:

                  \f[
                  r_{c}=\frac{1}{Ne^{i\varphi }}\sum_{j=0}^{N}e^{i\theta_{j}};
                  \f]

                  where \f$\varphi\f$ is a average phase coordinate in the network, \f$N\f$ is an amount of oscillators in the network.

        Example:
        @code
            oscillatory_network = sync(16, type_conn = conn_type.ALL_TO_ALL);
            output_dynamic = oscillatory_network.simulate_static(100, 10);

            if (oscillatory_network.sync_order() < 0.9): print("Global synchronization is not reached yet.");
            else: print("Global synchronization is reached.");
        @endcode

        @return (double) Level of global synchronization (order parameter).

        @see sync_local_order()


if (self._ccore_network_pointer is not None):<EOL><INDENT>return wrapper.sync_local_order(self._ccore_network_pointer);<EOL><DEDENT>return order_estimator.calculate_local_sync_order(self._phases, self)<EOL>

!
        @brief Calculates current level of local (partial) synchronization in the network.

        @return (double) Level of local (partial) synchronization.

        @see sync_order()


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

index = argv;<EOL>phase = <NUM_LIT:0>;<EOL>for k in range(<NUM_LIT:0>, self._num_osc):<EOL><INDENT>if (self.has_connection(index, k) == True):<EOL><INDENT>phase += math.sin(self._phases[k] - teta);<EOL><DEDENT><DEDENT>return ( self._freq[index] + (phase * self._weight / self._num_osc) )<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 here).


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

return self.simulate_static(steps, time, solution, collect_dynamic)<EOL>

!
        @brief Performs static simulation of Sync oscillatory network.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] solution (solve_type): Type of solution (solving).
        @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.

        @see simulate_dynamic()
        @see simulate_static()


def simulate_dynamic(self, order = <NUM_LIT>, solution = solve_type.FAST, collect_dynamic = False, step = <NUM_LIT:0.1>, int_step = <NUM_LIT>, threshold_changes = <NUM_LIT>):

if (self._ccore_network_pointer is not None):<EOL><INDENT>ccore_instance_dynamic = wrapper.sync_simulate_dynamic(self._ccore_network_pointer, order, solution, collect_dynamic, step, int_step, threshold_changes);<EOL>return sync_dynamic(None, None, ccore_instance_dynamic);<EOL><DEDENT>time_counter = <NUM_LIT:0>;<EOL>previous_order = <NUM_LIT:0>;<EOL>current_order = self.sync_local_order();<EOL>dyn_phase = [];<EOL>dyn_time = [];<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(<NUM_LIT:0>);<EOL><DEDENT>while (current_order < order):<EOL><INDENT>self._phases = self._calculate_phases(solution, time_counter, step, int_step);<EOL>time_counter += step;<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(time_counter);<EOL><DEDENT>previous_order = current_order;<EOL>current_order = self.sync_local_order();<EOL>if (abs(current_order - previous_order) < threshold_changes):<EOL><INDENT>break;<EOL><DEDENT><DEDENT>if (collect_dynamic != True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(time_counter);<EOL><DEDENT>output_sync_dynamic = sync_dynamic(dyn_phase, dyn_time, None);<EOL>return output_sync_dynamic<EOL>

!
        @brief Performs dynamic simulation of the network until stop condition is not reached. Stop condition is defined by input argument 'order'.

        @param[in] order (double): Order of process synchronization, distributed 0..1.
        @param[in] solution (solve_type): Type of solution.
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.
        @param[in] step (double): Time step of one iteration of simulation.
        @param[in] int_step (double): Integration step, should be less than step.
        @param[in] threshold_changes (double): Additional stop condition that helps prevent infinite simulation, defines limit of changes of oscillators between current and previous steps.

        @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.

        @see simulate()
        @see simulate_static()


def simulate_static(self, steps, time, solution = solve_type.FAST, collect_dynamic = False):

if (self._ccore_network_pointer is not None):<EOL><INDENT>ccore_instance_dynamic = wrapper.sync_simulate_static(self._ccore_network_pointer, steps, time, solution, collect_dynamic);<EOL>return sync_dynamic(None, None, ccore_instance_dynamic);<EOL><DEDENT>dyn_phase = [];<EOL>dyn_time = [];<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(<NUM_LIT:0>);<EOL><DEDENT>step = time / steps;<EOL>int_step = step / <NUM_LIT>;<EOL>for t in numpy.arange(step, time + step, step):<EOL><INDENT>self._phases = self._calculate_phases(solution, t, step, int_step);<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(t);<EOL><DEDENT><DEDENT>if (collect_dynamic != True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(time);<EOL><DEDENT>output_sync_dynamic = sync_dynamic(dyn_phase, dyn_time);<EOL>return output_sync_dynamic<EOL>

!
        @brief Performs static simulation of oscillatory network.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] solution (solve_type): Type of solution.
        @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.

        @see simulate()
        @see simulate_dynamic()


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

next_phases = [<NUM_LIT:0.0>] * self._num_osc;    <EOL>for index in range (<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>if (solution == solve_type.FAST):<EOL><INDENT>result = self._phases[index] + self._phase_kuramoto(self._phases[index], <NUM_LIT:0>, index);<EOL>next_phases[index] = self._phase_normalization(result);<EOL><DEDENT>elif ( (solution == solve_type.RK4) or (solution == solve_type.RKF45) ):<EOL><INDENT>result = odeint(self._phase_kuramoto, self._phases[index], numpy.arange(t - step, t, int_step), (index , ));<EOL>next_phases[index] = self._phase_normalization(result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>]);<EOL><DEDENT>else:<EOL><INDENT>raise NameError("<STR_LIT>" + str(solution) + "<STR_LIT>");<EOL><DEDENT><DEDENT>return next_phases<EOL>

!
        @brief Calculates new phases for oscillators in the network in line with current step.

        @param[in] solution (solve_type): Type solver of the differential equation.
        @param[in] t (double): 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.

        @return (list) New states (phases) for oscillators.


norm_teta = teta;<EOL>while (norm_teta > (<NUM_LIT> * pi)) or (norm_teta < <NUM_LIT:0>):<EOL><INDENT>if (norm_teta > (<NUM_LIT> * pi)):<EOL><INDENT>norm_teta -= <NUM_LIT> * pi;<EOL><DEDENT>else:<EOL><INDENT>norm_teta += <NUM_LIT> * pi;<EOL><DEDENT><DEDENT>return norm_teta<EOL>

!
        @brief Normalization of phase of oscillator that should be placed between [0; 2 * pi].

        @param[in] teta (double): phase of oscillator.

        @return (double) Normalized phase.


if ( (self._ccore_network_pointer is not None) and (self._osc_conn is None) ):<EOL><INDENT>self._osc_conn = wrapper.sync_connectivity_matrix(self._ccore_network_pointer);<EOL><DEDENT>return super().get_neighbors(index)<EOL>

!
        @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.


if ( (self._ccore_network_pointer is not None) and (self._osc_conn is None) ):<EOL><INDENT>self._osc_conn = wrapper.sync_connectivity_matrix(self._ccore_network_pointer);<EOL><DEDENT>return super().has_connection(i, j)<EOL>

!
        @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.


<EOL>self.nu      = random.random() * <NUM_LIT> - <NUM_LIT:1.0>;<EOL>self.gNa     = <NUM_LIT> * (<NUM_LIT:1> + <NUM_LIT> * self.nu);<EOL>self.gK      = <NUM_LIT> * (<NUM_LIT:1> + <NUM_LIT> * self.nu);<EOL>self.gL      = <NUM_LIT> * (<NUM_LIT:1> + <NUM_LIT> * self.nu);<EOL>self.vNa     = <NUM_LIT>;<EOL>self.vK      = -<NUM_LIT>;<EOL>self.vL      = -<NUM_LIT>;<EOL>self.vRest   = -<NUM_LIT>;    <EOL>self.Icn1    = <NUM_LIT>;<EOL>self.Icn2    = <NUM_LIT>;<EOL>self.Vsyninh = -<NUM_LIT>;    <EOL>self.Vsynexc = <NUM_LIT:0.0>;<EOL>self.alfa_inhibitory     = <NUM_LIT>;<EOL>self.betta_inhibitory    = <NUM_LIT>;<EOL>self.alfa_excitatory     = <NUM_LIT>;<EOL>self.betta_excitatory    = <NUM_LIT>;<EOL>self.w1 = <NUM_LIT:0.1>;<EOL>self.w2 = <NUM_LIT>;<EOL>self.w3 = <NUM_LIT>;<EOL>self.deltah = <NUM_LIT>;<EOL>self.threshold = -<NUM_LIT:10>;<EOL>self.eps = <NUM_LIT><EOL>

!
        @brief    Default constructor of parameters for Hodgkin-Huxley Oscillatory Network.
        @details  Constructor initializes parameters by default non-zero values that can be
                  used for simple simulation.


<EOL>self.membrane_potential      = <NUM_LIT:0.0>;<EOL>self.active_cond_sodium      = <NUM_LIT:0.0>;<EOL>self.inactive_cond_sodium    = <NUM_LIT:0.0>;<EOL>self.active_cond_potassium   = <NUM_LIT:0.0>;<EOL>self.pulse_generation = False;<EOL>self.pulse_generation_time = []<EOL>

!
        @brief Constructor of central element.


return "<STR_LIT>" % (self.membrane_potential, self.pulse_generation_time)<EOL>

!
        @brief Returns string that represents central element.


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

super().__init__(num_osc, conn_type.NONE, type_conn_represent);<EOL>if (stimulus is None):<EOL><INDENT>self._stimulus = [<NUM_LIT:0.0>] * num_osc;<EOL><DEDENT>else:<EOL><INDENT>self._stimulus = stimulus;<EOL><DEDENT>if (parameters is not None):<EOL><INDENT>self._params = parameters;<EOL><DEDENT>else:<EOL><INDENT>self._params = hhn_parameters();<EOL><DEDENT>self.__ccore_hhn_pointer = None;<EOL>self.__ccore_hhn_dynamic_pointer = None;<EOL>if ( (ccore is True) and ccore_library.workable() ):<EOL><INDENT>self.__ccore_hhn_pointer = wrapper.hhn_create(num_osc, self._params);<EOL><DEDENT>else:<EOL><INDENT>self._membrane_dynamic_pointer = None;        <EOL>self._membrane_potential        = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._active_cond_sodium        = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._inactive_cond_sodium      = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._active_cond_potassium     = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._link_activation_time      = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._link_pulse_counter        = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._link_deactivation_time    = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._link_weight3              = [<NUM_LIT:0.0>] * self._num_osc;<EOL>self._pulse_generation_time     = [ [] for i in range(self._num_osc) ];<EOL>self._pulse_generation          = [False] * self._num_osc;<EOL>self._noise = [random.random() * <NUM_LIT> - <NUM_LIT:1.0> for i in range(self._num_osc)];<EOL>self._central_element = [central_element(), central_element()];<EOL><DEDENT>

!
        @brief Constructor of oscillatory network based on Hodgkin-Huxley neuron model.

        @param[in] num_osc (uint): Number of peripheral oscillators in the network.
        @param[in] stimulus (list): List of stimulus for oscillators, number of stimulus should be equal to number of peripheral oscillators.
        @param[in] parameters (hhn_parameters): Parameters of the network.
        @param[in] type_conn (conn_type): Type of connections between oscillators in the network (ignored for this type of 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 CCORE is used (C/C++ implementation of the model).


if self.__ccore_hhn_pointer:<EOL><INDENT>wrapper.hhn_destroy(self.__ccore_hhn_pointer)<EOL><DEDENT>

!
        @brief Destroy dynamically allocated oscillatory network instance in case of CCORE usage.


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

return self.simulate_static(steps, time, solution)<EOL>

!
        @brief Performs static simulation of oscillatory network based on Hodgkin-Huxley neuron model.
        @details Output dynamic is sensible to amount of steps of simulation and solver of differential equation.
                  Python implementation uses 'odeint' from 'scipy', CCORE uses classical RK4 and RFK45 methods,
                  therefore in case of CCORE HHN (Hodgkin-Huxley network) amount of steps should be greater than in
                  case of Python HHN.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] solution (solve_type): Type of solver for differential equations.

        @return (tuple) Dynamic of oscillatory network represented by (time, peripheral neurons dynamic, central elements
                dynamic), where types are (list, list, list).


def simulate_static(self, steps, time, solution = solve_type.RK4):

<EOL>if (solution == solve_type.FAST):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>self._membrane_dynamic_pointer = None;<EOL>if (self.__ccore_hhn_pointer is not None):<EOL><INDENT>self.__ccore_hhn_dynamic_pointer = wrapper.hhn_dynamic_create(True, False, False, False);<EOL>wrapper.hhn_simulate(self.__ccore_hhn_pointer, steps, time, solution, self._stimulus, self.__ccore_hhn_dynamic_pointer);<EOL>peripheral_membrane_potential = wrapper.hhn_dynamic_get_peripheral_evolution(self.__ccore_hhn_dynamic_pointer, <NUM_LIT:0>);<EOL>central_membrane_potential = wrapper.hhn_dynamic_get_central_evolution(self.__ccore_hhn_dynamic_pointer, <NUM_LIT:0>);<EOL>dynamic_time = wrapper.hhn_dynamic_get_time(self.__ccore_hhn_dynamic_pointer);<EOL>self._membrane_dynamic_pointer = peripheral_membrane_potential;<EOL>wrapper.hhn_dynamic_destroy(self.__ccore_hhn_dynamic_pointer);<EOL>return (dynamic_time, peripheral_membrane_potential, central_membrane_potential);<EOL><DEDENT>if (solution == solve_type.RKF45):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>dyn_peripheral = [ self._membrane_potential[:] ];<EOL>dyn_central = [ [<NUM_LIT:0.0>, <NUM_LIT:0.0>] ];<EOL>dyn_time = [ <NUM_LIT:0.0> ];<EOL>step = time / steps;<EOL>int_step = step / <NUM_LIT>;<EOL>for t in numpy.arange(step, time + step, step):<EOL><INDENT>(memb_peripheral, memb_central) = self._calculate_states(solution, t, step, int_step);<EOL>dyn_peripheral.append(memb_peripheral);<EOL>dyn_central.append(memb_central);<EOL>dyn_time.append(t);<EOL><DEDENT>self._membrane_dynamic_pointer = dyn_peripheral;<EOL>return (dyn_time, dyn_peripheral, dyn_central)<EOL>


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

next_membrane           = [<NUM_LIT:0.0>] * self._num_osc;<EOL>next_active_sodium      = [<NUM_LIT:0.0>] * self._num_osc;<EOL>next_inactive_sodium    = [<NUM_LIT:0.0>] * self._num_osc;<EOL>next_active_potassium   = [<NUM_LIT:0.0>] * self._num_osc;<EOL>for index in range (<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>result = odeint(self.hnn_state, <EOL>[ self._membrane_potential[index], self._active_cond_sodium[index], self._inactive_cond_sodium[index], self._active_cond_potassium[index] ], <EOL>numpy.arange(t - step, t, int_step), <EOL>(index , ));<EOL>[ next_membrane[index], next_active_sodium[index], next_inactive_sodium[index], next_active_potassium[index] ] = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>:<NUM_LIT:4>];        <EOL><DEDENT>next_cn_membrane            = [<NUM_LIT:0.0>, <NUM_LIT:0.0>];<EOL>next_cn_active_sodium       = [<NUM_LIT:0.0>, <NUM_LIT:0.0>];<EOL>next_cn_inactive_sodium     = [<NUM_LIT:0.0>, <NUM_LIT:0.0>];<EOL>next_cn_active_potassium    = [<NUM_LIT:0.0>, <NUM_LIT:0.0>];<EOL>for index in range(<NUM_LIT:0>, len(self._central_element)):<EOL><INDENT>result = odeint(self.hnn_state, <EOL>[ self._central_element[index].membrane_potential, self._central_element[index].active_cond_sodium, self._central_element[index].inactive_cond_sodium, self._central_element[index].active_cond_potassium ], <EOL>numpy.arange(t - step, t, int_step), <EOL>(self._num_osc + index , ));<EOL>[ next_cn_membrane[index], next_cn_active_sodium[index], next_cn_inactive_sodium[index], next_cn_active_potassium[index] ] = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>:<NUM_LIT:4>];<EOL><DEDENT>self._noise = [ <NUM_LIT:1.0> + <NUM_LIT> * (random.random() * <NUM_LIT> - <NUM_LIT:1.0>) for i in range(self._num_osc)];<EOL>self.__update_peripheral_neurons(t, step, next_membrane, next_active_sodium, next_inactive_sodium, next_active_potassium);<EOL>self.__update_central_neurons(t, next_cn_membrane, next_cn_active_sodium, next_cn_inactive_sodium, next_cn_active_potassium);<EOL>return (next_membrane, next_cn_membrane)<EOL>

!
        @brief Caclculates new state of each oscillator in the network. Returns only excitatory state of oscillators.

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

        @return (list) New states of membrance potentials for peripheral oscillators and for cental elements as a list where
                the last two values correspond to central element 1 and 2.


def __update_peripheral_neurons(self, t, step, next_membrane, next_active_sodium, next_inactive_sodium, next_active_potassium):

self._membrane_potential = next_membrane[:];<EOL>self._active_cond_sodium = next_active_sodium[:];<EOL>self._inactive_cond_sodium = next_inactive_sodium[:];<EOL>self._active_cond_potassium = next_active_potassium[:];<EOL>for index in range(<NUM_LIT:0>, self._num_osc):<EOL><INDENT>if (self._pulse_generation[index] is False):<EOL><INDENT>if (self._membrane_potential[index] >= <NUM_LIT:0.0>):<EOL><INDENT>self._pulse_generation[index] = True;<EOL>self._pulse_generation_time[index].append(t);<EOL><DEDENT><DEDENT>elif (self._membrane_potential[index] < <NUM_LIT:0.0>):<EOL><INDENT>self._pulse_generation[index] = False;<EOL><DEDENT>if (self._link_weight3[index] == <NUM_LIT:0.0>):<EOL><INDENT>if (self._membrane_potential[index] > self._params.threshold):<EOL><INDENT>self._link_pulse_counter[index] += step;<EOL>if (self._link_pulse_counter[index] >= <NUM_LIT:1> / self._params.eps):<EOL><INDENT>self._link_weight3[index] = self._params.w3;<EOL>self._link_activation_time[index] = t;<EOL><DEDENT><DEDENT><DEDENT>elif ( not ((self._link_activation_time[index] < t) and (t < self._link_activation_time[index] + self._params.deltah)) ):<EOL><INDENT>self._link_weight3[index] = <NUM_LIT:0.0>;<EOL>self._link_pulse_counter[index] = <NUM_LIT:0.0>;<EOL><DEDENT><DEDENT>

!
        @brief Update peripheral neurons in line with new values of current in channels.

        @param[in] t (doubles): Current time of simulation.
        @param[in] step (uint): Step (time duration) during simulation when states of oscillators should be calculated.
        @param[in] next_membrane (list): New values of membrane potentials for peripheral neurons.
        @Param[in] next_active_sodium (list): New values of activation conductances of the sodium channels for peripheral neurons.
        @param[in] next_inactive_sodium (list): New values of inactivaton conductances of the sodium channels for peripheral neurons.
        @param[in] next_active_potassium (list): New values of activation conductances of the potassium channel for peripheral neurons.


def __update_central_neurons(self, t, next_cn_membrane, next_cn_active_sodium, next_cn_inactive_sodium, next_cn_active_potassium):

for index in range(<NUM_LIT:0>, len(self._central_element)):<EOL><INDENT>self._central_element[index].membrane_potential = next_cn_membrane[index];<EOL>self._central_element[index].active_cond_sodium = next_cn_active_sodium[index];<EOL>self._central_element[index].inactive_cond_sodium = next_cn_inactive_sodium[index];<EOL>self._central_element[index].active_cond_potassium = next_cn_active_potassium[index];<EOL>if (self._central_element[index].pulse_generation is False):<EOL><INDENT>if (self._central_element[index].membrane_potential >= <NUM_LIT:0.0>):<EOL><INDENT>self._central_element[index].pulse_generation = True;<EOL>self._central_element[index].pulse_generation_time.append(t);<EOL><DEDENT><DEDENT>elif (self._central_element[index].membrane_potential < <NUM_LIT:0.0>):<EOL><INDENT>self._central_element[index].pulse_generation = False;<EOL><DEDENT><DEDENT>

!
        @brief Update of central neurons in line with new values of current in channels.

        @param[in] t (doubles): Current time of simulation.
        @param[in] next_membrane (list): New values of membrane potentials for central neurons.
        @Param[in] next_active_sodium (list): New values of activation conductances of the sodium channels for central neurons.
        @param[in] next_inactive_sodium (list): New values of inactivaton conductances of the sodium channels for central neurons.
        @param[in] next_active_potassium (list): New values of activation conductances of the potassium channel for central neurons.


index = argv;<EOL>v = inputs[<NUM_LIT:0>]; <EOL>m = inputs[<NUM_LIT:1>]; <EOL>h = inputs[<NUM_LIT:2>]; <EOL>n = inputs[<NUM_LIT:3>]; <EOL>active_sodium_part = self._params.gNa * (m ** <NUM_LIT:3>) * h * (v - self._params.vNa);<EOL>inactive_sodium_part = self._params.gK * (n ** <NUM_LIT:4>) * (v - self._params.vK);<EOL>active_potassium_part = self._params.gL * (v - self._params.vL);<EOL>Iion = active_sodium_part + inactive_sodium_part + active_potassium_part;<EOL>Iext = <NUM_LIT:0.0>;<EOL>Isyn = <NUM_LIT:0.0>;<EOL>if (index < self._num_osc): <EOL><INDENT>Iext = self._stimulus[index] * self._noise[index];    <EOL>memory_impact1 = <NUM_LIT:0.0>;<EOL>for i in range(<NUM_LIT:0>, len(self._central_element[<NUM_LIT:0>].pulse_generation_time)):<EOL><INDENT>memory_impact1 += self.__alfa_function(t - self._central_element[<NUM_LIT:0>].pulse_generation_time[i], self._params.alfa_inhibitory, self._params.betta_inhibitory);<EOL><DEDENT>memory_impact2 = <NUM_LIT:0.0>;<EOL>for i in range(<NUM_LIT:0>, len(self._central_element[<NUM_LIT:1>].pulse_generation_time)):<EOL><INDENT>memory_impact2 += self.__alfa_function(t - self._central_element[<NUM_LIT:1>].pulse_generation_time[i], self._params.alfa_inhibitory, self._params.betta_inhibitory);<EOL><DEDENT>Isyn = self._params.w2 * (v - self._params.Vsyninh) * memory_impact1 + self._link_weight3[index] * (v - self._params.Vsyninh) * memory_impact2;<EOL><DEDENT>else:<EOL><INDENT>central_index = index - self._num_osc;<EOL>if (central_index == <NUM_LIT:0>):<EOL><INDENT>Iext = self._params.Icn1;   <EOL>memory_impact = <NUM_LIT:0.0>;<EOL>for index_oscillator in range(<NUM_LIT:0>, self._num_osc):<EOL><INDENT>for index_generation in range(<NUM_LIT:0>, len(self._pulse_generation_time[index_oscillator])):<EOL><INDENT>memory_impact += self.__alfa_function(t - self._pulse_generation_time[index_oscillator][index_generation], self._params.alfa_excitatory, self._params.betta_excitatory);<EOL><DEDENT><DEDENT>Isyn = self._params.w1 * (v - self._params.Vsynexc) * memory_impact;<EOL><DEDENT>elif (central_index == <NUM_LIT:1>):<EOL><INDENT>Iext = self._params.Icn2;   <EOL>Isyn = <NUM_LIT:0.0>;<EOL><DEDENT>else:<EOL><INDENT>assert <NUM_LIT:0>;<EOL><DEDENT><DEDENT>dv = -Iion + Iext - Isyn;<EOL>potential = v - self._params.vRest;<EOL>am = (<NUM_LIT> - <NUM_LIT:0.1> * potential) / (math.exp(<NUM_LIT> - <NUM_LIT:0.1> * potential) - <NUM_LIT:1.0>);<EOL>ah = <NUM_LIT> * math.exp(-potential / <NUM_LIT>);<EOL>an = (<NUM_LIT:0.1> - <NUM_LIT> * potential) / (math.exp(<NUM_LIT:1.0> - <NUM_LIT:0.1> * potential) - <NUM_LIT:1.0>);<EOL>bm = <NUM_LIT> * math.exp(-potential / <NUM_LIT>);<EOL>bh = <NUM_LIT:1.0> / (math.exp(<NUM_LIT> - <NUM_LIT:0.1> * potential) + <NUM_LIT:1.0>);<EOL>bn = <NUM_LIT> * math.exp(-potential / <NUM_LIT>);<EOL>dm = am * (<NUM_LIT:1.0> - m) - bm * m;<EOL>dh = ah * (<NUM_LIT:1.0> - h) - bh * h;<EOL>dn = an * (<NUM_LIT:1.0> - n) - bn * n;<EOL>return [dv, dm, dh, dn]<EOL>

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

        @param[in] inputs (list): States of oscillator for integration [v, m, h, n] (see description below).
        @param[in] t (double): Current time of simulation.
        @param[in] argv (tuple): Extra arguments that are not used for integration - index of oscillator.

        @return (list) new values of oscillator [v, m, h, n], where:
                v - membrane potantial of oscillator,
                m - activation conductance of the sodium channel,
                h - inactication conductance of the sodium channel,
                n - activation conductance of the potassium channel.


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

return allocate_sync_ensembles(self._membrane_dynamic_pointer, tolerance, <NUM_LIT>, None)<EOL>

!
        @brief Allocates 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 (lists) of indexes of synchronous oscillators. For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].


def __alfa_function(self, time, alfa, betta):

return alfa * time * math.exp(-betta * time)<EOL>

!
        @brief Calculates value of alfa-function for difference between spike generation time and current simulation time.

        @param[in] time (double): Difference between last spike generation time and current time.
        @param[in] alfa (double): Alfa parameter for alfa-function.
        @param[in] betta (double): Betta parameter for alfa-function.

        @return (double) Value of alfa-function.


<EOL>self.VF = <NUM_LIT:1.0><EOL>self.VL = <NUM_LIT:1.0><EOL>self.VT = <NUM_LIT><EOL>self.AF = <NUM_LIT:0.1><EOL>self.AL = <NUM_LIT:0.1><EOL>self.AT = <NUM_LIT:0.5><EOL>self.W = <NUM_LIT:1.0><EOL>self.M = <NUM_LIT:1.0><EOL>self.B = <NUM_LIT:0.1><EOL>self.FAST_LINKING = False<EOL>

!
        @brief    Default constructor of parameters for pulse-coupled neural network.
        @details  Constructor initializes parameters by default non-zero values that can be
                  used for simple simulation.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_get_output(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>return self.__dynamic<EOL>

!
        @brief (list) Returns oscillato outputs during simulation.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_get_time(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>return list(range(len(self)))<EOL>

!
        @brief (list) Returns sampling times when dynamic is measured during simulation.


def __init__(self, dynamic, ccore=None):

self.__OUTPUT_TRUE = <NUM_LIT:1>    <EOL>self.__OUTPUT_FALSE = <NUM_LIT:0>   <EOL>self.__dynamic = dynamic<EOL>self.__ccore_pcnn_dynamic_pointer = ccore<EOL>

!
        @brief Constructor of PCNN dynamic.

        @param[in] dynamic (list): Dynamic of oscillators on each step of simulation. If ccore pointer is specified than it can be ignored.
        @param[in] ccore (ctypes.pointer): Pointer to CCORE pcnn_dynamic instance in memory.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>wrapper.pcnn_dynamic_destroy(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>

!
        @brief Default destructor of PCNN dynamic.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_get_size(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>return len(self.__dynamic)<EOL>

!
        @brief (uint) Returns number of simulation steps that are stored in dynamic.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_allocate_sync_ensembles(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>sync_ensembles = []<EOL>traverse_oscillators = set()<EOL>number_oscillators = len(self.__dynamic[<NUM_LIT:0>])<EOL>for t in range(len(self.__dynamic) - <NUM_LIT:1>, <NUM_LIT:0>, -<NUM_LIT:1>):<EOL><INDENT>sync_ensemble = []<EOL>for i in range(number_oscillators):<EOL><INDENT>if self.__dynamic[t][i] == self.__OUTPUT_TRUE:<EOL><INDENT>if i not in traverse_oscillators:<EOL><INDENT>sync_ensemble.append(i)<EOL>traverse_oscillators.add(i)<EOL><DEDENT><DEDENT><DEDENT>if sync_ensemble != []:<EOL><INDENT>sync_ensembles.append(sync_ensemble)<EOL><DEDENT><DEDENT>return sync_ensembles<EOL>

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

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


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_allocate_spike_ensembles(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>spike_ensembles = []<EOL>number_oscillators = len(self.__dynamic[<NUM_LIT:0>])<EOL>for t in range(len(self.__dynamic)):<EOL><INDENT>spike_ensemble = []<EOL>for index in range(number_oscillators):<EOL><INDENT>if self.__dynamic[t][index] == self.__OUTPUT_TRUE:<EOL><INDENT>spike_ensemble.append(index)<EOL><DEDENT><DEDENT>if len(spike_ensemble) > <NUM_LIT:0>:<EOL><INDENT>spike_ensembles.append(spike_ensemble)<EOL><DEDENT><DEDENT>return spike_ensembles<EOL>

!
        @brief Analyses output dynamic of network and allocates spikes on each iteration as a list of indexes of oscillators.
        @details Each allocated spike ensemble represents list of indexes of oscillators whose output is active.

        @return (list) Spike ensembles of oscillators.


if self.__ccore_pcnn_dynamic_pointer is not None:<EOL><INDENT>return wrapper.pcnn_dynamic_allocate_time_signal(self.__ccore_pcnn_dynamic_pointer)<EOL><DEDENT>signal_vector_information = []<EOL>for t in range(<NUM_LIT:0>, len(self.__dynamic)):<EOL><INDENT>signal_vector_information.append(sum(self.__dynamic[t]))<EOL><DEDENT>return signal_vector_information<EOL>

!
        @brief Analyses output dynamic and calculates time signal (signal vector information) of network output.

        @return (list) Time signal of network output.


time_signal = pcnn_output_dynamic.allocate_time_signal()<EOL>time_axis = range(len(time_signal))<EOL>plt.subplot(<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:1>)<EOL>plt.plot(time_axis, time_signal, '<STR_LIT:->')<EOL>plt.ylabel("<STR_LIT>")<EOL>plt.xlabel("<STR_LIT>")<EOL>plt.grid(True)<EOL>plt.show()<EOL>

!
        @brief Shows time signal (signal vector information) using network dynamic during simulation.

        @param[in] pcnn_output_dynamic (pcnn_dynamic): Output dynamic of the pulse-coupled neural network.


@staticmethod<EOL><INDENT>def show_output_dynamic(pcnn_output_dynamic, separate_representation = False):<DEDENT>

draw_dynamics(pcnn_output_dynamic.time, pcnn_output_dynamic.output, x_title = "<STR_LIT:t>", y_title = "<STR_LIT>", separate = separate_representation)<EOL>

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

        @param[in] pcnn_output_dynamic (pcnn_dynamic): Output dynamic of the pulse-coupled neural network.
        @param[in] separate_representation (list): Consists of lists of oscillators where each such list consists of oscillator indexes that will be shown on separated stage.


figure = plt.figure()<EOL>time_signal = pcnn_output_dynamic.allocate_time_signal()<EOL>spike_ensembles = pcnn_output_dynamic.allocate_spike_ensembles()<EOL>spike_animation = []<EOL>ensemble_index = <NUM_LIT:0><EOL>for t in range(len(time_signal)):<EOL><INDENT>image_color_segments = [(<NUM_LIT:255>, <NUM_LIT:255>, <NUM_LIT:255>)] * (image_size[<NUM_LIT:0>] * image_size[<NUM_LIT:1>])<EOL>if time_signal[t] > <NUM_LIT:0>:<EOL><INDENT>for index_pixel in spike_ensembles[ensemble_index]:<EOL><INDENT>image_color_segments[index_pixel] = (<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>)<EOL><DEDENT>ensemble_index += <NUM_LIT:1><EOL><DEDENT>stage = numpy.array(image_color_segments, numpy.uint8)<EOL>stage = numpy.reshape(stage, image_size + ((<NUM_LIT:3>),)) <EOL>image_cluster = Image.fromarray(stage, '<STR_LIT>')<EOL>spike_animation.append( [ plt.imshow(image_cluster, interpolation='<STR_LIT:none>') ] )<EOL><DEDENT>im_ani = animation.ArtistAnimation(figure, spike_animation, interval=<NUM_LIT>, repeat_delay=<NUM_LIT>, blit=True)<EOL>plt.show()<EOL>

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

        @param[in] pcnn_output_dynamic (pcnn_dynamic): Output dynamic of the pulse-coupled neural network.
        @param[in] image_size (tuple): Image size represented as (height, width).


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

self._outputs = None            <EOL>self._feeding = None            <EOL>self._linking = None            <EOL>self._threshold = None          <EOL>self._params = None<EOL>self.__ccore_pcnn_pointer = None<EOL>if parameters is not None:<EOL><INDENT>self._params = parameters<EOL><DEDENT>else:<EOL><INDENT>self._params = pcnn_parameters()<EOL><DEDENT>if (ccore is True) and ccore_library.workable():<EOL><INDENT>network_height = height<EOL>network_width = width<EOL>if (type_conn == conn_type.GRID_FOUR) or (type_conn == conn_type.GRID_EIGHT):<EOL><INDENT>if (network_height is None) or (network_width is None):<EOL><INDENT>side_size = num_osc ** (<NUM_LIT:0.5>)<EOL>if side_size - math.floor(side_size) > <NUM_LIT:0>:<EOL><INDENT>raise NameError('<STR_LIT>')<EOL><DEDENT>network_height = int(side_size)<EOL>network_width = int(side_size)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>network_height = <NUM_LIT:0><EOL>network_width = <NUM_LIT:0><EOL><DEDENT>self.__ccore_pcnn_pointer = wrapper.pcnn_create(num_osc, type_conn, network_height, network_width, self._params)<EOL><DEDENT>else:<EOL><INDENT>super().__init__(num_osc, type_conn, type_conn_represent, height, width)<EOL>self._outputs = [<NUM_LIT:0.0>] * self._num_osc<EOL>self._feeding = [<NUM_LIT:0.0>] * self._num_osc<EOL>self._linking = [<NUM_LIT:0.0>] * self._num_osc<EOL>self._threshold = [ random.random() for i in range(self._num_osc) ]<EOL><DEDENT>

!
        @brief Constructor of oscillatory network is based on Kuramoto model.

        @param[in] num_osc (uint): Number of oscillators in the network.
        @param[in] parameters (pcnn_parameters): Parameters of the network.
        @param[in] type_conn (conn_type): Type of connection between oscillators in the network (all-to-all, grid, bidirectional list, etc.).
        @param[in] type_conn_represent (conn_represent): Internal representation of connection in the network: matrix or list.
        @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.
        @param[in] ccore (bool): If True then all interaction with object will be performed via CCORE library (C++ implementation of pyclustering).


if self.__ccore_pcnn_pointer is not None:<EOL><INDENT>wrapper.pcnn_destroy(self.__ccore_pcnn_pointer)<EOL>self.__ccore_pcnn_pointer = None<EOL><DEDENT>

!
        @brief Default destructor of PCNN.


if self.__ccore_pcnn_pointer is not None:<EOL><INDENT>return wrapper.pcnn_get_size(self.__ccore_pcnn_pointer)<EOL><DEDENT>return self._num_osc<EOL>

!
        @brief (uint) Returns size of oscillatory network.


if len(stimulus) != len(self):<EOL><INDENT>raise NameError('<STR_LIT>')<EOL><DEDENT>if self.__ccore_pcnn_pointer is not None:<EOL><INDENT>ccore_instance_dynamic = wrapper.pcnn_simulate(self.__ccore_pcnn_pointer, steps, stimulus)<EOL>return pcnn_dynamic(None, ccore_instance_dynamic)<EOL><DEDENT>dynamic = []<EOL>dynamic.append(self._outputs)<EOL>for step in range(<NUM_LIT:1>, steps, <NUM_LIT:1>):<EOL><INDENT>self._outputs = self._calculate_states(stimulus)<EOL>dynamic.append(self._outputs)<EOL><DEDENT>return pcnn_dynamic(dynamic)<EOL>

!
        @brief Performs static simulation of pulse coupled neural network using.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] stimulus (list): Stimulus for oscillators, number of stimulus should be equal to number of oscillators.

        @return (pcnn_dynamic) Dynamic of oscillatory network - output of each oscillator on each step of simulation.


feeding = [<NUM_LIT:0.0>] * self._num_osc<EOL>linking = [<NUM_LIT:0.0>] * self._num_osc<EOL>outputs = [<NUM_LIT:0.0>] * self._num_osc<EOL>threshold = [<NUM_LIT:0.0>] * self._num_osc<EOL>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>neighbors = self.get_neighbors(index)<EOL>feeding_influence = <NUM_LIT:0.0><EOL>linking_influence = <NUM_LIT:0.0><EOL>for index_neighbour in neighbors:<EOL><INDENT>feeding_influence += self._outputs[index_neighbour] * self._params.M<EOL>linking_influence += self._outputs[index_neighbour] * self._params.W<EOL><DEDENT>feeding_influence *= self._params.VF<EOL>linking_influence *= self._params.VL<EOL>feeding[index] = self._params.AF * self._feeding[index] + stimulus[index] + feeding_influence<EOL>linking[index] = self._params.AL * self._linking[index] + linking_influence<EOL>internal_activity = feeding[index] * (<NUM_LIT:1.0> + self._params.B * linking[index])<EOL>if internal_activity > self._threshold[index]:<EOL><INDENT>outputs[index] = self.__OUTPUT_TRUE<EOL><DEDENT>else:<EOL><INDENT>outputs[index] = self.__OUTPUT_FALSE<EOL><DEDENT>if self._params.FAST_LINKING is not True:<EOL><INDENT>threshold[index] = self._params.AT * self._threshold[index] + self._params.VT * outputs[index]<EOL><DEDENT><DEDENT>if self._params.FAST_LINKING is True:<EOL><INDENT>output_change = True    <EOL>previous_outputs = outputs[:]<EOL>while output_change is True:<EOL><INDENT>current_output_change = False<EOL>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>linking_influence = <NUM_LIT:0.0><EOL>neighbors = self.get_neighbors(index)<EOL>for index_neighbour in neighbors:<EOL><INDENT>linking_influence += previous_outputs[index_neighbour] * self._params.W<EOL><DEDENT>linking_influence *= self._params.VL<EOL>linking[index] = linking_influence<EOL>internal_activity = feeding[index] * (<NUM_LIT:1.0> + self._params.B * linking[index])<EOL>if internal_activity > self._threshold[index]:<EOL><INDENT>outputs[index] = self.__OUTPUT_TRUE<EOL><DEDENT>else:<EOL><INDENT>outputs[index] = self.__OUTPUT_FALSE<EOL><DEDENT>current_output_change |= (outputs[index] != previous_outputs[index])<EOL><DEDENT>output_change = current_output_change<EOL>if output_change is True:<EOL><INDENT>previous_outputs = outputs[:]<EOL><DEDENT><DEDENT><DEDENT>if self._params.FAST_LINKING is True:<EOL><INDENT>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>threshold[index] = self._params.AT * self._threshold[index] + self._params.VT * outputs[index]<EOL><DEDENT><DEDENT>self._feeding = feeding[:]<EOL>self._linking = linking[:]<EOL>self._threshold = threshold[:]<EOL>return outputs<EOL>

!
        @brief Calculates states of oscillators in the network for current step and stored them except outputs of oscillators.

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

        @return (list) New outputs for oscillators (do not stored it).


self.__amplitude = amplitude;<EOL>self.__time = time<EOL>

!
        @brief Constructor of Sync dynamic in frequency domain.

        @param[in] amplitude (list): Dynamic of oscillators on each step of simulation.
        @param[in] time (list): Simulation time where each time-point corresponds to amplitude-point.


return self.__amplitude<EOL>

!
        @brief (list) Returns output dynamic of the Sync network (amplitudes of each oscillator in the network) during simulation.


return self.__time<EOL>

!
        @brief (list) Returns time-points corresponds to dynamic-points points.


return len(self.__amplitude)<EOL>


if (index is <NUM_LIT:0>):<EOL><INDENT>return self.__time;<EOL><DEDENT>elif (index is <NUM_LIT:1>):<EOL><INDENT>return self.__amplitude;<EOL><DEDENT>else:<EOL><INDENT>raise NameError('<STR_LIT>' + index + '<STR_LIT>');<EOL><DEDENT>

!
        @brief Indexing of the dynamic.


return pyclustering.utils.allocate_sync_ensembles(self.__amplitude, tolerance, <NUM_LIT:0.0>)<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 extract_number_oscillations(self, index, amplitude_threshold):

return pyclustering.utils.extract_number_oscillations(self.__amplitude, index, amplitude_threshold)<EOL>

!
        @brief Extracts number of oscillations of specified oscillator.

        @param[in] index (uint): Index of oscillator whose dynamic is considered.
        @param[in] amplitude_threshold (double): Amplitude threshold when oscillation is taken into account, for example,
                    when oscillator amplitude is greater than threshold then oscillation is incremented.

        @return (uint) Number of oscillations of specified oscillator.


pyclustering.utils.draw_dynamics(fsync_output_dynamic.time, fsync_output_dynamic.output, x_title = "<STR_LIT:t>", y_title = "<STR_LIT>")<EOL>

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

        @param[in] fsync_output_dynamic (fsync_dynamic): Output dynamic of the fSync network.

        @see show_output_dynamics


pyclustering.utils.draw_dynamics_set(fsync_output_dynamics, "<STR_LIT:t>", "<STR_LIT>", None, None, False, False)<EOL>

!
        @brief Shows several output dynamics (output of each oscillator) during simulation.
        @details Each dynamic is presented on separate plot.

        @param[in] fsync_output_dynamics (list): list of output dynamics 'fsync_dynamic' of the fSync network.

        @see show_output_dynamic


def __init__(self, num_osc, factor_frequency = <NUM_LIT:1.0>, factor_radius = <NUM_LIT:1.0>, factor_coupling = <NUM_LIT:1.0>, type_conn = conn_type.ALL_TO_ALL, representation = conn_represent.MATRIX):

super().__init__(num_osc, type_conn, representation);<EOL>self.__frequency = factor_frequency if isinstance(factor_frequency, list) else [ fsync_network.__DEFAULT_FREQUENCY_VALUE * factor_frequency for _ in range(num_osc) ];<EOL>self.__radius = factor_radius if isinstance(factor_radius, list) else [ fsync_network.__DEFAULT_RADIUS_VALUE * factor_radius for _ in range(num_osc) ];<EOL>self.__coupling_strength = fsync_network.__DEFAULT_COUPLING_STRENGTH * factor_coupling;<EOL>self.__properties = [ self.__oscillator_property(index) for index in range(self._num_osc) ];<EOL>random.seed();<EOL>self.__amplitude = [ random.random() for _ in range(num_osc) ]<EOL>

!
        @brief Constructor of oscillatory network based on synchronization Kuramoto model and Landau-Stuart oscillator.

        @param[in] num_osc (uint): Amount oscillators in the network.
        @param[in] factor_frequency (double|list): Frequency of oscillators, it can be specified as common value for all oscillators by
                    single double value and for each separately by list.
        @param[in] factor_radius (double|list): Radius of oscillators that affects amplitude, it can be specified as common value for all oscillators by
                    single double value and for each separately by list.
        @param[in] factor_coupling (double): Coupling strength between oscillators.
        @param[in] type_conn (conn_type): Type of connection between oscillators in the network (all-to-all, grid, bidirectional list, etc.).
        @param[in] representation (conn_represent): Internal representation of connection in the network: matrix or list.


def simulate(self, steps, time, collect_dynamic = False):

dynamic_amplitude, dynamic_time = ([], []) if collect_dynamic is False else ([self.__amplitude], [<NUM_LIT:0>]);<EOL>step = time / steps;<EOL>int_step = step / <NUM_LIT>;<EOL>for t in numpy.arange(step, time + step, step):<EOL><INDENT>self.__amplitude = self.__calculate(t, step, int_step);<EOL>if collect_dynamic is True:<EOL><INDENT>dynamic_amplitude.append([ numpy.real(amplitude)[<NUM_LIT:0>] for amplitude in self.__amplitude ]);<EOL>dynamic_time.append(t);<EOL><DEDENT><DEDENT>if collect_dynamic is False:<EOL><INDENT>dynamic_amplitude.append([ numpy.real(amplitude)[<NUM_LIT:0>] for amplitude in self.__amplitude ]);<EOL>dynamic_time.append(time);<EOL><DEDENT>output_sync_dynamic = fsync_dynamic(dynamic_amplitude, dynamic_time);<EOL>return output_sync_dynamic<EOL>

!
        @brief Performs static simulation of oscillatory network.

        @param[in] steps (uint): Number simulation steps.
        @param[in] time (double): Time of simulation.
        @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' is True, than return dynamic for the whole simulation time,
                 otherwise returns only last values (last step of simulation) of output dynamic.

        @see simulate()
        @see simulate_dynamic()


def __calculate(self, t, step, int_step):

next_amplitudes = [<NUM_LIT:0.0>] * self._num_osc;<EOL>for index in range (<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>z = numpy.array(self.__amplitude[index], dtype = numpy.complex128, ndmin = <NUM_LIT:1>);<EOL>result = odeint(self.__calculate_amplitude, z.view(numpy.float64), numpy.arange(t - step, t, int_step), (index , ));<EOL>next_amplitudes[index] = (result[len(result) - <NUM_LIT:1>]).view(numpy.complex128);<EOL><DEDENT>return next_amplitudes<EOL>

!
        @brief Calculates new amplitudes for oscillators in the network in line with current step.

        @param[in] t (double): 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.

        @return (list) New states (phases) for oscillators.


return numpy.array(<NUM_LIT> * self.__frequency[index] + self.__radius[index]**<NUM_LIT:2>, dtype = numpy.complex128, ndmin = <NUM_LIT:1>)<EOL>

!
        @brief Calculate Landau-Stuart oscillator constant property that is based on frequency and radius.

        @param[in] index (uint): Oscillator index whose property is calculated.

        @return (double) Oscillator property.


def __landau_stuart(self, amplitude, index):

return (self.__properties[index] - numpy.absolute(amplitude) ** <NUM_LIT:2>) * amplitude<EOL>

!
        @brief Calculate Landau-Stuart state.

        @param[in] amplitude (double): Current amplitude of oscillator.
        @param[in] index (uint): Oscillator index whose state is calculated.

        @return (double) Landau-Stuart state.


def __synchronization_mechanism(self, amplitude, index):

sync_influence = <NUM_LIT:0.0>;<EOL>for k in range(self._num_osc):<EOL><INDENT>if self.has_connection(index, k) is True:<EOL><INDENT>amplitude_neighbor = numpy.array(self.__amplitude[k], dtype = numpy.complex128, ndmin = <NUM_LIT:1>);<EOL>sync_influence += amplitude_neighbor - amplitude;<EOL><DEDENT><DEDENT>return sync_influence * self.__coupling_strength / self._num_osc<EOL>

!
        @brief Calculate synchronization part using Kuramoto synchronization mechanism.

        @param[in] amplitude (double): Current amplitude of oscillator.
        @param[in] index (uint): Oscillator index whose synchronization influence is calculated.

        @return (double) Synchronization influence for the specified oscillator.


def __calculate_amplitude(self, amplitude, t, argv):

z = amplitude.view(numpy.complex);<EOL>dzdt = self.__landau_stuart(z, argv) + self.__synchronization_mechanism(z, argv);<EOL>return dzdt.view(numpy.float64)<EOL>

!
        @brief Returns new amplitude value for particular oscillator that is defined by index that is in 'argv' argument.
        @details The method is used for differential calculation.

        @param[in] amplitude (double): Current amplitude of oscillator.
        @param[in] t (double): Current time of simulation.
        @param[in] argv (uint): Index of the current oscillator.

        @return (double) New amplitude of the oscillator.


return self._dynamic<EOL>

!
        @brief (list) Returns outputs of oscillator during simulation.


return self._time<EOL>

!
        @brief (list) Returns sampling times when dynamic is measured during simulation.


if (len(amplitudes) != len(time)):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>self._dynamic = amplitudes;<EOL>self._time = time<EOL>

!
        @brief Constructor of hysteresis neural network dynamic.

        @param[in] amplitudes (list): Dynamic (amplitudes) of oscillators on each step of simulation.
        @param[in] time (list): Simulation time (timestamps of simulation steps) when amplitudes are stored.


return len(self._dynamic)<EOL>

!
        @brief (uint) Returns number of simulation steps that are stored in dynamic.


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

clusters = [ [<NUM_LIT:0>] ];<EOL>number_oscillators = len(self._dynamic[<NUM_LIT:0>]);<EOL>for i in range(<NUM_LIT:1>, number_oscillators, <NUM_LIT:1>):<EOL><INDENT>captured_neuron = True;<EOL>for cluster in clusters:<EOL><INDENT>neuron_index = cluster[<NUM_LIT:0>];<EOL>analysis_steps = threshold_steps;<EOL>if (len(self._dynamic) < analysis_steps):<EOL><INDENT>analysis_steps = len(self._dynamic);<EOL><DEDENT>analysis_start_step_index = len(self._dynamic) - <NUM_LIT:1>;<EOL>for step in range(analysis_start_step_index, analysis_start_step_index - analysis_steps, -<NUM_LIT:1>):<EOL><INDENT>neuron_amplitude = self._dynamic[step][neuron_index];<EOL>candidate_amplitude = self._dynamic[step][i];<EOL>if ( not (candidate_amplitude < (neuron_amplitude + tolerance)) or not (candidate_amplitude > (neuron_amplitude - tolerance)) ):<EOL><INDENT>captured_neuron = False;<EOL>break;<EOL><DEDENT><DEDENT>if ( captured_neuron is True ):<EOL><INDENT>cluster.append(i);<EOL>break;<EOL><DEDENT><DEDENT>if (captured_neuron is False):<EOL><INDENT>clusters.append([i]);<EOL><DEDENT><DEDENT>return clusters<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.
        @param[in] threshold_steps (uint): Number of steps from the end of simulation that should be analysed for ensemble allocation.
                    If amout of simulation steps has been less than threshold steps than amount of steps will be reduced to amout
                    of simulation steps.

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


draw_dynamics(hysteresis_output_dynamic.time, hysteresis_output_dynamic.output, x_title = "<STR_LIT>", y_title = "<STR_LIT>")<EOL>

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

        @param[in] hysteresis_output_dynamic (hysteresis_dynamic): Output dynamic of the hysteresis oscillatory network.


return self._outputs<EOL>

!
        @brief Returns current outputs of neurons.

        @return (list) Current outputs of neurons.


self._outputs = [val for val in values];<EOL>self._outputs_buffer = [val for val in values]<EOL>

!
        @brief Sets outputs of neurons.


return self._states<EOL>

!
        @brief Return current states of neurons.

        @return (list) States of neurons.


self._states = [val for val in values]<EOL>

!
        @brief Set current states of neurons.


def __init__(self, num_osc, own_weight = -<NUM_LIT:4>, neigh_weight = -<NUM_LIT:1>, type_conn = conn_type.ALL_TO_ALL, type_conn_represent = conn_represent.MATRIX):

super().__init__(num_osc, type_conn, type_conn_represent);<EOL>self._states = [<NUM_LIT:0>] * self._num_osc;<EOL>self._outputs = [-<NUM_LIT:1>] * self._num_osc;<EOL>self._outputs_buffer = [-<NUM_LIT:1>] * self._num_osc;<EOL>self._weight = list();<EOL>for index in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>self._weight.append( [neigh_weight] * self._num_osc);<EOL>self._weight[index][index] = own_weight;<EOL><DEDENT>

!
        @brief Constructor of hysteresis oscillatory network.

        @param[in] num_osc (uint): Number of oscillators in the network.
        @param[in] own_weight (double): Weight of connection from oscillator to itself - own weight.
        @param[in] neigh_weight (double): Weight of connection between oscillators.
        @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.


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

xi = inputs[<NUM_LIT:0>];<EOL>index = argv;<EOL>impact = self._weight[index][index] * self._outputs[index];<EOL>for i in range(<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):<EOL><INDENT>if (self.has_connection(i, index)):<EOL><INDENT>impact += self._weight[index][i] * self._outputs[i];<EOL><DEDENT><DEDENT>x = -xi + impact;<EOL>if (xi > <NUM_LIT:1>): self._outputs_buffer[index] = <NUM_LIT:1>; <EOL>if (xi < -<NUM_LIT:1>): self._outputs_buffer[index] = -<NUM_LIT:1>;<EOL>return x<EOL>

!
        @brief Returns new value of the neuron (oscillator).

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

        @return (double) New value of the neuron.


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

return self.simulate_static(steps, time, solution, collect_dynamic)<EOL>

!
        @brief Performs static simulation of hysteresis oscillatory network.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] solution (solve_type): Type of solution (solving).
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.

        @return (hysteresis_dynamic) 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 simulate_static(self, steps, time, solution = solve_type.RK4, collect_dynamic = False):

<EOL>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>dyn_state = None;<EOL>dyn_time = None;<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_state = [];<EOL>dyn_time = [];<EOL>dyn_state.append(self._states);<EOL>dyn_time.append(<NUM_LIT:0>);<EOL><DEDENT>step = time / steps;<EOL>int_step = step / <NUM_LIT>;<EOL>for t in numpy.arange(step, time + step, step):<EOL><INDENT>self._states = self._calculate_states(solution, t, step, int_step);<EOL>if (collect_dynamic is True):<EOL><INDENT>dyn_state.append(self._states);<EOL>dyn_time.append(t);<EOL><DEDENT><DEDENT>if (collect_dynamic is False):<EOL><INDENT>dyn_state.append(self._states);<EOL>dyn_time.append(time);<EOL><DEDENT>return hysteresis_dynamic(dyn_state, dyn_time)<EOL>


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

next_states = [<NUM_LIT:0>] * self._num_osc;<EOL>for index in range (<NUM_LIT:0>, self._num_osc, <NUM_LIT:1>):            <EOL><INDENT>result = odeint(self._neuron_states, self._states[index], numpy.arange(t - step, t, int_step), (index , ));<EOL>next_states[index] = result[len(result) - <NUM_LIT:1>][<NUM_LIT:0>];<EOL><DEDENT>self._outputs = [val for val in self._outputs_buffer];<EOL>return next_states<EOL>

!
        @brief Calculates new states for neurons using differential calculus. Returns new states for neurons.

        @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.

        @return (list) New states for neurons.


super().__init__(phase, time, ccore)<EOL>

!
        @brief Constructor of syncpr dynamic.

        @param[in] phase (list): Dynamic of oscillators on each step of simulation. If ccore pointer is specified than it can be ignored.
        @param[in] time (list): Simulation time.
        @param[in] ccore (ctypes.pointer): Pointer to CCORE sync_dynamic instance in memory.


@staticmethod<EOL><INDENT>def show_pattern(syncpr_output_dynamic, image_height, image_width):<DEDENT>

number_pictures = len(syncpr_output_dynamic);<EOL>iteration_math_step = <NUM_LIT:1.0>;<EOL>if (number_pictures > <NUM_LIT:50>):<EOL><INDENT>iteration_math_step = number_pictures / <NUM_LIT>;<EOL>number_pictures = <NUM_LIT:50>;<EOL><DEDENT>number_cols = int(numpy.ceil(number_pictures ** <NUM_LIT:0.5>));<EOL>number_rows = int(numpy.ceil(number_pictures / number_cols));<EOL>real_index = <NUM_LIT:0>, <NUM_LIT:0>;<EOL>double_indexer = True;<EOL>if ( (number_cols == <NUM_LIT:1>) or (number_rows == <NUM_LIT:1>) ):<EOL><INDENT>real_index = <NUM_LIT:0>;<EOL>double_indexer = False;<EOL><DEDENT>(_, axarr) = plt.subplots(number_rows, number_cols);<EOL>if (number_pictures > <NUM_LIT:1>):<EOL><INDENT>plt.setp([ax for ax in axarr], visible = False);<EOL><DEDENT>iteration_display = <NUM_LIT:0.0>;<EOL>for iteration in range(len(syncpr_output_dynamic)):<EOL><INDENT>if (iteration >= iteration_display):<EOL><INDENT>iteration_display += iteration_math_step;<EOL>ax_handle = axarr;<EOL>if (number_pictures > <NUM_LIT:1>):<EOL><INDENT>ax_handle = axarr[real_index];<EOL><DEDENT>syncpr_visualizer.__show_pattern(ax_handle, syncpr_output_dynamic, image_height, image_width, iteration);<EOL>if (double_indexer is True):<EOL><INDENT>real_index = real_index[<NUM_LIT:0>], real_index[<NUM_LIT:1>] + <NUM_LIT:1>;<EOL>if (real_index[<NUM_LIT:1>] >= number_cols):<EOL><INDENT>real_index = real_index[<NUM_LIT:0>] + <NUM_LIT:1>, <NUM_LIT:0>; <EOL><DEDENT><DEDENT>else:<EOL><INDENT>real_index += <NUM_LIT:1>;<EOL><DEDENT><DEDENT><DEDENT>plt.show()<EOL>

!
        @brief Displays evolution of phase oscillators as set of patterns where the last one means final result of recognition.

        @param[in] syncpr_output_dynamic (syncpr_dynamic): Output dynamic of a syncpr network.
        @param[in] image_height (uint): Height of the pattern (image_height * image_width should be equal to number of oscillators).
        @param[in] image_width (uint): Width of the pattern.


@staticmethod<EOL><INDENT>def animate_pattern_recognition(syncpr_output_dynamic, image_height, image_width, animation_velocity = <NUM_LIT>, title = None, save_movie = None):<DEDENT>

figure = plt.figure();<EOL>def init_frame():<EOL><INDENT>return frame_generation(<NUM_LIT:0>);<EOL><DEDENT>def frame_generation(index_dynamic):<EOL><INDENT>figure.clf();<EOL>if (title is not None):<EOL><INDENT>figure.suptitle(title, fontsize = <NUM_LIT>, fontweight = '<STR_LIT>')<EOL><DEDENT>ax1 = figure.add_subplot(<NUM_LIT>, projection='<STR_LIT>');<EOL>ax2 = figure.add_subplot(<NUM_LIT>);<EOL>dynamic = syncpr_output_dynamic.output[index_dynamic];<EOL>artist1, = ax1.plot(dynamic, [<NUM_LIT:1.0>] * len(dynamic), marker = '<STR_LIT:o>', color = '<STR_LIT>', ls = '<STR_LIT>');<EOL>artist2 = syncpr_visualizer.__show_pattern(ax2, syncpr_output_dynamic, image_height, image_width, index_dynamic);<EOL>return [ artist1, artist2 ];<EOL><DEDENT>cluster_animation = animation.FuncAnimation(figure, frame_generation, len(syncpr_output_dynamic), interval = animation_velocity, init_func = init_frame, repeat_delay = <NUM_LIT>);<EOL>if (save_movie is not None):<EOL><INDENT>plt.rcParams['<STR_LIT>'] = '<STR_LIT>';<EOL>ffmpeg_writer = animation.FFMpegWriter();<EOL>cluster_animation.save(save_movie, writer = ffmpeg_writer, fps = <NUM_LIT:15>);<EOL>

!
        @brief Shows animation of pattern recognition process that has been preformed by the oscillatory network.

        @param[in] syncpr_output_dynamic (syncpr_dynamic): Output dynamic of a syncpr network.
        @param[in] image_height (uint): Height of the pattern (image_height * image_width should be equal to number of oscillators).
        @param[in] image_width (uint): Width of the pattern.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds.
        @param[in] title (string): Title of the animation that is displayed on a figure if it is specified.
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.


@staticmethod<EOL><INDENT>def __show_pattern(ax_handle, syncpr_output_dynamic, image_height, image_width, iteration):<DEDENT>

current_dynamic = syncpr_output_dynamic.output[iteration];<EOL>stage_picture = [(<NUM_LIT:255>, <NUM_LIT:255>, <NUM_LIT:255>)] * (image_height * image_width);<EOL>for index_phase in range(len(current_dynamic)):<EOL><INDENT>phase = current_dynamic[index_phase];<EOL>pixel_color = math.floor( phase * (<NUM_LIT:255> / (<NUM_LIT:2> * math.pi)) );<EOL>stage_picture[index_phase] = (pixel_color, pixel_color, pixel_color);<EOL><DEDENT>stage = numpy.array(stage_picture, numpy.uint8);<EOL>stage = numpy.reshape(stage, (image_height, image_width) + ((<NUM_LIT:3>),)); <EOL>image_cluster = Image.fromarray(stage);<EOL>artist = ax_handle.imshow(image_cluster, interpolation = '<STR_LIT:none>');<EOL>plt.setp(ax_handle, visible = True);<EOL>ax_handle.xaxis.set_ticklabels([]);<EOL>ax_handle.yaxis.set_ticklabels([]);<EOL>ax_handle.xaxis.set_ticks_position('<STR_LIT:none>');<EOL>ax_handle.yaxis.set_ticks_position('<STR_LIT:none>');<EOL>return artist<EOL>

!
        @brief Draws pattern on specified ax.

        @param[in] ax_handle (Axis): Axis where pattern should be drawn.
        @param[in] syncpr_output_dynamic (syncpr_dynamic): Output dynamic of a syncpr network.
        @param[in] image_height (uint): Height of the pattern (image_height * image_width should be equal to number of oscillators).
        @param[in] image_width (uint): Width of the pattern.
        @param[in] iteration (uint): Simulation iteration that should be used for extracting pattern.

        @return (matplotlib.artist) Artist (pattern) that is rendered in the canvas.


def __init__(self, num_osc, increase_strength1, increase_strength2, ccore = True):

if ( (ccore is True) and ccore_library.workable() ):<EOL><INDENT>self._ccore_network_pointer = wrapper.syncpr_create(num_osc, increase_strength1, increase_strength2);<EOL><DEDENT>else:<EOL><INDENT>self._increase_strength1 = increase_strength1;<EOL>self._increase_strength2 = increase_strength2;<EOL>self._coupling = [ [<NUM_LIT:0.0> for i in range(num_osc)] for j in range(num_osc) ];<EOL>super().__init__(num_osc, <NUM_LIT:1>, <NUM_LIT:0>, conn_type.ALL_TO_ALL, conn_represent.MATRIX, initial_type.RANDOM_GAUSSIAN, ccore)<EOL><DEDENT>

!
        @brief Constructor of oscillatory network for pattern recognition based on Kuramoto model.

        @param[in] num_osc (uint): Number of oscillators in the network.
        @param[in] increase_strength1 (double): Parameter for increasing strength of the second term of the Fourier component.
        @param[in] increase_strength2 (double): Parameter for increasing strength of the third term of the Fourier component.
        @param[in] ccore (bool): If True simulation is performed by CCORE library (C++ implementation of pyclustering).


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

!
        @brief Default destructor of syncpr.


if (self._ccore_network_pointer is not None):<EOL><INDENT>return wrapper.syncpr_get_size(self._ccore_network_pointer);<EOL><DEDENT>else:<EOL><INDENT>return self._num_osc;<EOL><DEDENT>

!
        @brief Returns size of the network.


<EOL>for pattern in samples:<EOL><INDENT>self.__validate_pattern(pattern);<EOL><DEDENT>if (self._ccore_network_pointer is not None):<EOL><INDENT>return wrapper.syncpr_train(self._ccore_network_pointer, samples);<EOL><DEDENT>length = len(self);<EOL>number_samples = len(samples);<EOL>for i in range(length):<EOL><INDENT>for j in range(i + <NUM_LIT:1>, len(self), <NUM_LIT:1>):<EOL><INDENT>for p in range(number_samples):<EOL><INDENT>value1 = samples[p][i];<EOL>value2 = samples[p][j];<EOL>self._coupling[i][j] += value1 * value2;<EOL><DEDENT>self._coupling[i][j] /= length;<EOL>self._coupling[j][i] = self._coupling[i][j];<EOL><DEDENT><DEDENT>

!
        @brief Trains syncpr network using Hebbian rule for adjusting strength of connections between oscillators during training.

        @param[in] samples (list): list of patterns where each pattern is represented by list of features that are equal to [-1; 1].


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

return self.simulate_static(steps, time, pattern, solution, collect_dynamic)<EOL>

!
        @brief Performs static simulation of syncpr oscillatory network.
        @details In other words network performs pattern recognition during simulation.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] pattern (list): Pattern for recognition represented by list of features that are equal to [-1; 1].
        @param[in] solution (solve_type): Type of solver that should be used for simulation.
        @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.

        @see simulate_dynamic()
        @see simulate_static()


def simulate_dynamic(self, pattern, order = <NUM_LIT>, solution = solve_type.RK4, collect_dynamic = False, step = <NUM_LIT:0.1>, int_step = <NUM_LIT>, threshold_changes = <NUM_LIT>):

self.__validate_pattern(pattern);<EOL>if (self._ccore_network_pointer is not None):<EOL><INDENT>ccore_instance_dynamic = wrapper.syncpr_simulate_dynamic(self._ccore_network_pointer, pattern, order, solution, collect_dynamic, step);<EOL>return syncpr_dynamic(None, None, ccore_instance_dynamic);<EOL><DEDENT>for i in range(<NUM_LIT:0>, len(pattern), <NUM_LIT:1>):<EOL><INDENT>if (pattern[i] > <NUM_LIT:0.0>):<EOL><INDENT>self._phases[i] = <NUM_LIT:0.0>;<EOL><DEDENT>else:<EOL><INDENT>self._phases[i] = math.pi / <NUM_LIT>;<EOL><DEDENT><DEDENT>time_counter = <NUM_LIT:0>;<EOL>previous_order = <NUM_LIT:0>;<EOL>current_order = self.__calculate_memory_order(pattern);<EOL>dyn_phase = [];<EOL>dyn_time = [];<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(<NUM_LIT:0>);<EOL><DEDENT>while (current_order < order):<EOL><INDENT>self._phases = self._calculate_phases(solution, time_counter, step, int_step);<EOL>time_counter += step;<EOL>if (collect_dynamic == True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(time_counter);<EOL><DEDENT>previous_order = current_order;<EOL>current_order = self.__calculate_memory_order(pattern);<EOL>if (abs(current_order - previous_order) < threshold_changes):<EOL><INDENT>break;<EOL><DEDENT><DEDENT>if (collect_dynamic != True):<EOL><INDENT>dyn_phase.append(self._phases);<EOL>dyn_time.append(time_counter);<EOL><DEDENT>output_sync_dynamic = syncpr_dynamic(dyn_phase, dyn_time, None);<EOL>return output_sync_dynamic<EOL>

!
        @brief Performs dynamic simulation of the network until stop condition is not reached.
        @details In other words network performs pattern recognition during simulation.
                 Stop condition is defined by input argument 'order' that represents memory order, but
                 process of simulation can be stopped if convergance rate is low whose threshold is defined
                 by the argument 'threshold_changes'.

        @param[in] pattern (list): Pattern for recognition represented by list of features that are equal to [-1; 1].
        @param[in] order (double): Order of process synchronization, distributed 0..1.
        @param[in] solution (solve_type): Type of solution.
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.
        @param[in] step (double): Time step of one iteration of simulation.
        @param[in] int_step (double): Integration step, should be less than step.
        @param[in] threshold_changes (double): Additional stop condition that helps prevent infinite simulation, defines limit of changes of oscillators between current and previous steps.

        @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.

        @see simulate()
        @see simulate_static()


def simulate_static(self, steps, time, pattern, solution = solve_type.FAST, collect_dynamic = False):

self.__validate_pattern(pattern);<EOL>if (self._ccore_network_pointer is not None):<EOL><INDENT>ccore_instance_dynamic = wrapper.syncpr_simulate_static(self._ccore_network_pointer, steps, time, pattern, solution, collect_dynamic);<EOL>return syncpr_dynamic(None, None, ccore_instance_dynamic);<EOL><DEDENT>for i in range(<NUM_LIT:0>, len(pattern), <NUM_LIT:1>):<EOL><INDENT>if (pattern[i] > <NUM_LIT:0.0>):<EOL><INDENT>self._phases[i] = <NUM_LIT:0.0>;<EOL><DEDENT>else:<EOL><INDENT>self._phases[i] = math.pi / <NUM_LIT>;<EOL><DEDENT><DEDENT>return super().simulate_static(steps, time, solution, collect_dynamic)<EOL>

!
        @brief Performs static simulation of syncpr oscillatory network.
        @details In other words network performs pattern recognition during simulation.

        @param[in] steps (uint): Number steps of simulations during simulation.
        @param[in] time (double): Time of simulation.
        @param[in] pattern (list): Pattern for recognition represented by list of features that are equal to [-1; 1].
        @param[in] solution (solve_type): Type of solution.
        @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.

        @see simulate()
        @see simulate_dynamic()


self.__validate_pattern(pattern);<EOL>if (self._ccore_network_pointer is not None):<EOL><INDENT>return wrapper.syncpr_memory_order(self._ccore_network_pointer, pattern);<EOL><DEDENT>else:<EOL><INDENT>return self.__calculate_memory_order(pattern);<EOL><DEDENT>

!
        @brief Calculates function of the memorized 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].

        @return (double) Order of memory for the specified pattern.


memory_order = <NUM_LIT:0.0>;<EOL>for index in range(len(self)):<EOL><INDENT>memory_order += pattern[index] * cmath.exp( <NUM_LIT> * self._phases[index] );<EOL><DEDENT>memory_order /= len(self);<EOL>return abs(memory_order)<EOL>

!
        @brief Calculates function of the memorized pattern without any pattern validation.

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

        @return (double) Order of memory for the specified pattern.