3 @brief Neural and oscillatory network module. Consists of models of bio-inspired networks.
5 @authors Andrei Novikov (pyclustering@yandex.ru)
7 @copyright BSD-3-Clause
13 from enum
import IntEnum;
17 @brief Enumerator of types of oscillator output initialization.
30 @brief Enumerator of solver types that are used for network simulation.
46 @brief Enumerator of connection types between oscillators.
71 @brief Enumerator of internal network connection representation between oscillators.
84 @brief Common network description that consists of information about oscillators and connection between them.
91 _conn_represent =
None;
101 @brief Height of the network grid (that is defined by amout of oscillators in each column), this value is zero in case of non-grid structure.
103 @note This property returns valid value only for network with grid structure.
112 @brief Width of the network grid, this value is zero in case of non-grid structure.
114 @note This property returns valid value only for network with grid structure.
123 @brief Type of network structure that is used for connecting oscillators.
129 def __init__(self, num_osc, type_conn = conn_type.ALL_TO_ALL, conn_repr = conn_represent.MATRIX, height = None, width = None):
131 @brief Constructor of the network.
133 @param[in] num_osc (uint): Number of oscillators in the network that defines size of the network.
134 @param[in] type_conn (conn_type): Type of connections that are used in the network between oscillators.
135 @param[in] conn_repr (conn_represent): Type of representation of connections.
136 @param[in] height (uint): Number of oscillators in column of the network, this argument is used
137 only for network with grid structure (GRID_FOUR, GRID_EIGHT), for other types this argument is ignored.
138 @param[in] width (uint): Number of oscillotors in row of the network, this argument is used only
139 for network with grid structure (GRID_FOUR, GRID_EIGHT), for other types this argument is ignored.
147 if (conn_repr
is None):
150 if ( (type_conn == conn_type.GRID_EIGHT)
or (type_conn == conn_type.GRID_FOUR) ):
151 if ( (height
is not None)
and (width
is not None) ):
156 if (side_size - math.floor(side_size) > 0):
157 raise NameError(
"Invalid number of oscillators '" + str(num_osc) +
"' in the network in case of grid structure (root square should be extractable for the number of oscillators).");
163 raise NameError(
'Width (' + str(self.
__width) +
') x Height (' + str(self.
__height) +
') must be equal to Size (' + str(self.
_num_osc) +
') in case of grid structure');
170 @brief Returns size of the network that is defined by amount of oscillators.
176 def __create_connection(self, index1, index2):
183 def __create_all_to_all_connections(self):
185 @brief Creates connections between all oscillators.
190 for index
in range(0, self.
_num_osc, 1):
195 for index
in range(0, self.
_num_osc, 1):
196 self.
_osc_conn.append([neigh
for neigh
in range(0, self.
_num_osc, 1)
if index != neigh]);
199 def __create_grid_four_connections(self):
201 @brief Creates network with connections that make up four grid structure.
202 @details Each oscillator may be connected with four neighbors in line with 'grid' structure: right, upper, left, lower.
212 raise NameError(
"Unknown type of representation of connections");
214 for index
in range(0, self.
_num_osc, 1):
215 upper_index = index - side_size;
216 lower_index = index + side_size;
217 left_index = index - 1;
218 right_index = index + 1;
220 node_row_index = math.ceil(index / side_size);
221 if (upper_index >= 0):
227 if ( (left_index >= 0)
and (math.ceil(left_index / side_size) == node_row_index) ):
230 if ( (right_index < self.
_num_osc)
and (math.ceil(right_index / side_size) == node_row_index) ):
234 def __create_grid_eight_connections(self):
236 @brief Creates network with connections that make up eight grid structure.
237 @details Each oscillator may be connected with eight neighbors in line with grid structure: right, right-upper, upper, upper-left, left, left-lower, lower, lower-right.
244 for index
in range(0, self.
_num_osc, 1):
245 upper_left_index = index - side_size - 1;
246 upper_right_index = index - side_size + 1;
248 lower_left_index = index + side_size - 1;
249 lower_right_index = index + side_size + 1;
251 node_row_index = math.floor(index / side_size);
252 upper_row_index = node_row_index - 1;
253 lower_row_index = node_row_index + 1;
255 if ( (upper_left_index >= 0)
and (math.floor(upper_left_index / side_size) == upper_row_index) ):
258 if ( (upper_right_index >= 0)
and (math.floor(upper_right_index / side_size) == upper_row_index) ):
261 if ( (lower_left_index < self.
_num_osc)
and (math.floor(lower_left_index / side_size) == lower_row_index) ):
264 if ( (lower_right_index < self.
_num_osc)
and (math.floor(lower_right_index / side_size) == lower_row_index) ):
268 def __create_list_bidir_connections(self):
270 @brief Creates network as bidirectional list.
271 @details Each oscillator may be conneted with two neighbors in line with classical list structure: right, left.
276 for index
in range(0, self.
_num_osc, 1):
295 def __create_none_connections(self):
297 @brief Creates network without connections.
301 for _
in range(0, self.
_num_osc, 1):
307 def __create_dynamic_connection(self):
309 @brief Prepare storage for dynamic connections.
313 for _
in range(0, self.
_num_osc, 1):
319 def _create_structure(self, type_conn = conn_type.ALL_TO_ALL):
321 @brief Creates connection in line with representation of matrix connections [NunOsc x NumOsc].
323 @param[in] type_conn (conn_type): Connection type (all-to-all, bidirectional list, grid structure, etc.) that is used by the network.
329 if (type_conn == conn_type.NONE):
332 elif (type_conn == conn_type.ALL_TO_ALL):
335 elif (type_conn == conn_type.GRID_FOUR):
338 elif (type_conn == conn_type.GRID_EIGHT):
341 elif (type_conn == conn_type.LIST_BIDIR):
344 elif (type_conn == conn_type.DYNAMIC):
348 raise NameError(
'The unknown type of connections');
353 @brief Returns True if there is connection between i and j oscillators and False - if connection doesn't exist.
355 @param[in] i (uint): index of an oscillator in the network.
356 @param[in] j (uint): index of an oscillator in the network.
363 for neigh_index
in range(0, len(self.
_osc_conn[i]), 1):
364 if (self.
_osc_conn[i][neigh_index] == j):
369 raise NameError(
"Unknown type of representation of coupling");
374 @brief Couples two specified oscillators in the network with dynamic connections.
376 @param[in] i (uint): index of an oscillator that should be coupled with oscillator 'j' in the network.
377 @param[in] j (uint): index of an oscillator that should be coupled with oscillator 'i' in the network.
379 @note This method can be used only in case of DYNAMIC connections, otherwise it throws expection.
383 if (self.
structure != conn_type.DYNAMIC):
384 raise NameError(
"Connection between oscillators can be changed only in case of dynamic type.");
396 @brief Finds neighbors of the oscillator with specified index.
398 @param[in] index (uint): index of oscillator for which neighbors should be found in the network.
400 @return (list) Indexes of neighbors of the specified oscillator.
407 return [neigh_index
for neigh_index
in range(self.
_num_osc)
if self.
_osc_conn[index][neigh_index] ==
True];
409 raise NameError(
"Unknown type of representation of connections");