class_docstr: !
  @brief Represents output dynamic of Sync.
docstr: !
  @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] 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]).
  @param[in] iteration (uint): Iteration of simulation that should be used for allocation.
  
  @return (list) Groups (lists) of indexes of synchronous oscillators.
          For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].
docstr_tok: ["!","@","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","]","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","]",")",".","@","param","[","in","]","iteration","(","uint",")",":","Iteration","of","simulation","that","should","be","used","for","allocation",".","@","return","(","list",")","Groups","(","lists",")","of","indexes","of","synchronous","oscillators",".","For","example","[","[","index_osc1",",","index_osc3","]",",","[","index_osc2","]",",","[","index_osc4",",","index_osc5","]","]","."]
code: def allocate_sync_ensembles(
      self, tolerance=0.01, indexes=None, iteration=None
  ):
      """!
      @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] 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]).
      @param[in] iteration (uint): Iteration of simulation that should be used for allocation.
  
      @return (list) Groups (lists) of indexes of synchronous oscillators.
              For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].
  
      """
  
      if self._ccore_sync_dynamic_pointer is not None:
          ensembles = wrapper.sync_dynamic_allocate_sync_ensembles(
              self._ccore_sync_dynamic_pointer, tolerance, iteration
          )
  
          if indexes is not None:
              for ensemble in ensembles:
                  for index in range(len(ensemble)):
                      ensemble[index] = indexes[ensemble[index]]
  
          return ensembles
  
      if (self._dynamic is None) or (len(self._dynamic) == 0):
          return []
  
      number_oscillators = len(self._dynamic[0])
      last_state = None
  
      if iteration is None:
          last_state = self._dynamic[len(self._dynamic) - 1]
      else:
          last_state = self._dynamic[iteration]
  
      clusters = []
      if number_oscillators > 0:
          clusters.append([0])
  
      for i in range(1, number_oscillators, 1):
          cluster_allocated = False
          for cluster in clusters:
              for neuron_index in cluster:
                  last_state_shifted = abs(last_state[i] - 2 * pi)
  
                  if (
                      (
                          last_state[i]
                          < (last_state[neuron_index] + tolerance)
                      )
                      and (
                          last_state[i]
                          > (last_state[neuron_index] - tolerance)
                      )
                  ) or (
                      (
                          last_state_shifted
                          < (last_state[neuron_index] + tolerance)
                      )
                      and (
                          last_state_shifted
                          > (last_state[neuron_index] - tolerance)
                      )
                  ):
                      cluster_allocated = True
  
                      real_index = i
                      if indexes is not None:
                          real_index = indexes[i]
  
                      cluster.append(real_index)
                      break
  
              if cluster_allocated is True:
                  break
  
          if cluster_allocated is False:
              clusters.append([i])
  
      return clusters
  
imports: import math
  import numpy
  import random
  import matplotlib.pyplot
  import matplotlib.animation
  import pyclustering.core.sync_wrapper
  from pyclustering.core.wrapper import ccore_library
  from scipy.integrate import odeint
  from pyclustering.nnet import network, conn_represent, conn_type, initial_type, solve_type
  from pyclustering.utils import pi, draw_dynamics, draw_dynamics_set, set_ax_param
label_desc: Use image node_id 7 for calling the sync_dynamic obj's underlying member method code with example usage: obj.allocate_sync_ensembles(tolerance, indexes, iteration) and returns: clusters, ensembles, list