3 @brief Neural Network: Oscillatory Neural Network based on Kuramoto model 4 @details Implementation based on paper @cite article::syncnet::1, @cite article::nnet::sync::1, @cite inproceedings::net::sync::1. 6 @authors Andrei Novikov (pyclustering@yandex.ru) 8 @copyright GNU Public License 10 @cond GNU_PUBLIC_LICENSE 11 PyClustering is free software: you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation, either version 3 of the License, or 14 (at your option) any later version. 16 PyClustering is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 33 import matplotlib.pyplot
as plt
34 import matplotlib.animation
as animation
35 except Exception
as error_instance:
36 warnings.warn(
"Impossible to import matplotlib (please, install 'matplotlib'), pyclustering's visualization " 37 "functionality is not available (details: '%s')." % str(error_instance))
39 import pyclustering.core.sync_wrapper
as wrapper
41 from pyclustering.core.wrapper
import ccore_library
43 from scipy.integrate
import odeint
45 from pyclustering.nnet import network, conn_represent, conn_type, initial_type, solve_type
51 @brief Provides services to calculate order parameter and local order parameter that are used 52 for synchronization level estimation. 58 @brief Calculates level of global synchronization (order parameter) for input phases. 59 @details This parameter is tend 1.0 when the oscillatory network close to global synchronization and it tend to 0.0 when 60 desynchronization is observed in the network. 62 @param[in] oscillator_phases (list): List of oscillator phases that are used for level of global synchronization. 64 @return (double) Level of global synchronization (order parameter). 66 @see calculate_order_parameter() 73 for phase
in oscillator_phases:
74 exp_amount += math.expm1( abs(1j * phase) );
75 average_phase += phase;
77 exp_amount /= len(oscillator_phases);
78 average_phase = math.expm1( abs(1j * (average_phase / len(oscillator_phases))) );
80 return abs(average_phase) / abs(exp_amount);
86 @brief Calculates level of local synchorization (local order parameter) for input phases for the specified network. 87 @details This parameter is tend 1.0 when the oscillatory network close to local synchronization and it tend to 0.0 when 88 desynchronization is observed in the network. 90 @param[in] oscillator_phases (list): List of oscillator phases that are used for level of local (partial) synchronization. 91 @param[in] oscillatory_network (sync): Instance of oscillatory network whose connections are required for calculation. 93 @return (double) Level of local synchronization (local order parameter). 100 for i
in range(0, len(oscillatory_network), 1):
101 for j
in range(0, len(oscillatory_network), 1):
102 if (oscillatory_network.has_connection(i, j) ==
True):
103 exp_amount += math.exp(-abs(oscillator_phases[j] - oscillator_phases[i]));
109 return exp_amount / num_neigh;
115 @brief Represents output dynamic of Sync. 122 @brief (list) Returns output dynamic of the Sync network (phase coordinates of each oscillator in the network) during simulation. 134 @brief (list) Returns sampling times when dynamic is measured during simulation. 145 @brief Constructor of Sync dynamic. 147 @param[in] phase (list): Dynamic of oscillators on each step of simulation. If ccore pointer is specified than it can be ignored. 148 @param[in] time (list): Simulation time. 149 @param[in] ccore (ctypes.pointer): Pointer to CCORE sync_dynamic instance in memory. 160 @brief Default destructor of Sync dynamic. 169 @brief Returns number of simulation steps that are stored in dynamic. 170 @return (uint) Number of simulation steps that are stored in dynamic. 181 @brief Indexing of the dynamic. 191 raise NameError(
'Out of range ' + index +
': only indexes 0 and 1 are supported.');
196 @brief Allocate clusters in line with ensembles of synchronous oscillators where each synchronous ensemble corresponds to only one cluster. 198 @param[in] tolerance (double): Maximum error for allocation of synchronous ensemble oscillators. 199 @param[in] indexes (list): List of real object indexes and it should be equal to amount of oscillators (in case of 'None' - indexes are in range [0; amount_oscillators]). 200 @param[in] iteration (uint): Iteration of simulation that should be used for allocation. 202 @return (list) Grours (lists) of indexes of synchronous oscillators. 203 For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ]. 210 if (indexes
is not None):
211 for ensemble
in ensembles:
212 for index
in range(len(ensemble)):
213 ensemble[index] = indexes[ ensemble[index] ];
220 number_oscillators = len(self.
_dynamic[0]);
223 if (iteration
is None):
226 last_state = self.
_dynamic[iteration];
229 if (number_oscillators > 0):
230 clusters.append([0]);
232 for i
in range(1, number_oscillators, 1):
233 cluster_allocated =
False;
234 for cluster
in clusters:
235 for neuron_index
in cluster:
236 last_state_shifted = abs(last_state[i] - 2 * pi);
238 if ( ( (last_state[i] < (last_state[neuron_index] + tolerance))
and (last_state[i] > (last_state[neuron_index] - tolerance)) )
or 239 ( (last_state_shifted < (last_state[neuron_index] + tolerance))
and (last_state_shifted > (last_state[neuron_index] - tolerance)) ) ):
240 cluster_allocated =
True;
243 if (indexes
is not None):
244 real_index = indexes[i];
246 cluster.append(real_index);
249 if (cluster_allocated ==
True):
252 if (cluster_allocated ==
False):
253 clusters.append([i]);
260 @brief Returns 2D matrix of phase values of oscillators at the specified iteration of simulation. 261 @details User should ensure correct matrix sizes in line with following expression grid_width x grid_height that should be equal to 262 amount of oscillators otherwise exception is thrown. If grid_width or grid_height are not specified than phase matrix size 263 will by calculated automatically by square root. 265 @param[in] grid_width (uint): Width of the allocated matrix. 266 @param[in] grid_height (uint): Height of the allocated matrix. 267 @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated. 268 If iternation number is not specified, the last step of simulation is used for the matrix allocation. 270 @return (list) Phase value matrix of oscillators with size [number_oscillators x number_oscillators]. 274 output_dynamic = self.
output;
276 if ( (output_dynamic
is None)
or (len(output_dynamic) == 0) ):
279 current_dynamic = output_dynamic[len(output_dynamic) - 1];
280 if (iteration
is not None):
281 current_dynamic = output_dynamic[iteration];
283 width_matrix = grid_width;
284 height_matrix = grid_height;
285 number_oscillators = len(current_dynamic);
286 if ( (width_matrix
is None)
or (height_matrix
is None) ):
287 width_matrix = int(math.ceil(math.sqrt(number_oscillators)));
288 height_matrix = width_matrix;
290 if (number_oscillators != width_matrix * height_matrix):
291 raise NameError(
"Impossible to allocate phase matrix with specified sizes, amout of neurons should be equal to grid_width * grid_height.");
294 phase_matrix = [ [ 0.0
for i
in range(width_matrix) ]
for j
in range(height_matrix) ];
295 for i
in range(height_matrix):
296 for j
in range(width_matrix):
297 phase_matrix[i][j] = current_dynamic[j + i * width_matrix];
304 @brief Allocate correlation matrix between oscillators at the specified step of simulation. 306 @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated. 307 If iternation number is not specified, the last step of simulation is used for the matrix allocation. 309 @return (list) Correlation matrix between oscillators with size [number_oscillators x number_oscillators]. 320 current_dynamic = dynamic[len(dynamic) - 1];
322 if (iteration
is not None):
323 current_dynamic = dynamic[iteration];
325 number_oscillators = len(dynamic[0]);
326 affinity_matrix = [ [ 0.0
for i
in range(number_oscillators) ]
for j
in range(number_oscillators) ];
328 for i
in range(number_oscillators):
329 for j
in range(number_oscillators):
330 phase1 = current_dynamic[i];
331 phase2 = current_dynamic[j];
333 affinity_matrix[i][j] = abs(math.sin(phase1 - phase2));
335 return affinity_matrix;
340 @brief Calculates level of global synchorization (order parameter). 341 @details This parameter is tend 1.0 when the oscillatory network close to global synchronization and it tend to 0.0 when 342 desynchronization is observed in the network. Order parameter is calculated using following equation: 345 r_{c}=\frac{1}{Ne^{i\varphi }}\sum_{j=0}^{N}e^{i\theta_{j}}; 348 where \f$\varphi\f$ is a average phase coordinate in the network, \f$N\f$ is an amount of oscillators in the network. 350 @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the last iteration is used. 351 @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then 'start_iteration' + 1 is used. 355 oscillatory_network = sync(16, type_conn = conn_type.ALL_TO_ALL); 356 output_dynamic = oscillatory_network.simulate_static(100, 10); 358 print("Order parameter at the last step: ", output_dynamic.calculate_order_parameter()); 359 print("Order parameter at the first step:", output_dynamic.calculate_order_parameter(0)); 360 print("Order parameter evolution between 40 and 50 steps:", output_dynamic.calculate_order_parameter(40, 50)); 363 @return (list) List of levels of global synchronization (order parameter evolution). 375 for index
in range(start_iteration, stop_iteration):
376 sequence_order.append(order_estimator.calculate_sync_order(self.
output[index]));
378 return sequence_order;
383 @brief Calculates local order parameter. 384 @details Local order parameter or so-called level of local or partial synchronization is calculated by following expression: 387 r_{c}=\left | \sum_{i=0}^{N} \frac{1}{N_{i}} \sum_{j=0}e^{ \theta_{j} - \theta_{i} } \right |; 390 where N - total amount of oscillators in the network and \f$N_{i}\f$ - amount of neighbors of oscillator with index \f$i\f$. 392 @param[in] oscillatory_network (sync): Sync oscillatory network whose structure of connections is required for calculation. 393 @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the last iteration is used. 394 @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then 'start_iteration' + 1 is used. 396 @return (list) List of levels of local (partial) synchronization (local order parameter evolution). 403 network_pointer = oscillatory_network._ccore_network_pointer;
404 return wrapper.sync_dynamic_calculate_local_order(self.
_ccore_sync_dynamic_pointer, network_pointer, start_iteration, stop_iteration);
406 sequence_local_order = [];
407 for index
in range(start_iteration, stop_iteration):
408 sequence_local_order.append(order_estimator.calculate_local_sync_order(self.
output[index], oscillatory_network));
410 return sequence_local_order;
413 def __get_start_stop_iterations(self, start_iteration, stop_iteration):
415 @brief Aplly rules for start_iteration and stop_iteration parameters. 417 @param[in] start_iteration (uint): The first iteration that is used for calculation. 418 @param[in] stop_iteration (uint): The last iteration that is used for calculation. 420 @return (tuple) New the first iteration and the last. 423 if (start_iteration
is None):
424 start_iteration = len(self) - 1;
426 if (stop_iteration
is None):
427 stop_iteration = start_iteration + 1;
429 return (start_iteration, stop_iteration);
435 @brief Visualizer of output dynamic of sync network (Sync). 442 @brief Shows output dynamic (output of each oscillator) during simulation. 444 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 446 @see show_output_dynamics 450 draw_dynamics(sync_output_dynamic.time, sync_output_dynamic.output, x_title =
"t", y_title =
"phase", y_lim = [0, 2 * 3.14]);
456 @brief Shows several output dynamics (output of each oscillator) during simulation. 457 @details Each dynamic is presented on separate plot. 459 @param[in] sync_output_dynamics (list): list of output dynamics 'sync_dynamic' of the Sync network. 461 @see show_output_dynamic 465 draw_dynamics_set(sync_output_dynamics,
"t",
"phase",
None, [0, 2 * 3.14],
False,
False);
471 @brief Shows correlation matrix between oscillators at the specified iteration. 473 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 474 @param[in] iteration (uint): Number of interation of simulation for which correlation matrix should be allocated. 475 If iternation number is not specified, the last step of simulation is used for the matrix allocation. 480 correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(iteration);
482 plt.imshow(correlation_matrix, cmap = plt.get_cmap(
'cool'), interpolation=
'kaiser', vmin = 0.0, vmax = 1.0);
487 def show_phase_matrix(sync_output_dynamic, grid_width = None, grid_height = None, iteration = None):
489 @brief Shows 2D matrix of phase values of oscillators at the specified iteration. 490 @details User should ensure correct matrix sizes in line with following expression grid_width x grid_height that should be equal to 491 amount of oscillators otherwise exception is thrown. If grid_width or grid_height are not specified than phase matrix size 492 will by calculated automatically by square root. 494 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose phase matrix should be shown. 495 @param[in] grid_width (uint): Width of the phase matrix. 496 @param[in] grid_height (uint): Height of the phase matrix. 497 @param[in] iteration (uint): Number of iteration of simulation for which correlation matrix should be allocated. 498 If iternation number is not specified, the last step of simulation is used for the matrix allocation. 503 phase_matrix = sync_output_dynamic.allocate_phase_matrix(grid_width, grid_height, iteration);
505 plt.imshow(phase_matrix, cmap = plt.get_cmap(
'jet'), interpolation=
'kaiser', vmin = 0.0, vmax = 2.0 * math.pi);
512 @brief Shows evolution of order parameter (level of global synchronization in the network). 514 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose evolution of global synchronization should be visualized. 515 @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the first is used 516 @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then the last is used. 520 (start_iteration, stop_iteration) = sync_visualizer.__get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration);
522 order_parameter = sync_output_dynamic.calculate_order_parameter(start_iteration, stop_iteration);
523 axis = plt.subplot(111);
524 plt.plot(sync_output_dynamic.time[start_iteration:stop_iteration], order_parameter,
'b-', linewidth = 2.0);
525 set_ax_param(axis,
"t",
"R (order parameter)",
None, [0.0, 1.05]);
533 @brief Shows evolution of local order parameter (level of local synchronization in the network). 535 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network whose evolution of global synchronization should be visualized. 536 @param[in] oscillatory_network (sync): Sync oscillatory network whose structure of connections is required for calculation. 537 @param[in] start_iteration (uint): The first iteration that is used for calculation, if 'None' then the first is used 538 @param[in] stop_iteration (uint): The last iteration that is used for calculation, if 'None' then the last is used. 541 (start_iteration, stop_iteration) = sync_visualizer.__get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration);
543 order_parameter = sync_output_dynamic.calculate_local_order_parameter(oscillatory_network, start_iteration, stop_iteration);
544 axis = plt.subplot(111);
545 plt.plot(sync_output_dynamic.time[start_iteration:stop_iteration], order_parameter,
'b-', linewidth = 2.0);
546 set_ax_param(axis,
"t",
"R (local order parameter)",
None, [0.0, 1.05]);
554 @brief Shows animation of output dynamic (output of each oscillator) during simulation on a circle from [0; 2pi]. 556 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 557 @param[in] animation_velocity (uint): Interval between frames in milliseconds. 558 @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter. 562 figure = plt.figure();
564 dynamic = sync_output_dynamic.output[0];
565 artist, = plt.polar(dynamic, [1.0] * len(dynamic),
'o', color =
'blue');
570 def frame_generation(index_dynamic):
571 dynamic = sync_output_dynamic.output[index_dynamic];
572 artist.set_data(dynamic, [1.0] * len(dynamic));
576 phase_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), interval = animation_velocity, init_func = init_frame, repeat_delay = 5000);
578 if (save_movie
is not None):
579 phase_animation.save(save_movie, writer =
'ffmpeg', fps = 15, bitrate = 1500);
587 @brief Shows animation of correlation matrix between oscillators during simulation. 589 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 590 @param[in] animation_velocity (uint): Interval between frames in milliseconds. 591 @param[in] colormap (string): Name of colormap that is used by matplotlib ('gray', 'pink', 'cool', spring', etc.). 592 @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter. 596 figure = plt.figure()
598 correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(0)
599 artist = plt.imshow(correlation_matrix, cmap = plt.get_cmap(colormap), interpolation=
'kaiser', vmin = 0.0, vmax = 1.0)
604 def frame_generation(index_dynamic):
605 correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(index_dynamic)
606 artist.set_data(correlation_matrix)
610 correlation_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), init_func = init_frame, interval = animation_velocity , repeat_delay = 1000, blit =
True)
612 if (save_movie
is not None):
613 correlation_animation.save(save_movie, writer =
'ffmpeg', fps = 15, bitrate = 1500)
619 def animate_phase_matrix(sync_output_dynamic, grid_width = None, grid_height = None, animation_velocity = 75, colormap = 'jet', save_movie = None):
621 @brief Shows animation of phase matrix between oscillators during simulation on 2D stage. 622 @details If grid_width or grid_height are not specified than phase matrix size will by calculated automatically by square root. 624 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 625 @param[in] grid_width (uint): Width of the phase matrix. 626 @param[in] grid_height (uint): Height of the phase matrix. 627 @param[in] animation_velocity (uint): Interval between frames in milliseconds. 628 @param[in] colormap (string): Name of colormap that is used by matplotlib ('gray', 'pink', 'cool', spring', etc.). 629 @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter. 633 figure = plt.figure();
636 return frame_generation(0);
638 def frame_generation(index_dynamic):
640 axis = figure.add_subplot(111);
642 phase_matrix = sync_output_dynamic.allocate_phase_matrix(grid_width, grid_height, index_dynamic);
643 axis.imshow(phase_matrix, cmap = plt.get_cmap(colormap), interpolation=
'kaiser', vmin = 0.0, vmax = 2.0 * math.pi);
644 artist = figure.gca();
648 phase_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), init_func = init_frame, interval = animation_velocity , repeat_delay = 1000);
650 if (save_movie
is not None):
651 phase_animation.save(save_movie, writer =
'ffmpeg', fps = 15, bitrate = 1500);
657 def __get_start_stop_iterations(sync_output_dynamic, start_iteration, stop_iteration):
659 @brief Apply rule of preparation for start iteration and stop iteration values. 661 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 662 @param[in] start_iteration (uint): The first iteration that is used for calculation. 663 @param[in] stop_iteration (uint): The last iteration that is used for calculation. 665 @return (tuple) New values of start and stop iterations. 668 if (start_iteration
is None):
671 if (stop_iteration
is None):
672 stop_iteration = len(sync_output_dynamic);
674 return (start_iteration, stop_iteration);
678 def animate(sync_output_dynamic, title = None, save_movie = None):
680 @brief Shows animation of phase coordinates and animation of correlation matrix together for the Sync dynamic output on the same figure. 682 @param[in] sync_output_dynamic (sync_dynamic): Output dynamic of the Sync network. 683 @param[in] title (string): Title of the animation that is displayed on a figure if it is specified. 684 @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter. 688 dynamic = sync_output_dynamic.output[0];
689 correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(0);
691 figure = plt.figure(1);
692 if (title
is not None):
693 figure.suptitle(title, fontsize = 26, fontweight =
'bold')
695 ax1 = figure.add_subplot(121, projection=
'polar');
696 ax2 = figure.add_subplot(122);
698 artist1, = ax1.plot(dynamic, [1.0] * len(dynamic), marker =
'o', color =
'blue', ls =
'');
699 artist2 = ax2.imshow(correlation_matrix, cmap = plt.get_cmap(
'Accent'), interpolation=
'kaiser');
702 return [ artist1, artist2 ];
704 def frame_generation(index_dynamic):
705 dynamic = sync_output_dynamic.output[index_dynamic];
706 artist1.set_data(dynamic, [1.0] * len(dynamic));
708 correlation_matrix = sync_output_dynamic.allocate_correlation_matrix(index_dynamic);
709 artist2.set_data(correlation_matrix);
711 return [ artist1, artist2 ];
713 dynamic_animation = animation.FuncAnimation(figure, frame_generation, len(sync_output_dynamic), interval = 75, init_func = init_frame, repeat_delay = 5000);
715 if (save_movie
is not None):
716 dynamic_animation.save(save_movie, writer =
'ffmpeg', fps = 15, bitrate = 1500);
724 @brief Model of oscillatory network that is based on the Kuramoto model of synchronization. 726 @details CCORE option can be used to use the pyclustering core - C/C++ shared library for processing that significantly increases performance. 730 def __init__(self, num_osc, weight = 1, frequency = 0, type_conn = conn_type.ALL_TO_ALL, representation = conn_represent.MATRIX, initial_phases = initial_type.RANDOM_GAUSSIAN, ccore = True):
732 @brief Constructor of oscillatory network is based on Kuramoto model. 734 @param[in] num_osc (uint): Number of oscillators in the network. 735 @param[in] weight (double): Coupling strength of the links between oscillators. 736 @param[in] frequency (double): Multiplier of internal frequency of the oscillators. 737 @param[in] type_conn (conn_type): Type of connection between oscillators in the network (all-to-all, grid, bidirectional list, etc.). 738 @param[in] representation (conn_represent): Internal representation of connection in the network: matrix or list. 739 @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.). 740 @param[in] ccore (bool): If True simulation is performed by CCORE library (C++ implementation of pyclustering). 746 if ( (ccore
is True)
and ccore_library.workable() ):
747 self.
_ccore_network_pointer = wrapper.sync_create_network(num_osc, weight, frequency, type_conn, initial_phases);
752 super().
__init__(num_osc, type_conn, representation);
760 for index
in range(0, num_osc, 1):
761 if (initial_phases == initial_type.RANDOM_GAUSSIAN):
762 self.
_phases.append(random.random() * 2 * pi);
764 elif (initial_phases == initial_type.EQUIPARTITION):
765 self.
_phases.append( pi / num_osc * index);
767 self.
_freq.append(random.random() * frequency);
772 @brief Destructor of oscillatory network is based on Kuramoto model. 783 @brief Calculates current level of global synchorization (order parameter) in the network. 784 @details This parameter is tend 1.0 when the oscillatory network close to global synchronization and it tend to 0.0 when 785 desynchronization is observed in the network. Order parameter is calculated using following equation: 788 r_{c}=\frac{1}{Ne^{i\varphi }}\sum_{j=0}^{N}e^{i\theta_{j}}; 791 where \f$\varphi\f$ is a average phase coordinate in the network, \f$N\f$ is an amount of oscillators in the network. 795 oscillatory_network = sync(16, type_conn = conn_type.ALL_TO_ALL); 796 output_dynamic = oscillatory_network.simulate_static(100, 10); 798 if (oscillatory_network.sync_order() < 0.9): print("Global synchronization is not reached yet."); 799 else: print("Global synchronization is reached."); 802 @return (double) Level of global synchronization (order parameter). 804 @see sync_local_order() 811 return order_estimator.calculate_sync_order(self.
_phases);
816 @brief Calculates current level of local (partial) synchronization in the network. 818 @return (double) Level of local (partial) synchronization. 827 return order_estimator.calculate_local_sync_order(self.
_phases, self);
830 def _phase_kuramoto(self, teta, t, argv):
832 @brief Returns result of phase calculation for specified oscillator in the network. 834 @param[in] teta (double): Phase of the oscillator that is differentiated. 835 @param[in] t (double): Current time of simulation. 836 @param[in] argv (tuple): Index of the oscillator in the list. 838 @return (double) New phase for specified oscillator (don't assign here). 846 phase += math.sin(self.
_phases[k] - teta);
851 def simulate(self, steps, time, solution = solve_type.FAST, collect_dynamic = True):
853 @brief Performs static simulation of Sync oscillatory network. 855 @param[in] steps (uint): Number steps of simulations during simulation. 856 @param[in] time (double): Time of simulation. 857 @param[in] solution (solve_type): Type of solution (solving). 858 @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics. 860 @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time, 861 otherwise returns only last values (last step of simulation) of dynamic. 863 @see simulate_dynamic() 864 @see simulate_static() 871 def simulate_dynamic(self, order = 0.998, solution = solve_type.FAST, collect_dynamic = False, step = 0.1, int_step = 0.01, threshold_changes = 0.0000001):
873 @brief Performs dynamic simulation of the network until stop condition is not reached. Stop condition is defined by input argument 'order'. 875 @param[in] order (double): Order of process synchronization, distributed 0..1. 876 @param[in] solution (solve_type): Type of solution. 877 @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics. 878 @param[in] step (double): Time step of one iteration of simulation. 879 @param[in] int_step (double): Integration step, should be less than step. 880 @param[in] threshold_changes (double): Additional stop condition that helps prevent infinite simulation, defines limit of changes of oscillators between current and previous steps. 882 @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time, 883 otherwise returns only last values (last step of simulation) of dynamic. 886 @see simulate_static() 891 ccore_instance_dynamic = wrapper.sync_simulate_dynamic(self.
_ccore_network_pointer, order, solution, collect_dynamic, step, int_step, threshold_changes);
892 return sync_dynamic(
None,
None, ccore_instance_dynamic);
904 if (collect_dynamic ==
True):
905 dyn_phase.append(self.
_phases);
909 while (current_order < order):
914 time_counter += step;
917 if (collect_dynamic ==
True):
918 dyn_phase.append(self.
_phases);
919 dyn_time.append(time_counter);
922 previous_order = current_order;
926 if (abs(current_order - previous_order) < threshold_changes):
930 if (collect_dynamic !=
True):
931 dyn_phase.append(self.
_phases);
932 dyn_time.append(time_counter);
934 output_sync_dynamic =
sync_dynamic(dyn_phase, dyn_time,
None);
935 return output_sync_dynamic;
938 def simulate_static(self, steps, time, solution = solve_type.FAST, collect_dynamic = False):
940 @brief Performs static simulation of oscillatory network. 942 @param[in] steps (uint): Number steps of simulations during simulation. 943 @param[in] time (double): Time of simulation. 944 @param[in] solution (solve_type): Type of solution. 945 @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics. 947 @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time, 948 otherwise returns only last values (last step of simulation) of dynamic. 951 @see simulate_dynamic() 956 ccore_instance_dynamic = wrapper.sync_simulate_static(self.
_ccore_network_pointer, steps, time, solution, collect_dynamic);
957 return sync_dynamic(
None,
None, ccore_instance_dynamic);
962 if (collect_dynamic ==
True):
963 dyn_phase.append(self.
_phases);
967 int_step = step / 10.0;
969 for t
in numpy.arange(step, time + step, step):
974 if (collect_dynamic ==
True):
975 dyn_phase.append(self.
_phases);
978 if (collect_dynamic !=
True):
979 dyn_phase.append(self.
_phases);
980 dyn_time.append(time);
982 output_sync_dynamic =
sync_dynamic(dyn_phase, dyn_time);
983 return output_sync_dynamic;
986 def _calculate_phases(self, solution, t, step, int_step):
988 @brief Calculates new phases for oscillators in the network in line with current step. 990 @param[in] solution (solve_type): Type solver of the differential equation. 991 @param[in] t (double): Time of simulation. 992 @param[in] step (double): Step of solution at the end of which states of oscillators should be calculated. 993 @param[in] int_step (double): Step differentiation that is used for solving differential equation. 995 @return (list) New states (phases) for oscillators. 999 next_phases = [0.0] * self.
_num_osc;
1001 for index
in range (0, self.
_num_osc, 1):
1002 if (solution == solve_type.FAST):
1006 elif ( (solution == solve_type.RK4)
or (solution == solve_type.RKF45) ):
1007 result = odeint(self.
_phase_kuramoto, self.
_phases[index], numpy.arange(t - step, t, int_step), (index , ));
1011 raise NameError(
"Solver '" + str(solution) +
"' is not supported");
1016 def _phase_normalization(self, teta):
1018 @brief Normalization of phase of oscillator that should be placed between [0; 2 * pi]. 1020 @param[in] teta (double): phase of oscillator. 1022 @return (double) Normalized phase. 1027 while (norm_teta > (2.0 * pi))
or (norm_teta < 0):
1028 if (norm_teta > (2.0 * pi)):
1029 norm_teta -= 2.0 * pi;
1031 norm_teta += 2.0 * pi;
1038 @brief Finds neighbors of the oscillator with specified index. 1040 @param[in] index (uint): index of oscillator for which neighbors should be found in the network. 1042 @return (list) Indexes of neighbors of the specified oscillator. 1054 @brief Returns True if there is connection between i and j oscillators and False - if connection doesn't exist. 1056 @param[in] i (uint): index of an oscillator in the network. 1057 @param[in] j (uint): index of an oscillator in the network.
def simulate_dynamic(self, order=0.998, solution=solve_type.FAST, collect_dynamic=False, step=0.1, int_step=0.01, threshold_changes=0.0000001)
Performs dynamic simulation of the network until stop condition is not reached.
def animate_correlation_matrix(sync_output_dynamic, animation_velocity=75, colormap='cool', save_movie=None)
Shows animation of correlation matrix between oscillators during simulation.
def __del__(self)
Default destructor of Sync dynamic.
def __get_start_stop_iterations(self, start_iteration, stop_iteration)
Aplly rules for start_iteration and stop_iteration parameters.
def _calculate_phases(self, solution, t, step, int_step)
Calculates new phases for oscillators in the network in line with current step.
def calculate_local_sync_order(oscillator_phases, oscillatory_network)
Calculates level of local synchorization (local order parameter) for input phases for the specified n...
def time(self)
(list) Returns sampling times when dynamic is measured during simulation.
def animate_output_dynamic(sync_output_dynamic, animation_velocity=75, save_movie=None)
Shows animation of output dynamic (output of each oscillator) during simulation on a circle from [0; ...
Represents output dynamic of Sync.
def show_phase_matrix(sync_output_dynamic, grid_width=None, grid_height=None, iteration=None)
Shows 2D matrix of phase values of oscillators at the specified iteration.
def allocate_correlation_matrix(self, iteration=None)
Allocate correlation matrix between oscillators at the specified step of simulation.
def simulate_static(self, steps, time, solution=solve_type.FAST, collect_dynamic=False)
Performs static simulation of oscillatory network.
Utils that are used by modules of pyclustering.
def sync_local_order(self)
Calculates current level of local (partial) synchronization in the network.
def animate_phase_matrix(sync_output_dynamic, grid_width=None, grid_height=None, animation_velocity=75, colormap='jet', save_movie=None)
Shows animation of phase matrix between oscillators during simulation on 2D stage.
def allocate_sync_ensembles(self, tolerance=0.01, indexes=None, iteration=None)
Allocate clusters in line with ensembles of synchronous oscillators where each synchronous ensemble c...
def show_output_dynamic(sync_output_dynamic)
Shows output dynamic (output of each oscillator) during simulation.
def __len__(self)
Returns number of simulation steps that are stored in dynamic.
def has_connection(self, i, j)
Returns True if there is connection between i and j oscillators and False - if connection doesn't exi...
def show_output_dynamics(sync_output_dynamics)
Shows several output dynamics (output of each oscillator) during simulation.
def _phase_kuramoto(self, teta, t, argv)
Returns result of phase calculation for specified oscillator in the network.
def __getitem__(self, index)
Indexing of the dynamic.
def calculate_local_order_parameter(self, oscillatory_network, start_iteration=None, stop_iteration=None)
Calculates local order parameter.
def show_correlation_matrix(sync_output_dynamic, iteration=None)
Shows correlation matrix between oscillators at the specified iteration.
def calculate_sync_order(oscillator_phases)
Calculates level of global synchronization (order parameter) for input phases.
Common network description that consists of information about oscillators and connection between them...
Provides services to calculate order parameter and local order parameter that are used for synchroniz...
def __init__(self, phase, time, ccore=None)
Constructor of Sync dynamic.
def show_order_parameter(sync_output_dynamic, start_iteration=None, stop_iteration=None)
Shows evolution of order parameter (level of global synchronization in the network).
def __del__(self)
Destructor of oscillatory network is based on Kuramoto model.
def get_neighbors(self, index)
Finds neighbors of the oscillator with specified index.
def has_connection(self, i, j)
Returns True if there is connection between i and j oscillators and False - if connection doesn't exi...
_ccore_sync_dynamic_pointer
def __init__(self, num_osc, weight=1, frequency=0, type_conn=conn_type.ALL_TO_ALL, representation=conn_represent.MATRIX, initial_phases=initial_type.RANDOM_GAUSSIAN, ccore=True)
Constructor of oscillatory network is based on Kuramoto model.
def animate(sync_output_dynamic, title=None, save_movie=None)
Shows animation of phase coordinates and animation of correlation matrix together for the Sync dynami...
def _phase_normalization(self, teta)
Normalization of phase of oscillator that should be placed between [0; 2 * pi].
def sync_order(self)
Calculates current level of global synchorization (order parameter) in the network.
def allocate_phase_matrix(self, grid_width=None, grid_height=None, iteration=None)
Returns 2D matrix of phase values of oscillators at the specified iteration of simulation.
def calculate_order_parameter(self, start_iteration=None, stop_iteration=None)
Calculates level of global synchorization (order parameter).
Visualizer of output dynamic of sync network (Sync).
def show_local_order_parameter(sync_output_dynamic, oscillatory_network, start_iteration=None, stop_iteration=None)
Shows evolution of local order parameter (level of local synchronization in the network).
def simulate(self, steps, time, solution=solve_type.FAST, collect_dynamic=True)
Performs static simulation of Sync oscillatory network.
def output(self)
(list) Returns output dynamic of the Sync network (phase coordinates of each oscillator in the networ...
Neural and oscillatory network module.
Model of oscillatory network that is based on the Kuramoto model of synchronization.