if pieces["<STR_LIT:error>"]:<EOL><INDENT>return {"<STR_LIT:version>": "<STR_LIT>",<EOL>"<STR_LIT>": pieces.get("<STR_LIT>"),<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT:error>": pieces["<STR_LIT:error>"],<EOL>"<STR_LIT:date>": None}<EOL><DEDENT>if not style or style == "<STR_LIT:default>":<EOL><INDENT>style = "<STR_LIT>"  <EOL><DEDENT>if style == "<STR_LIT>":<EOL><INDENT>rendered = render_pep440(pieces)<EOL><DEDENT>elif style == "<STR_LIT>":<EOL><INDENT>rendered = render_pep440_pre(pieces)<EOL><DEDENT>elif style == "<STR_LIT>":<EOL><INDENT>rendered = render_pep440_post(pieces)<EOL><DEDENT>elif style == "<STR_LIT>":<EOL><INDENT>rendered = render_pep440_old(pieces)<EOL><DEDENT>elif style == "<STR_LIT>":<EOL><INDENT>rendered = render_git_describe(pieces)<EOL><DEDENT>elif style == "<STR_LIT>":<EOL><INDENT>rendered = render_git_describe_long(pieces)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>" % style)<EOL><DEDENT>return {"<STR_LIT:version>": rendered, "<STR_LIT>": pieces["<STR_LIT>"],<EOL>"<STR_LIT>": pieces["<STR_LIT>"], "<STR_LIT:error>": None,<EOL>"<STR_LIT:date>": pieces.get("<STR_LIT:date>")}<EOL>

Render the given version pieces into the requested style.


if "<STR_LIT:+>" in pieces.get("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>return "<STR_LIT:.>"<EOL><DEDENT>return "<STR_LIT:+>"<EOL>

Return a + if we don't already have one, else return a .


<EOL>git_refnames = "<STR_LIT>"<EOL>git_full = "<STR_LIT>"<EOL>git_date = "<STR_LIT>"<EOL>keywords = {"<STR_LIT>": git_refnames, "<STR_LIT>": git_full, "<STR_LIT:date>": git_date}<EOL>return keywords<EOL>

Get the keywords needed to look up the version information.


<EOL>cfg = VersioneerConfig()<EOL>cfg.VCS = "<STR_LIT>"<EOL>cfg.style = "<STR_LIT>"<EOL>cfg.tag_prefix = "<STR_LIT>"<EOL>cfg.parentdir_prefix = "<STR_LIT>"<EOL>cfg.versionfile_source = "<STR_LIT>"<EOL>cfg.verbose = False<EOL>return cfg<EOL>

Create, populate and return the VersioneerConfig() object.


<EOL>cfg = get_config()<EOL>verbose = cfg.verbose<EOL>try:<EOL><INDENT>return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,<EOL>verbose)<EOL><DEDENT>except NotThisMethod:<EOL><INDENT>pass<EOL><DEDENT>try:<EOL><INDENT>root = os.path.realpath(__file__)<EOL>for i in cfg.versionfile_source.split('<STR_LIT:/>'):<EOL><INDENT>root = os.path.dirname(root)<EOL><DEDENT><DEDENT>except NameError:<EOL><INDENT>return {"<STR_LIT:version>": "<STR_LIT>", "<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT:error>": "<STR_LIT>",<EOL>"<STR_LIT:date>": None}<EOL><DEDENT>try:<EOL><INDENT>pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)<EOL>return render(pieces, cfg.style)<EOL><DEDENT>except NotThisMethod:<EOL><INDENT>pass<EOL><DEDENT>try:<EOL><INDENT>if cfg.parentdir_prefix:<EOL><INDENT>return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)<EOL><DEDENT><DEDENT>except NotThisMethod:<EOL><INDENT>pass<EOL><DEDENT>return {"<STR_LIT:version>": "<STR_LIT>", "<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT:error>": "<STR_LIT>", "<STR_LIT:date>": None}<EOL>

Get version information or return default if unable to do so.


@register_vcs_handler("<STR_LIT>", "<STR_LIT>")<EOL>def git_versions_from_keywords(keywords, tag_prefix, verbose):

if not keywords:<EOL><INDENT>raise NotThisMethod("<STR_LIT>")<EOL><DEDENT>date = keywords.get("<STR_LIT:date>")<EOL>if date is not None:<EOL><INDENT>date = date.strip().replace("<STR_LIT:U+0020>", "<STR_LIT:T>", <NUM_LIT:1>).replace("<STR_LIT:U+0020>", "<STR_LIT>", <NUM_LIT:1>)<EOL><DEDENT>refnames = keywords["<STR_LIT>"].strip()<EOL>if refnames.startswith("<STR_LIT>"):<EOL><INDENT>if verbose:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>raise NotThisMethod("<STR_LIT>")<EOL><DEDENT>refs = set([r.strip() for r in refnames.strip("<STR_LIT>").split("<STR_LIT:U+002C>")])<EOL>TAG = "<STR_LIT>"<EOL>tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])<EOL>if not tags:<EOL><INDENT>tags = set([r for r in refs if re.search(r'<STR_LIT>', r)])<EOL>if verbose:<EOL><INDENT>print("<STR_LIT>" % "<STR_LIT:U+002C>".join(refs - tags))<EOL><DEDENT><DEDENT>if verbose:<EOL><INDENT>print("<STR_LIT>" % "<STR_LIT:U+002C>".join(sorted(tags)))<EOL><DEDENT>for ref in sorted(tags):<EOL><INDENT>if ref.startswith(tag_prefix):<EOL><INDENT>r = ref[len(tag_prefix):]<EOL>if verbose:<EOL><INDENT>print("<STR_LIT>" % r)<EOL><DEDENT>return {"<STR_LIT:version>": r,<EOL>"<STR_LIT>": keywords["<STR_LIT>"].strip(),<EOL>"<STR_LIT>": False, "<STR_LIT:error>": None,<EOL>"<STR_LIT:date>": date}<EOL><DEDENT><DEDENT>if verbose:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>return {"<STR_LIT:version>": "<STR_LIT>",<EOL>"<STR_LIT>": keywords["<STR_LIT>"].strip(),<EOL>"<STR_LIT>": False, "<STR_LIT:error>": "<STR_LIT>", "<STR_LIT:date>": None}<EOL>

Get version information from git keywords.


<EOL>return [self.delta[d, d] * np.arange(self.shape[d] + <NUM_LIT:1>) +<EOL>self.origin[d] - <NUM_LIT:0.5> * self.delta[d, d]<EOL>for d in range(self.rank)]<EOL>

Edges of the grid cells, origin at centre of 0,0,..,0 grid cell.

        Only works for regular, orthonormal grids.


if filename is not None:<EOL><INDENT>self.filename = filename<EOL><DEDENT>with open(self.filename, '<STR_LIT:rb>') as ccp4:<EOL><INDENT>h = self.header = self._read_header(ccp4)<EOL>nentries = h['<STR_LIT>'] * h['<STR_LIT>'] * h['<STR_LIT>']<EOL>datafmt = h['<STR_LIT>'] + str(nentries) + self._data_bintype<EOL>a = np.array(struct.unpack(datafmt, ccp4.read(struct.calcsize(datafmt))))<EOL><DEDENT>self.header['<STR_LIT:filename>'] = self.filename<EOL>order = '<STR_LIT:C>' if h['<STR_LIT>'] == '<STR_LIT:z>' else '<STR_LIT:F>'<EOL>self.array = a.reshape(h['<STR_LIT>'], h['<STR_LIT>'], h['<STR_LIT>'], order=order)<EOL>self.delta = self._delta()<EOL>self.origin = np.zeros(<NUM_LIT:3>)<EOL>self.rank = <NUM_LIT:3><EOL>

Populate the instance from the ccp4 file *filename*.


bsaflag = None<EOL>ccp4file.seek(<NUM_LIT> * <NUM_LIT:4>)<EOL>mapbin = ccp4file.read(<NUM_LIT:4>)<EOL>for flag in '<STR_LIT>':<EOL><INDENT>mapstr = struct.unpack(flag + '<STR_LIT>', mapbin)[<NUM_LIT:0>].decode('<STR_LIT:utf-8>')<EOL>if mapstr.upper() == '<STR_LIT>':<EOL><INDENT>bsaflag = flag<EOL>break  <EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>")<EOL><DEDENT>ccp4file.seek(<NUM_LIT:0>)<EOL>return bsaflag<EOL>

Detect the byteorder of stream `ccp4file` and return format character.

        Try all endinaness and alignment options until we find
        something that looks sensible ("MAPS " in the first 4 bytes).

        (The ``machst`` field could be used to obtain endianness, but
        it does not specify alignment.)

        .. SeeAlso::

          :mod:`struct`


from struct import calcsize, unpack<EOL>if not filename is None:<EOL><INDENT>self.filename = filename<EOL><DEDENT>with open(self.filename, '<STR_LIT:rb>') as plt:<EOL><INDENT>h = self.header = self._read_header(plt)<EOL>nentries = h['<STR_LIT>'] * h['<STR_LIT>'] * h['<STR_LIT>']<EOL>datafmt = h['<STR_LIT>']+str(nentries)+self._data_bintype<EOL>a = numpy.array(unpack(datafmt, plt.read(calcsize(datafmt))))<EOL><DEDENT>self.header['<STR_LIT:filename>'] = self.filename<EOL>self.array = a.reshape(h['<STR_LIT>'], h['<STR_LIT>'], h['<STR_LIT>']).transpose()  <EOL>self.delta = self._delta()<EOL>self.origin = numpy.array([h['<STR_LIT>'], h['<STR_LIT>'], h['<STR_LIT>']]) + <NUM_LIT:0.5>*numpy.diagonal(self.delta)<EOL>self.rank = h['<STR_LIT>']<EOL>

Populate the instance from the plt file *filename*.


return (self.array, self.edges)<EOL>

Return array data as (edges,grid), i.e. a numpy nD histogram.


nheader = struct.calcsize(self._headerfmt)<EOL>names = [r.key for r in self._header_struct]<EOL>binheader = pltfile.read(nheader)<EOL>def decode_header(bsaflag='<STR_LIT:@>'):<EOL><INDENT>h = dict(zip(names, struct.unpack(bsaflag+self._headerfmt, binheader)))<EOL>h['<STR_LIT>'] = bsaflag<EOL>return h<EOL><DEDENT>for flag in '<STR_LIT>':<EOL><INDENT>header = decode_header(flag)<EOL>if header['<STR_LIT>'] == <NUM_LIT:3>:<EOL><INDENT>break   <EOL><DEDENT>header = None<EOL><DEDENT>if header is None:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>for rec in self._header_struct:<EOL><INDENT>if not rec.is_legal_dict(header):<EOL><INDENT>warnings.warn("<STR_LIT>" % (rec.key, header[rec.key]))<EOL><DEDENT><DEDENT>return header<EOL>

Read header bytes, try all possibilities for byte order/size/alignment.


<EOL>arrs = tuple(arrs)<EOL>lens = list(map(len, arrs))<EOL>dim = len(arrs)<EOL>sz = <NUM_LIT:1><EOL>for s in lens:<EOL><INDENT>sz *= s<EOL><DEDENT>ans = []<EOL>for i, arr in enumerate(arrs):<EOL><INDENT>slc = [<NUM_LIT:1>] * dim<EOL>slc[i] = lens[i]<EOL>arr2 = numpy.asanyarray(arr).reshape(slc)<EOL>for j, sz in enumerate(lens):<EOL><INDENT>if j != i:<EOL><INDENT>arr2 = arr2.repeat(sz, axis=j)<EOL><DEDENT><DEDENT>ans.append(arr2)<EOL><DEDENT>return tuple(ans)<EOL>

Return a mesh grid for N dimensions.

    The input are N arrays, each of which contains the values along one axis of
    the coordinate system. The arrays do not have to have the same number of
    entries. The function returns arrays that can be fed into numpy functions
    so that they produce values for *all* points spanned by the axes *arrs*.

    Original from
    http://stackoverflow.com/questions/1827489/numpy-meshgrid-in-3d and fixed.

    .. SeeAlso: :func:`numpy.meshgrid` for the 2D case.


dx = OpenDX.field(<NUM_LIT:0>)<EOL>dx.read(filename)<EOL>grid, edges = dx.histogramdd()<EOL>self.__init__(grid=grid, edges=edges, metadata=self.metadata)<EOL>


self.export(filename, file_format="<STR_LIT>")<EOL>

Save a grid object to <filename>.pickle

        Internally, this calls
        ``Grid.export(filename, format="python")``. A grid can be
        regenerated from the saved data with ::

           g = Grid(filename="grid.pickle")

        .. note::
           The pickle format depends on the Python version and
           therefore it is not guaranteed that a grid saved with, say,
           Python 2.7 can also be read with Python 3.5. The OpenDX format
           is a better alternative for portability.


try:<EOL><INDENT>edges = edges.edges  <EOL><DEDENT>except AttributeError:<EOL><INDENT>pass<EOL><DEDENT>midpoints = self._midpoints(edges)<EOL>coordinates = ndmeshgrid(*midpoints)<EOL>newgrid = self.interpolated(*coordinates)<EOL>return self.__class__(newgrid, edges)<EOL>

Resample data to a new grid with edges *edges*.

        This method creates a new grid with the data from the current
        grid resampled to a regular grid specified by *edges*.  The
        order of the interpolation is set by
        :attr:`Grid.interpolation_spline_order`: change the value
        *before* calling :meth:`resample`.

        Parameters
        ----------
        edges : tuple of arrays or Grid
             edges of the new grid or a :class:`Grid` instance that
             provides :attr:`Grid.edges`

        Returns
        -------
        Grid
             a new :class:`Grid` with the data interpolated over the
             new grid cells

        Examples
        --------

        Providing *edges* (a tuple of three arrays, indicating the
        boundaries of each grid cell)::

          g = grid.resample(edges)

        As a convenience, one can also supply another :class:`Grid` as
        the argument for this method ::

          g = grid.resample(othergrid)

        and the edges are taken from :attr:`Grid.edges`.


def _export_python(self, filename, **kwargs):

data = dict(grid=self.grid, edges=self.edges, metadata=self.metadata)<EOL>with open(filename, '<STR_LIT:wb>') as f:<EOL><INDENT>cPickle.dump(data, f, cPickle.HIGHEST_PROTOCOL)<EOL><DEDENT>

Pickle the Grid object

        The object is dumped as a dictionary with grid and edges: This
        is sufficient to recreate the grid object with __init__().


g = gOpenMol.Plt()<EOL>g.read(filename)<EOL>grid, edges = g.histogramdd()<EOL>self.__init__(grid=grid, edges=edges, metadata=self.metadata)<EOL>


if self.__interpolated is None:<EOL><INDENT>self.__interpolated = self._interpolationFunctionFactory()<EOL><DEDENT>return self.__interpolated<EOL>

B-spline function over the data grid(x,y,z).

        The :func:`interpolated` function allows one to obtain data
        values for any values of the coordinates::

           interpolated([x1,x2,...],[y1,y2,...],[z1,z2,...]) -> F[x1,y1,z1],F[x2,y2,z2],...

        The interpolation order is set in
        :attr:`Grid.interpolation_spline_order`.

        The interpolated function is computed once and is cached for better
        performance. Whenever :attr:`~Grid.interpolation_spline_order` is
        modified, :meth:`Grid.interpolated` is recomputed.

        The value for unknown data is set in :attr:`Grid.interpolation_cval`
        (TODO: also recompute when ``interpolation_cval`` value is changed.)

        Example
        -------
        Example usage for resampling::

           XX, YY, ZZ = numpy.mgrid[40:75:0.5, 96:150:0.5, 20:50:0.5]
           FF = interpolated(XX, YY, ZZ)

        Note
        ----
        Values are interpolated with a spline function. It is possible
        that the spline will generate values that would not normally
        appear in the data. For example, a density is non-negative but
        a cubic spline interpolation can generate negative values,
        especially at the boundary between 0 and high values.


return self._clusters<EOL>

!
        @brief Returns list of allocated clusters, each cluster contains indexes of objects in list of data.

        @see process()
        @see get_representatives()


if self._ccore is True:<EOL><INDENT>self.__process_by_ccore();<EOL><DEDENT>else:<EOL><INDENT>self.__prcess_by_python();<EOL><DEDENT>

!
        @brief Performs cluster analysis in line with rules of BSAS algorithm.

        @remark Results of clustering can be obtained using corresponding get methods.

        @see get_clusters()
        @see get_representatives()


index_cluster = -<NUM_LIT:1>;<EOL>nearest_distance = float('<STR_LIT>');<EOL>for index in range(len(self._representatives)):<EOL><INDENT>distance = self._metric(point, self._representatives[index]);<EOL>if distance < nearest_distance:<EOL><INDENT>index_cluster = index;<EOL>nearest_distance = distance;<EOL><DEDENT><DEDENT>return index_cluster, nearest_distance<EOL>

!
        @brief Find nearest cluster to the specified point.

        @param[in] point (list): Point from dataset.

        @return (uint, double) Index of nearest cluster and distance to it.


def __init__(self, data, amount_centers):

self.__data = data<EOL>self.__amount = amount_centers<EOL>self.__available_indexes = set(list(range(len(self.__data))))<EOL>if self.__amount <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if self.__amount > len(self.__data):<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__amount)<EOL><DEDENT>

!
        @brief Creates instance of random center initializer.

        @param[in] data (list): List of points where each point is represented by list of coordinates.
        @param[in] amount_centers (unit): Amount of centers that should be initialized.


index_center = random.randint(<NUM_LIT:0>, len(self.__data) - <NUM_LIT:1>)<EOL>if return_index:<EOL><INDENT>return index_center<EOL><DEDENT>return self.__data[index_center]<EOL>

!
        @brief Choose randomly first center.

        @param[in] return_index (bool): If True then return center's index instead of point.

        @return (array_like) First center.<br>
                (uint) Index of first center.


if (self.__amount <= <NUM_LIT:0>) or (self.__amount > len(self.__data)):<EOL><INDENT>raise AttributeError("<STR_LIT>" + str(self.__amount) + "<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if self.__candidates != kmeans_plusplus_initializer.FARTHEST_CENTER_CANDIDATE:<EOL><INDENT>if (self.__candidates <= <NUM_LIT:0>) or (self.__candidates > len(self.__data)):<EOL><INDENT>raise AttributeError("<STR_LIT>" + str(self.__candidates) + "<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>if len(self.__data) == <NUM_LIT:0>:<EOL><INDENT>raise AttributeError("<STR_LIT>")<EOL><DEDENT>

!
        @brief Checks input parameters of the algorithm and if something wrong then corresponding exception is thrown.


random_index_point = random.randint(<NUM_LIT:0>, len(self.__data[<NUM_LIT:0>]))<EOL>if random_index_point not in self.__available_indexes:<EOL><INDENT>random_index_point = self.__available_indexes.pop()<EOL><DEDENT>else:<EOL><INDENT>self.__available_indexes.remove(random_index_point)<EOL><DEDENT>if return_index:<EOL><INDENT>return random_index_point<EOL><DEDENT>return self.__data[random_index_point]<EOL>

!
        @brief Generates and returns random center.

        @param[in] return_index (bool): If True then returns index of point from input data instead of point itself.


return_index = kwargs.get('<STR_LIT>', False)<EOL>index_point = self.__get_initial_center(True)<EOL>centers = [index_point]<EOL>self.__free_indexes.remove(index_point)<EOL>for _ in range(<NUM_LIT:1>, self.__amount):<EOL><INDENT>index_point = self.__get_next_center(centers, True)<EOL>centers.append(index_point)<EOL>self.__free_indexes.remove(index_point)<EOL><DEDENT>if not return_index:<EOL><INDENT>centers = [self.__data[index] for index in centers]<EOL><DEDENT>return centers<EOL>

!
        @brief Calculates initial centers using K-Means++ method.

        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'return_index').

        Keyword Args:

            - return_index (bool): If True then returns indexes of points from input data instead of points itself.

        @return (list) List of initialized initial centers.
                  If argument 'return_index' is False then returns list of points.
                  If argument 'return_index' is True then returns list of indexes.


return self.__cells<EOL>

!
        @brief Returns CLIQUE blocks that are formed during clustering process.
        @details CLIQUE blocks can be used for visualization purposes. Each CLIQUE block contain its logical location
                  in grid, spatial location in data space and points that belong to block.

        @return (list) List of CLIQUE blocks.


return self.__noise<EOL>

!
        @brief Returns allocated noise.

        @remark Allocated noise is returned only after data processing (method process()). Otherwise empty list is returned.

        @return (list) List of indexes that are marked as a noise.

        @see process()
        @see get_clusters()


return self.__visited<EOL>

!
        @brief Defines whether block is visited during cluster analysis.
        @details If cluster analysis has not been performed then value will False.

        @return (bool) True if block has been visited during processing, False otherwise.


for index_dimension in range(self.__dimension):<EOL><INDENT>if self.__coordiate[index_dimension] + <NUM_LIT:1> < self.__intervals:<EOL><INDENT>self.__coordiate[index_dimension] += <NUM_LIT:1><EOL>return<EOL><DEDENT>else:<EOL><INDENT>self.__coordiate[index_dimension] = <NUM_LIT:0><EOL><DEDENT><DEDENT>self.__coordiate = None<EOL>

!
        @brief Forms logical location for next block.


def __init__(self, logical_location=None, spatial_location=None, points=None, visited=False):

self.__logical_location = logical_location or []<EOL>self.__spatial_location = spatial_location<EOL>self.__points = points or []<EOL>self.__visited = visited<EOL>

!
        @brief Initializes CLIQUE block.

        @param[in] logical_location (list): Logical location of the block in CLIQUE grid.
        @param[in] spatial_location (spatial_block): Spatial location in data space.
        @param[in] points (array_like): Points that belong to this block (can be obtained by method 'capture_points',
                    this parameter is used by CLIQUE in case of processing by C++ implementation when clustering
                    result are passed back to Python code.
        @param[in] visited (bool): Marks if block is visited during clustering process.


return self.__points<EOL>

!
        @brief Points that belong to the CLIQUE block.
        @details Points are represented by indexes that correspond to points in input data space.

        @return (array_like) Points that belong to the CLIQUE block.

        @see capture_points


self.__logical_location = location<EOL>

!
        @brief Assign logical location to CLIQUE block.

        @param[in] location (list): New logical location of the block in CLIQUE grid.


if self.__ccore:<EOL><INDENT>self.__process_by_ccore()<EOL><DEDENT>else:<EOL><INDENT>self.__process_by_python()<EOL><DEDENT>return self<EOL>

!
        @brief Performs clustering process in line with rules of CLIQUE clustering algorithm.

        @return (clique) Returns itself (CLIQUE instance).

        @see get_clusters()
        @see get_noise()
        @see get_cells()


return self.__coordiate<EOL>

!
        @brief Returns current block coordinate.


return str(self.__logical_location)<EOL>

!
        @brief Returns string representation of the block using its logical location in CLIQUE grid.


cell.visited = True<EOL>if len(cell.points) <= self.__density_threshold:<EOL><INDENT>if len(cell.points) > <NUM_LIT:0>:<EOL><INDENT>self.__noise.extend(cell.points)<EOL><DEDENT>return<EOL><DEDENT>cluster = cell.points[:]<EOL>neighbors = self.__get_neighbors(cell)<EOL>for neighbor in neighbors:<EOL><INDENT>if len(neighbor.points) > self.__density_threshold:<EOL><INDENT>cluster.extend(neighbor.points)<EOL>neighbors += self.__get_neighbors(neighbor)<EOL><DEDENT>elif len(neighbor.points) > <NUM_LIT:0>:<EOL><INDENT>self.__noise.extend(neighbor.points)<EOL><DEDENT><DEDENT>self.__clusters.append(cluster)<EOL>

!
        @brief Tries to expand cluster from specified cell.
        @details During expanding points are marked as noise or append to new cluster.

        @param[in] cell (clique_block): CLIQUE block from that cluster should be expanded.


neighbors = []<EOL>for index_dimension in range(len(self.__logical_location)):<EOL><INDENT>if self.__logical_location[index_dimension] + <NUM_LIT:1> < edge:<EOL><INDENT>position = self.__logical_location[:]<EOL>position[index_dimension] += <NUM_LIT:1><EOL>neighbors.append(position)<EOL><DEDENT>if self.__logical_location[index_dimension] - <NUM_LIT:1> >= <NUM_LIT:0>:<EOL><INDENT>position = self.__logical_location[:]<EOL>position[index_dimension] -= <NUM_LIT:1><EOL>neighbors.append(position)<EOL><DEDENT><DEDENT>return neighbors<EOL>

!
        @brief Forms list of logical location of each neighbor for this particular CLIQUE block.

        @param[in] edge (uint): Amount of intervals in each dimension that is used for clustering process.

        @return (list) Logical location of each neighbor for this particular CLIQUE block.


if len(self.__data) == <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if self.__amount_intervals <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__amount_intervals)<EOL><DEDENT>if self.__density_threshold < <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__density_threshold)<EOL><DEDENT>

!
        @brief Check input arguments of CLIQUE algorithm and if one of them is not correct then appropriate exception
                is thrown.


data_sizes, min_corner, max_corner = self.__get_data_size_derscription()<EOL>dimension = len(self.__data[<NUM_LIT:0>])<EOL>cell_sizes = [dimension_length / self.__amount_intervals for dimension_length in data_sizes]<EOL>self.__cells = [clique_block() for _ in range(pow(self.__amount_intervals, dimension))]<EOL>iterator = coordinate_iterator(dimension, self.__amount_intervals)<EOL>point_availability = [True] * len(self.__data)<EOL>self.__cell_map = {}<EOL>for index_cell in range(len(self.__cells)):<EOL><INDENT>logical_location = iterator.get_coordinate()<EOL>iterator.increment()<EOL>self.__cells[index_cell].logical_location = logical_location[:]<EOL>cur_max_corner, cur_min_corner = self.__get_spatial_location(logical_location, min_corner, max_corner, cell_sizes)<EOL>self.__cells[index_cell].spatial_location = spatial_block(cur_max_corner, cur_min_corner)<EOL>self.__cells[index_cell].capture_points(self.__data, point_availability)<EOL>self.__cell_map[self.__location_to_key(logical_location)] = self.__cells[index_cell]<EOL><DEDENT>

!
        @brief Creates CLIQUE grid that consists of CLIQUE blocks for clustering process.


return "<STR_LIT>" % (self.__max_corner, self.__min_corner)<EOL>

!
        @brief Returns string block description.

        @return String representation of the block.


(self.__clusters, self.__noise, block_logical_locations, block_max_corners, block_min_corners, block_points) =wrapper.clique(self.__data, self.__amount_intervals, self.__density_threshold)<EOL>amount_cells = len(block_logical_locations)<EOL>for i in range(amount_cells):<EOL><INDENT>self.__cells.append(clique_block(block_logical_locations[i],<EOL>spatial_block(block_max_corners[i], block_min_corners[i]),<EOL>block_points[i],<EOL>True))<EOL><DEDENT>

!
        @brief Performs cluster analysis using C++ implementation of CLIQUE algorithm that is used by default if
                user's target platform is supported.


neighbors = []<EOL>location_neighbors = cell.get_location_neighbors(self.__amount_intervals)<EOL>for i in range(len(location_neighbors)):<EOL><INDENT>key = self.__location_to_key(location_neighbors[i])<EOL>candidate_neighbor = self.__cell_map[key]<EOL>if not candidate_neighbor.visited:<EOL><INDENT>candidate_neighbor.visited = True<EOL>neighbors.append(candidate_neighbor)<EOL><DEDENT><DEDENT>return neighbors<EOL>

!
        @brief Returns neighbors for specified CLIQUE block as clique_block objects.

        @return (list) Neighbors as clique_block objects.


return self.__spatial_location<EOL>

!
        @brief Spatial location is represented by real data space coordinates.
        @return (spatial_block) Spatial block that describes location in data space.


for cell in self.__cells:<EOL><INDENT>if cell.visited is False:<EOL><INDENT>self.__expand_cluster(cell)<EOL><DEDENT><DEDENT>

!
        @brief Performs cluster analysis using formed CLIQUE blocks.


self.__create_grid()<EOL>self.__allocate_clusters()<EOL>self.__cells_map.clear()<EOL>

!
        @brief Performs cluster analysis using Python implementation of CLIQUE algorithm.


def __init__(self, max_corner, min_corner):

self.__max_corner = max_corner<EOL>self.__min_corner = min_corner<EOL>

!
        @brief Creates spatial block in data space.

        @param[in] max_corner (array_like): Maximum corner coordinates of the block.
        @param[in] min_corner (array_like): Minimal corner coordinates of the block.


random.seed()<EOL>for _ in range(<NUM_LIT:0>, self.__numlocal):<EOL><INDENT>self.__current = random.sample(range(<NUM_LIT:0>, len(self.__pointer_data)), self.__number_clusters)<EOL>self.__update_clusters(self.__current)<EOL>self.__optimize_configuration()<EOL>estimation = self.__calculate_estimation()<EOL>if estimation < self.__optimal_estimation:<EOL><INDENT>self.__optimal_medoids = self.__current[:]<EOL>self.__optimal_estimation = estimation<EOL><DEDENT><DEDENT>self.__update_clusters(self.__optimal_medoids)<EOL>

!
        @brief Performs cluster analysis in line with rules of CLARANS algorithm.

        @see get_clusters()
        @see get_medoids()


return self.__clusters<EOL>

!
        @brief Returns allocated clusters by the algorithm.

        @remark Allocated clusters can be returned only after data processing (use method process()), otherwise empty list is returned.

        @return (list) List of allocated clusters, each cluster contains indexes of objects in list of data.

        @see process()
        @see get_medoids()


self.__belong = [<NUM_LIT:0>] * len(self.__pointer_data)<EOL>self.__clusters = [[] for i in range(len(medoids))]<EOL>for index_point in range(len(self.__pointer_data)):<EOL><INDENT>index_optim = -<NUM_LIT:1><EOL>dist_optim = <NUM_LIT:0.0><EOL>for index in range(len(medoids)):<EOL><INDENT>dist = euclidean_distance_square(self.__pointer_data[index_point], self.__pointer_data[medoids[index]])<EOL>if (dist < dist_optim) or (index is <NUM_LIT:0>):<EOL><INDENT>index_optim = index<EOL>dist_optim = dist<EOL><DEDENT><DEDENT>self.__clusters[index_optim].append(index_point)<EOL>self.__belong[index_point] = index_optim<EOL><DEDENT>self.__clusters = [cluster for cluster in self.__clusters if len(cluster) > <NUM_LIT:0>]<EOL>

!
        @brief Forms cluster in line with specified medoids by calculation distance from each point to medoids.


def __find_another_nearest_medoid(self, point_index, current_medoid_index):

other_medoid_index = -<NUM_LIT:1><EOL>other_distance_nearest = float('<STR_LIT>')<EOL>for index_medoid in self.__current:<EOL><INDENT>if (index_medoid != current_medoid_index):<EOL><INDENT>other_distance_candidate = euclidean_distance_square(self.__pointer_data[point_index], self.__pointer_data[current_medoid_index])<EOL>if other_distance_candidate < other_distance_nearest:<EOL><INDENT>other_distance_nearest = other_distance_candidate<EOL>other_medoid_index = index_medoid<EOL><DEDENT><DEDENT><DEDENT>return other_medoid_index<EOL>

!
        @brief Finds the another nearest medoid for the specified point that is differ from the specified medoid.

        @param[in] point_index: index of point in dataspace for that searching of medoid in current list of medoids is perfomed.
        @param[in] current_medoid_index: index of medoid that shouldn't be considered as a nearest.

        @return (uint) index of the another nearest medoid for the point.


def __get_nearest_feature(self, point, feature_collection):

minimum_distance = float("<STR_LIT>");<EOL>index_nearest_feature = -<NUM_LIT:1>;<EOL>for index_entry in range(<NUM_LIT:0>, len(feature_collection)):<EOL><INDENT>point_entry = cfentry(<NUM_LIT:1>, linear_sum([ point ]), square_sum([ point ]));<EOL>distance = feature_collection[index_entry].get_distance(point_entry, self.__measurement_type);<EOL>if (distance < minimum_distance):<EOL><INDENT>minimum_distance = distance;<EOL>index_nearest_feature = index_entry;<EOL><DEDENT><DEDENT>return (minimum_distance, index_nearest_feature)<EOL>

!
        @brief Find nearest entry for specified point.

        @param[in] point (list): Pointer to point from input dataset.
        @param[in] feature_collection (list): Feature collection that is used for obtaining nearest feature for the specified point.

        @return (double, uint) Tuple of distance to nearest entry to the specified point and index of that entry.


rebuild_result = False;<EOL>increased_diameter = self.__tree.threshold * self.__diameter_multiplier;<EOL>tree = None;<EOL>while(rebuild_result is False):<EOL><INDENT>if (increased_diameter == <NUM_LIT:0.0>):<EOL><INDENT>increased_diameter = <NUM_LIT:1.0>;<EOL><DEDENT>tree = cftree(self.__tree.branch_factor, self.__tree.max_entries, increased_diameter, self.__tree.type_measurement);<EOL>for index_point in range(<NUM_LIT:0>, index_point + <NUM_LIT:1>):<EOL><INDENT>point = self.__pointer_data[index_point];<EOL>tree.insert_cluster([point]);<EOL>if (tree.amount_entries > self.__entry_size_limit):<EOL><INDENT>increased_diameter *= self.__diameter_multiplier;<EOL>continue;<EOL><DEDENT><DEDENT>rebuild_result = True;<EOL><DEDENT>return tree<EOL>

!
        @brief Rebuilt tree in case of maxumum number of entries is exceeded.

        @param[in] index_point (uint): Index of point that is used as end point of re-building.

        @return (cftree) Rebuilt tree with encoded points till specified point from input data space.


return type_encoding.CLUSTER_INDEX_LIST_SEPARATION<EOL>

!
        @brief Returns clustering result representation type that indicate how clusters are encoded.

        @return (type_encoding) Clustering result representation.

        @see get_clusters()


self.__features = [];<EOL>if (len(self.__tree.leafes) == <NUM_LIT:1>):<EOL><INDENT>for entry in self.__tree.leafes[<NUM_LIT:0>].entries:<EOL><INDENT>self.__features.append(entry);<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for node in self.__tree.leafes:<EOL><INDENT>self.__features.append(node.feature);<EOL><DEDENT><DEDENT>

!
        @brief Extracts features from CF-tree cluster.


minimum_distance = float("<STR_LIT>");<EOL>index1 = <NUM_LIT:0>;<EOL>index2 = <NUM_LIT:0>;<EOL>for index_candidate1 in range(<NUM_LIT:0>, len(self.__features)):<EOL><INDENT>feature1 = self.__features[index_candidate1];<EOL>for index_candidate2 in range(index_candidate1 + <NUM_LIT:1>, len(self.__features)):<EOL><INDENT>feature2 = self.__features[index_candidate2];<EOL>distance = feature1.get_distance(feature2, self.__measurement_type);<EOL>if (distance < minimum_distance):<EOL><INDENT>minimum_distance = distance;<EOL>index1 = index_candidate1;<EOL>index2 = index_candidate2;<EOL><DEDENT><DEDENT><DEDENT>return [index1, index2]<EOL>

!
        @brief Find pair of nearest CF entries.

        @return (list) List of two nearest enties that are represented by list [index_point1, index_point2].


if self.__ccore is True:<EOL><INDENT>self.__process_by_ccore()<EOL><DEDENT>else:<EOL><INDENT>self.__process_by_python()<EOL><DEDENT>

!
        @brief Performs cluster analysis in line with rules of CURE algorithm.

        @remark Results of clustering can be obtained using corresponding get methods.

        @see get_clusters()


for index in range(len(self.__queue)):<EOL><INDENT>if cluster.distance < self.__queue[index].distance:<EOL><INDENT>self.__queue.insert(index, cluster)<EOL>return<EOL><DEDENT><DEDENT>self.__queue.append(cluster)<EOL>

!
        @brief Insert cluster to the list (sorted queue) in line with sequence order (distance).

        @param[in] cluster (cure_cluster): Cluster that should be inserted.


for point in cluster.rep:<EOL><INDENT>self.__tree.remove(point, payload=cluster)<EOL><DEDENT>

!
        @brief Remove representation points of clusters from the k-d tree

        @param[in] cluster (cure_cluster): Cluster whose representation points should be removed.


def __merge_clusters(self, cluster1, cluster2):

merged_cluster = cure_cluster(None, None)<EOL>merged_cluster.points = cluster1.points + cluster2.points<EOL>merged_cluster.indexes = cluster1.indexes + cluster2.indexes<EOL>dimension = len(cluster1.mean)<EOL>merged_cluster.mean = [<NUM_LIT:0>] * dimension<EOL>if merged_cluster.points[<NUM_LIT:1>:] == merged_cluster.points[:-<NUM_LIT:1>]:<EOL><INDENT>merged_cluster.mean = merged_cluster.points[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>for index in range(dimension):<EOL><INDENT>merged_cluster.mean[index] = ( len(cluster1.points) * cluster1.mean[index] + len(cluster2.points) * cluster2.mean[index] ) / ( len(cluster1.points) + len(cluster2.points) );<EOL><DEDENT><DEDENT>temporary = list()<EOL>for index in range(self.__number_represent_points):<EOL><INDENT>maximal_distance = <NUM_LIT:0><EOL>maximal_point = None<EOL>for point in merged_cluster.points:<EOL><INDENT>minimal_distance = <NUM_LIT:0><EOL>if index == <NUM_LIT:0>:<EOL><INDENT>minimal_distance = euclidean_distance_square(point, merged_cluster.mean)<EOL><DEDENT>else:<EOL><INDENT>minimal_distance = min([euclidean_distance_square(point, p) for p in temporary])<EOL><DEDENT>if minimal_distance >= maximal_distance:<EOL><INDENT>maximal_distance = minimal_distance<EOL>maximal_point = point<EOL><DEDENT><DEDENT>if maximal_point not in temporary:<EOL><INDENT>temporary.append(maximal_point)<EOL><DEDENT><DEDENT>for point in temporary:<EOL><INDENT>representative_point = [<NUM_LIT:0>] * dimension<EOL>for index in range(dimension):<EOL><INDENT>representative_point[index] = point[index] + self.__compression * (merged_cluster.mean[index] - point[index])<EOL><DEDENT>merged_cluster.rep.append(representative_point)<EOL><DEDENT>return merged_cluster<EOL>

!
        @brief Merges two clusters and returns new merged cluster. Representation points and mean points are calculated for the new cluster.

        @param[in] cluster1 (cure_cluster): Cluster that should be merged.
        @param[in] cluster2 (cure_cluster): Cluster that should be merged.

        @return (cure_cluster) New merged CURE cluster.


if len(self.__pointer_data) == <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if self.__number_cluster <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__number_cluster)<EOL><DEDENT>if self.__compression < <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__compression)<EOL><DEDENT>if self.__number_represent_points <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__number_cluster)<EOL><DEDENT>

!
        @brief Check input arguments of BANG algorithm and if one of them is not correct then appropriate exception
                is thrown.


self.__queue = [cure_cluster(self.__pointer_data[index_point], index_point) for index_point in range(len(self.__pointer_data))]<EOL>for i in range(<NUM_LIT:0>, len(self.__queue)):<EOL><INDENT>minimal_distance = float('<STR_LIT>')<EOL>closest_index_cluster = -<NUM_LIT:1><EOL>for k in range(<NUM_LIT:0>, len(self.__queue)):<EOL><INDENT>if i != k:<EOL><INDENT>dist = self.__cluster_distance(self.__queue[i], self.__queue[k])<EOL>if dist < minimal_distance:<EOL><INDENT>minimal_distance = dist<EOL>closest_index_cluster = k<EOL><DEDENT><DEDENT><DEDENT>self.__queue[i].closest = self.__queue[closest_index_cluster]<EOL>self.__queue[i].distance = minimal_distance<EOL><DEDENT>self.__queue.sort(key = lambda x: x.distance, reverse = False)<EOL>

!
        @brief Create queue of sorted clusters by distance between them, where first cluster has the nearest neighbor. At the first iteration each cluster contains only one point.

        @param[in] data (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple.

        @return (list) Create queue of sorted clusters by distance between them.


self.__tree = kdtree()<EOL>for current_cluster in self.__queue:<EOL><INDENT>for representative_point in current_cluster.rep:<EOL><INDENT>self.__tree.insert(representative_point, current_cluster)<EOL><DEDENT><DEDENT>

!
        @brief Create k-d tree in line with created clusters. At the first iteration contains all points from the input data set.

        @return (kdtree) k-d tree that consist of representative points of CURE clusters.


def __init__(self, data, number_cluster, number_represent_points = <NUM_LIT:5>, compression = <NUM_LIT:0.5>, ccore = True):

self.__pointer_data = self.__prepare_data_points(data)<EOL>self.__clusters = None<EOL>self.__representors = None<EOL>self.__means = None<EOL>self.__number_cluster = number_cluster<EOL>self.__number_represent_points = number_represent_points<EOL>self.__compression = compression<EOL>self.__ccore = ccore<EOL>if self.__ccore:<EOL><INDENT>self.__ccore = ccore_library.workable()<EOL><DEDENT>self.__validate_arguments()<EOL>

!
        @brief Constructor of clustering algorithm CURE.

        @param[in] data (array_like): Input data that should be processed.
        @param[in] number_cluster (uint): Number of clusters that should be allocated.
        @param[in] number_represent_points (uint): Number of representative points for each cluster.
        @param[in] compression (double): Coefficient defines level of shrinking of representation points toward the mean of the new created cluster after merging on each step. Usually it destributed from 0 to 1.
        @param[in] ccore (bool): If True then CCORE (C++ solution) will be used for solving.


<EOL>self.points = [ ]<EOL>self.indexes = -<NUM_LIT:1><EOL>self.mean = None<EOL>self.rep = [ ]<EOL>if point is not None:<EOL><INDENT>self.points = [ point ]<EOL>self.indexes = [ index ]<EOL>self.mean = point<EOL>self.rep = [ point ]<EOL><DEDENT>self.closest = None<EOL>self.distance = float('<STR_LIT>')<EOL>

!
        @brief Constructor of CURE cluster.

        @param[in] point (list): Point represented by list of coordinates.
        @param[in] index (uint): Index point in dataset.


self.__queue.remove(cluster)<EOL>self.__insert_cluster(cluster)<EOL>

!
        @brief Relocate cluster in list in line with distance order.

        @param[in] cluster (cure_cluster): Cluster that should be relocated in line with order.


return self.__clusters<EOL>

!
        @brief Returns list of allocated clusters, each cluster contains indexes of objects in list of data.

        @return (list) List of allocated clusters.

        @see process()
        @see get_representors()
        @see get_means()


return self.__means<EOL>

!
        @brief Returns list of mean values of each cluster.
        @details Cluster index should be used for navigation between mean values.

        @return (list) List of mean values of each cluster.

        @see get_clusters()
        @see get_representors()


if isinstance(sample, numpy.ndarray):<EOL><INDENT>return sample.tolist()<EOL><DEDENT>return sample<EOL>

!
        @brief Prepare data points for clustering.
        @details In case of numpy.array there are a lot of overloaded basic operators, such as __contains__, __eq__.

        @return (list) Returns sample in list format.


return self.__representors<EOL>

!
        @brief Returns list of point-representors of each cluster.
        @details Cluster index should be used for navigation between lists of point-representors.

        @return (list) List of point-representors of each cluster.

        @see get_clusters()
        @see get_means()


kdnodes = self.__kdtree.find_nearest_dist_nodes(self.__sample_pointer[optic_object.index_object], self.__eps)<EOL>return [[node_tuple[<NUM_LIT:1>].payload, math.sqrt(node_tuple[<NUM_LIT:0>])] for node_tuple in kdnodes if<EOL>node_tuple[<NUM_LIT:1>].payload != optic_object.index_object]<EOL>

!
        @brief Return neighbors of the specified object in case of sequence of points.

        @param[in] optic_object (optics_descriptor): Object for which neighbors should be returned in line with connectivity radius.

        @return (list) List of indexes of neighbors in line the connectivity radius.


(self.__clusters, self.__noise, self.__ordering, self.__eps,<EOL>objects_indexes, objects_core_distances, objects_reachability_distances) =wrapper.optics(self.__sample_pointer, self.__eps, self.__minpts, self.__amount_clusters, self.__data_type)<EOL>self.__optics_objects = []<EOL>for i in range(len(objects_indexes)):<EOL><INDENT>if objects_core_distances[i] < <NUM_LIT:0.0>:<EOL><INDENT>objects_core_distances[i] = None<EOL><DEDENT>if objects_reachability_distances[i] < <NUM_LIT:0.0>:<EOL><INDENT>objects_reachability_distances[i] = None<EOL><DEDENT>optics_object = optics_descriptor(objects_indexes[i], objects_core_distances[i], objects_reachability_distances[i])<EOL>optics_object.processed = True<EOL>self.__optics_objects.append(optics_object)<EOL><DEDENT>

!
        @brief Performs cluster analysis using CCORE (C/C++ part of pyclustering library).


return len(self.__ordering)<EOL>

!
        @brief Returns length of clustering-ordering diagram.


def __init__(self, sample, eps, minpts, amount_clusters = None, ccore = True, **kwargs):

self.__sample_pointer = sample      <EOL>self.__eps = eps                    <EOL>self.__minpts = minpts              <EOL>self.__amount_clusters = amount_clusters<EOL>self.__ordering = None<EOL>self.__clusters = None<EOL>self.__noise = None<EOL>self.__optics_objects = None<EOL>self.__data_type = kwargs.get('<STR_LIT>', '<STR_LIT>')<EOL>self.__kdtree = None<EOL>self.__ccore = ccore<EOL>self.__neighbor_searcher = self.__create_neighbor_searcher(self.__data_type)<EOL>if self.__ccore:<EOL><INDENT>self.__ccore = ccore_library.workable()<EOL><DEDENT>

!
        @brief Constructor of clustering algorithm OPTICS.

        @param[in] sample (list): Input data that is presented as a list of points (objects), where each point is represented by list or tuple.
        @param[in] eps (double): Connectivity radius between points, points may be connected if distance between them less than the radius.
        @param[in] minpts (uint): Minimum number of shared neighbors that is required for establishing links between points.
        @param[in] amount_clusters (uint): Optional parameter where amount of clusters that should be allocated is specified.
                    In case of usage 'amount_clusters' connectivity radius can be greater than real, in other words, there is place for mistake
                    in connectivity radius usage.
        @param[in] ccore (bool): if True than DLL CCORE (C++ solution) will be used for solving the problem.
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'data_type').

        Keyword Args:

            - data_type (string): Data type of input sample 'data' that is processed by the algorithm ('points', 'distance_matrix').


def __init__(self, index, core_distance = None, reachability_distance = None):

<EOL>self.index_object = index<EOL>self.core_distance = core_distance<EOL>self.reachability_distance = reachability_distance<EOL>self.processed = False<EOL>

!
        @brief Constructor of object description in optics terms.

        @param[in] index (uint): Index of the object in the data set.
        @param[in] core_distance (double): Core distance that is minimum distance to specified number of neighbors.
        @param[in] reachability_distance (double): Reachability distance to this object.


self.__processed = [False] * len(sample)<EOL>self.__optics_objects = [optics_descriptor(i) for i in range(len(sample))]      <EOL>self.__ordered_database = []        <EOL>self.__clusters = None      <EOL>self.__noise = None         <EOL>

!
        @brief Initializes internal states and resets clustering results in line with input sample.


return self.__clusters<EOL>

!
        @brief Returns list of allocated clusters, where each cluster contains indexes of objects and each cluster is represented by list.

        @return (list) List of allocated clusters.

        @see process()
        @see get_noise()
        @see get_ordering()
        @see get_radius()


if self.__ordering is None:<EOL><INDENT>self.__ordering = []<EOL>for cluster in self.__clusters:<EOL><INDENT>for index_object in cluster:<EOL><INDENT>optics_object = self.__optics_objects[index_object]<EOL>if optics_object.reachability_distance is not None:<EOL><INDENT>self.__ordering.append(optics_object.reachability_distance)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return self.__ordering<EOL>

!
        @brief Returns clustering ordering information about the input data set.
        @details Clustering ordering of data-set contains the information about the internal clustering structure in line with connectivity radius.

        @return (ordering_analyser) Analyser of clustering ordering.

        @see process()
        @see get_clusters()
        @see get_noise()
        @see get_radius()
        @see get_optics_objects()


self.__clusters = []<EOL>self.__noise = []<EOL>current_cluster = self.__noise<EOL>for optics_object in self.__ordered_database:<EOL><INDENT>if (optics_object.reachability_distance is None) or (optics_object.reachability_distance > self.__eps):<EOL><INDENT>if (optics_object.core_distance is not None) and (optics_object.core_distance <= self.__eps):<EOL><INDENT>self.__clusters.append([ optics_object.index_object ])<EOL>current_cluster = self.__clusters[-<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>self.__noise.append(optics_object.index_object)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>current_cluster.append(optics_object.index_object)<EOL><DEDENT><DEDENT>

!
        @brief Extract clusters and noise from order database.


amount_clusters = <NUM_LIT:1><EOL>cluster_start = False<EOL>cluster_pick = False<EOL>total_similarity = True<EOL>previous_cluster_distance = None<EOL>previous_distance = None<EOL>cluster_borders = []<EOL>for index_ordering in range(len(self.__ordering)):<EOL><INDENT>distance = self.__ordering[index_ordering]<EOL>if distance >= radius:<EOL><INDENT>if cluster_start is False:<EOL><INDENT>cluster_start = True<EOL>amount_clusters += <NUM_LIT:1><EOL>if index_ordering != <NUM_LIT:0>:<EOL><INDENT>cluster_borders.append(index_ordering)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if (distance < previous_cluster_distance) and (cluster_pick is False):<EOL><INDENT>cluster_pick = True<EOL><DEDENT>elif (distance > previous_cluster_distance) and (cluster_pick is True):<EOL><INDENT>cluster_pick = False<EOL>amount_clusters += <NUM_LIT:1><EOL>if index_ordering != <NUM_LIT:0>:<EOL><INDENT>cluster_borders.append(index_ordering)<EOL><DEDENT><DEDENT><DEDENT>previous_cluster_distance = distance<EOL><DEDENT>else:<EOL><INDENT>cluster_start = False<EOL>cluster_pick = False<EOL><DEDENT>if (previous_distance is not None) and (distance != previous_distance):<EOL><INDENT>total_similarity = False<EOL><DEDENT>previous_distance = distance<EOL><DEDENT>if (total_similarity is True) and (previous_distance > radius):<EOL><INDENT>amount_clusters = <NUM_LIT:0><EOL><DEDENT>return amount_clusters, cluster_borders<EOL>

!
        @brief Obtains amount of clustering that can be allocated by using specified radius for ordering diagram and borders between them.
        @details When growth of reachability-distances is detected than it is considered as a start point of cluster,
                 than pick is detected and after that recession is observed until new growth (that means end of the
                 current cluster and start of a new one) or end of diagram.

        @param[in] radius (double): connectivity radius that is used for cluster allocation.

        @return (unit, list) Amount of clusters that can be allocated by the connectivity radius on ordering diagram and borders between them using indexes
                 from ordering diagram (amount_clusters, border_clusters).


return self.__noise<EOL>

!
        @brief Returns list of noise that contains indexes of objects that corresponds to input data.

        @return (list) List of allocated noise objects.

        @see process()
        @see get_clusters()
        @see get_ordering()
        @see get_radius()


self.__ordering = ordering_diagram<EOL>

!
        @brief Analyser of ordering diagram that is based on reachability-distances.

        @see calculate_connvectivity_radius


if self.__ccore is True:<EOL><INDENT>self.__process_by_ccore()<EOL><DEDENT>else:<EOL><INDENT>self.__process_by_python()<EOL><DEDENT>

!
        @brief Performs cluster analysis in line with rules of OPTICS algorithm.

        @remark Results of clustering can be obtained using corresponding gets methods.

        @see get_clusters()
        @see get_noise()
        @see get_ordering()


return self.__ordering<EOL>

!
        @brief (list) Returns values of dataset cluster ordering.


def calculate_connvectivity_radius(self, amount_clusters, maximum_iterations = <NUM_LIT:100>):

maximum_distance = max(self.__ordering)<EOL>upper_distance = maximum_distance<EOL>lower_distance = <NUM_LIT:0.0><EOL>result = None<EOL>amount, borders = self.extract_cluster_amount(maximum_distance)<EOL>if amount <= amount_clusters:<EOL><INDENT>for _ in range(maximum_iterations):<EOL><INDENT>radius = (lower_distance + upper_distance) / <NUM_LIT><EOL>amount, borders = self.extract_cluster_amount(radius)<EOL>if amount == amount_clusters:<EOL><INDENT>result = radius<EOL>break<EOL><DEDENT>elif amount == <NUM_LIT:0>:<EOL><INDENT>break<EOL><DEDENT>elif amount > amount_clusters:<EOL><INDENT>lower_distance = radius<EOL><DEDENT>elif amount < amount_clusters:<EOL><INDENT>upper_distance = radius<EOL><DEDENT><DEDENT><DEDENT>return result, borders<EOL>

!
        @brief Calculates connectivity radius of allocation specified amount of clusters using ordering diagram and marks borders of clusters using indexes of values of ordering diagram.
        @details Parameter 'maximum_iterations' is used to protect from hanging when it is impossible to allocate specified number of clusters.

        @param[in] amount_clusters (uint): amount of clusters that should be allocated by calculated connectivity radius.
        @param[in] maximum_iterations (uint): maximum number of iteration for searching connectivity radius to allocated specified amount of clusters (by default it is restricted by 100 iterations).

        @return (double, list) Value of connectivity radius and borders of clusters like (radius, borders), radius may be 'None' as well as borders may be '[]'
                                if connectivity radius hasn't been found for the specified amount of iterations.


return self.__type_representation<EOL>

!
        @brief Returns current cluster representation.


def __init__(self, encoding, clusters, data):

self.__type_representation = encoding;<EOL>self.__clusters = clusters;<EOL>self.__data = data<EOL>

!
        @brief Constructor of clustering result representor.

        @param[in] encoding (type_encoding): Type of clusters representation (index list, object list or labels).
        @param[in] clusters (list): Current clusters representation.
        @param[in] data (list): Data that corresponds to clusters.


<EOL>res_idx = None<EOL>random_num = np.random.rand()<EOL>for _idx in range(len(probabilities)):<EOL><INDENT>if random_num < probabilities[_idx]:<EOL><INDENT>res_idx = _idx<EOL>break<EOL><DEDENT><DEDENT>if res_idx is None:<EOL><INDENT>print('<STR_LIT>', probabilities)<EOL>raise AttributeError("<STR_LIT>")<EOL><DEDENT>return res_idx<EOL>

!
        @brief Returns index in probabilities.

        @param[in] probabilities (list): List with segments in increasing sequence with val in [0, 1],
                   for example, [0 0.1 0.2 0.3 1.0].


@staticmethod<EOL><INDENT>def get_centres(chromosomes, data, count_clusters):<DEDENT>

centres = ga_math.calc_centers(chromosomes, data, count_clusters)<EOL>return centres<EOL>


def process(self, order = <NUM_LIT>, solution = solve_type.FAST, collect_dynamic = True):

if (self._ccore_network_pointer is not None):<EOL><INDENT>pointer_output_dynamic = syncnet_process(self._ccore_network_pointer, order, solution, collect_dynamic);<EOL>return syncnet_analyser(None, None, pointer_output_dynamic);<EOL><DEDENT>else:<EOL><INDENT>output_sync_dynamic = self.simulate_dynamic(order, solution, collect_dynamic);<EOL>return syncnet_analyser(output_sync_dynamic.output, output_sync_dynamic.time, None);<EOL><DEDENT>

!
        @brief Peforms cluster analysis using simulation of the oscillatory network.

        @param[in] order (double): Order of synchronization that is used as indication for stopping processing.
        @param[in] solution (solve_type): Specified type of solving diff. equation.
        @param[in] collect_dynamic (bool): Specified requirement to collect whole dynamic of the network.

        @return (syncnet_analyser) Returns analyser of results of clustering.


def __init__(self, phase, time, pointer_sync_analyser):

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

!
        @brief Constructor of the analyser.

        @param[in] phase (list): Output dynamic of the oscillatory network, where one iteration consists of all phases of oscillators.
        @param[in] time (list): Simulation time.
        @param[in] pointer_sync_analyser (POINTER): Pointer to CCORE analyser, if specified then other arguments can be omitted.


def allocate_clusters(self, eps = <NUM_LIT>, indexes = None, iteration = None):

return self.allocate_sync_ensembles(eps, indexes, iteration)<EOL>

!
        @brief Returns list of clusters in line with state of ocillators (phases).

        @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one cluster.
        @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) List of clusters, for example [ [cluster1], [cluster2], ... ].)


return type_encoding.CLUSTER_INDEX_LIST_SEPARATION<EOL>

!
        @brief Returns clustering result representation type that indicate how clusters are encoded.

        @return (type_encoding) Clustering result representation.

        @see get_clusters()


@staticmethod<EOL><INDENT>def animate_cluster_allocation(dataset, analyser, animation_velocity = <NUM_LIT>, tolerance = <NUM_LIT:0.1>, save_movie = None, title = 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>clusters = analyser.allocate_clusters(eps = tolerance, iteration = index_dynamic);<EOL>dynamic = analyser.output[index_dynamic];<EOL>visualizer = cluster_visualizer(size_row = <NUM_LIT:2>);<EOL>visualizer.append_clusters(clusters, dataset);<EOL>artist1, = ax1.plot(dynamic, [<NUM_LIT:1.0>] * len(dynamic), marker = '<STR_LIT:o>', color = '<STR_LIT>', ls = '<STR_LIT>');<EOL>visualizer.show(figure, display = False);<EOL>artist2 = figure.gca();<EOL>return [ artist1, artist2 ];<EOL><DEDENT>cluster_animation = animation.FuncAnimation(figure, frame_generation, len(analyser), 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(fps = <NUM_LIT:15>);<EOL>cluster_animation.save(save_movie, writer = ffmpeg_writer);<EOL>

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

        @param[in] dataset (list): Input data that was used for processing by the network.
        @param[in] analyser (syncnet_analyser): Output dynamic analyser of the Sync network.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds.
        @param[in] tolerance (double): Tolerance level that define maximal difference between phases of oscillators in one cluster.
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.
        @param[in] title (string): If it is specified then title will be displayed on the animation plot.


def __init__(self, sample, radius, conn_repr = conn_represent.MATRIX, initial_phases = initial_type.RANDOM_GAUSSIAN, enable_conn_weight = False, ccore = True):

self._ccore_network_pointer = None;<EOL>self._osc_loc = sample;<EOL>self._num_osc = len(sample);<EOL>if ( (ccore is True) and ccore_library.workable() ):<EOL><INDENT>self._ccore_network_pointer = syncnet_create_network(sample, radius, initial_phases, enable_conn_weight);<EOL>self._conn_represent = conn_represent.MATRIX;<EOL><DEDENT>else:<EOL><INDENT>super().__init__(len(sample), <NUM_LIT:1>, <NUM_LIT:0>, conn_type.DYNAMIC, conn_repr, initial_phases, False);<EOL>self._conn_weight = None;<EOL>self._ena_conn_weight = enable_conn_weight;<EOL>if (radius is not None):<EOL><INDENT>self._create_connections(radius);<EOL><DEDENT><DEDENT>

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

        @param[in] sample (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple.
        @param[in] radius (double): Connectivity radius between points, points should be connected if distance between them less then the radius.
        @param[in] conn_repr (conn_represent): Internal representation of connection in the network: matrix or list. Ignored in case of usage of CCORE library.
        @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.).
        @param[in] enable_conn_weight (bool): If True - enable mode when strength between oscillators depends on distance between two oscillators.
              If False - all connection between oscillators have the same strength that equals to 1 (True).
        @param[in] ccore (bool): Defines should be CCORE C++ library used instead of Python code or not.


def __init__(self, data, eps, number_clusters, threshold = <NUM_LIT:0.5>, ccore = True):

self.__pointer_data = data;<EOL>self.__eps = eps;<EOL>self.__number_clusters = number_clusters;<EOL>self.__threshold = threshold;<EOL>self.__clusters = None;<EOL>self.__ccore = ccore;<EOL>if (self.__ccore):<EOL><INDENT>self.__ccore = ccore_library.workable();<EOL><DEDENT>self.__degree_normalization = <NUM_LIT:1.0> + <NUM_LIT> * ( (<NUM_LIT:1.0> - threshold) / (<NUM_LIT:1.0> + threshold) );<EOL>self.__adjacency_matrix = None;<EOL>self.__create_adjacency_matrix()<EOL>

!
        @brief Constructor of clustering algorithm ROCK.

        @param[in] data (list): Input data - list of points where each point is represented by list of coordinates.
        @param[in] eps (double): Connectivity radius (similarity threshold), points are neighbors if distance between them is less than connectivity radius.
        @param[in] number_clusters (uint): Defines number of clusters that should be allocated from the input data set.
        @param[in] threshold (double): Value that defines degree of normalization that influences on choice of clusters for merging during processing.
        @param[in] ccore (bool): Defines should be CCORE (C++ pyclustering library) used instead of Python code or not.


size_data = len(self.__pointer_data);<EOL>self.__adjacency_matrix = [ [ <NUM_LIT:0> for i in range(size_data) ] for j in range(size_data) ];<EOL>for i in range(<NUM_LIT:0>, size_data):<EOL><INDENT>for j in range(i + <NUM_LIT:1>, size_data):<EOL><INDENT>distance = euclidean_distance(self.__pointer_data[i], self.__pointer_data[j]);<EOL>if (distance <= self.__eps):<EOL><INDENT>self.__adjacency_matrix[i][j] = <NUM_LIT:1>;<EOL>self.__adjacency_matrix[j][i] = <NUM_LIT:1>;<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Creates 2D adjacency matrix (list of lists) where each element described existence of link between points (means that points are neighbors).


<EOL>if (self.__ccore is True):<EOL><INDENT>self.__clusters = wrapper.rock(self.__pointer_data, self.__eps, self.__number_clusters, self.__threshold);<EOL><DEDENT>else:  <EOL><INDENT>self.__clusters = [[index] for index in range(len(self.__pointer_data))];<EOL>while (len(self.__clusters) > self.__number_clusters):<EOL><INDENT>indexes = self.__find_pair_clusters(self.__clusters);<EOL>if (indexes != [-<NUM_LIT:1>, -<NUM_LIT:1>]):<EOL><INDENT>self.__clusters[indexes[<NUM_LIT:0>]] += self.__clusters[indexes[<NUM_LIT:1>]];<EOL>self.__clusters.pop(indexes[<NUM_LIT:1>]);   <EOL><DEDENT>else:<EOL><INDENT>break;<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Performs cluster analysis in line with rules of ROCK algorithm.

        @remark Results of clustering can be obtained using corresponding get methods.

        @see get_clusters()


maximum_goodness = <NUM_LIT:0.0>;<EOL>cluster_indexes = [-<NUM_LIT:1>, -<NUM_LIT:1>];<EOL>for i in range(<NUM_LIT:0>, len(clusters)):<EOL><INDENT>for j in range(i + <NUM_LIT:1>, len(clusters)):<EOL><INDENT>goodness = self.__calculate_goodness(clusters[i], clusters[j]);<EOL>if (goodness > maximum_goodness):<EOL><INDENT>maximum_goodness = goodness;<EOL>cluster_indexes = [i, j];<EOL><DEDENT><DEDENT><DEDENT>return cluster_indexes<EOL>

!
        @brief Returns pair of clusters that are best candidates for merging in line with goodness measure.
               The pair of clusters for which the above goodness measure is maximum is the best pair of clusters to be merged.

        @param[in] clusters (list): List of clusters that have been allocated during processing, each cluster is represented by list of indexes of points from the input data set.

        @return (list) List that contains two indexes of clusters (from list 'clusters') that should be merged on this step.
                It can be equals to [-1, -1] when no links between clusters.


optimal_elbow_value = max(self.__elbows)<EOL>self.__kvalue = self.__elbows.index(optimal_elbow_value) + <NUM_LIT:1> + self.__kmin<EOL>

!
        @brief Finds elbow and returns corresponding K-value.


if isinstance(self.__initializer, kmeans_plusplus_initializer):<EOL><INDENT>initializer = wrapper.elbow_center_initializer.KMEANS_PLUS_PLUS<EOL><DEDENT>else:<EOL><INDENT>initializer = wrapper.elbow_center_initializer.RANDOM<EOL><DEDENT>result = wrapper.elbow(self.__data, self.__kmin, self.__kmax, initializer)<EOL>self.__kvalue = result[<NUM_LIT:0>]<EOL>self.__wce = result[<NUM_LIT:1>]<EOL>

!
        @brief Performs processing using C++ implementation.


if self.__ccore:<EOL><INDENT>self.__process_by_ccore()<EOL><DEDENT>else:<EOL><INDENT>self.__process_by_python()<EOL><DEDENT>return self<EOL>

!
        @brief Performs analysis to find out appropriate amount of clusters.

        @return


return self.__wce<EOL>

!
        @brief Returns list of total within cluster errors for each K-value (kmin, kmin + 1, ..., kmax - 1).


return self.__network.capture_objects<EOL>

!
        @brief Returns list of allocated clusters, each cluster contains indexes of objects in list of data.

        @see process()


def __init__(self, data, amount_clusters, epouch = <NUM_LIT:100>, ccore = True):

self.__data_pointer = data;<EOL>self.__amount_clusters = amount_clusters;<EOL>self.__epouch = epouch;<EOL>self.__ccore = ccore;<EOL>self.__network = None<EOL>

!
        @brief Creates SOM-SC (Self Organized Map for Simple Clustering) algorithm for clustering analysis.

        @param[in] data (list): List of points that are used for processing.
        @param[in] amount_clusters (uint): Amount of clusters that should be allocated.
        @param[in] epouch (uint): Number of epochs for training of SOM.
        @param[in] ccore (bool): If it is True then CCORE implementation will be used for clustering analysis.


cluster = None<EOL>self.__visited[index_point] = True<EOL>neighbors = self.__neighbor_searcher(index_point)<EOL>if len(neighbors) >= self.__neighbors:<EOL><INDENT>cluster = [index_point]<EOL>self.__belong[index_point] = True<EOL>for i in neighbors:<EOL><INDENT>if self.__visited[i] is False:<EOL><INDENT>self.__visited[i] = True<EOL>next_neighbors = self.__neighbor_searcher(i)<EOL>if len(next_neighbors) >= self.__neighbors:<EOL><INDENT>neighbors += [k for k in next_neighbors if ( (k in neighbors) == False) and k != index_point]<EOL><DEDENT><DEDENT>if self.__belong[i] is False:<EOL><INDENT>cluster.append(i)<EOL>self.__belong[i] = True<EOL><DEDENT><DEDENT><DEDENT>return cluster<EOL>

!
        @brief Expands cluster from specified point in the input data space.

        @param[in] index_point (list): Index of a point from the data.

        @return (list) Return tuple of list of indexes that belong to the same cluster and list of points that are marked as noise: (cluster, noise), or None if nothing has been expanded.


def __calculate_radius(self, number_neighbors, radius):

if (number_neighbors >= len(self._osc_loc)):<EOL><INDENT>return radius * self.__increase_persent + radius;<EOL><DEDENT>return average_neighbor_distance(self._osc_loc, number_neighbors)<EOL>

!
        @brief Calculate new connectivity radius.

        @param[in] number_neighbors (uint): Average amount of neighbors that should be connected by new radius.
        @param[in] radius (double): Current connectivity radius.

        @return New connectivity radius.


def process(self, order = <NUM_LIT>, solution = solve_type.FAST, collect_dynamic = False):

if (self.__ccore_network_pointer is not None):<EOL><INDENT>analyser = wrapper.hsyncnet_process(self.__ccore_network_pointer, order, solution, collect_dynamic);<EOL>return syncnet_analyser(None, None, analyser);<EOL><DEDENT>number_neighbors = self.__initial_neighbors;<EOL>current_number_clusters = float('<STR_LIT>');<EOL>dyn_phase = [];<EOL>dyn_time = [];<EOL>radius = average_neighbor_distance(self._osc_loc, number_neighbors);<EOL>increase_step = int(len(self._osc_loc) * self.__increase_persent);<EOL>if (increase_step < <NUM_LIT:1>):<EOL><INDENT>increase_step = <NUM_LIT:1>;<EOL><DEDENT>analyser = None;<EOL>while(current_number_clusters > self._number_clusters):<EOL><INDENT>self._create_connections(radius);<EOL>analyser = self.simulate_dynamic(order, solution, collect_dynamic);<EOL>if (collect_dynamic == True):<EOL><INDENT>if (len(dyn_phase) == <NUM_LIT:0>):<EOL><INDENT>self.__store_dynamic(dyn_phase, dyn_time, analyser, True);<EOL><DEDENT>self.__store_dynamic(dyn_phase, dyn_time, analyser, False);<EOL><DEDENT>clusters = analyser.allocate_sync_ensembles(<NUM_LIT>);<EOL>current_number_clusters = len(clusters);<EOL>number_neighbors += increase_step;<EOL>radius = self.__calculate_radius(number_neighbors, radius);<EOL><DEDENT>if (collect_dynamic != True):<EOL><INDENT>self.__store_dynamic(dyn_phase, dyn_time, analyser, False);<EOL><DEDENT>return syncnet_analyser(dyn_phase, dyn_time, None)<EOL>

!
        @brief Performs clustering of input data set in line with input parameters.

        @param[in] order (double): Level of local synchronization between oscillator that defines end of synchronization process, range [0..1].
        @param[in] solution (solve_type) Type of solving differential equation.
        @param[in] collect_dynamic (bool): If True - returns whole history of process synchronization otherwise - only final state (when process of clustering is over).

        @return (tuple) Returns dynamic of the network as tuple of lists on each iteration (time, oscillator_phases) that depends on collect_dynamic parameter.

        @see get_clusters()


dimension = self.__data.shape[<NUM_LIT:1>]<EOL>centers = numpy.zeros((len(self.__centers), dimension))<EOL>for i in range(len(self.__centers)):<EOL><INDENT>centers[i] = numpy.divide(self.__membership[:, i] @ self.__data, numpy.sum(self.__membership[:, i]))<EOL><DEDENT>return centers<EOL>

!
        @brief Calculate center using membership of each cluster.

        @return (list) Updated clusters as list of clusters. Each cluster contains indexes of objects from data.

        @return (numpy.array) Updated centers.


result = wrapper.fcm_algorithm(self.__data, self.__centers, self.__m, self.__tolerance, self.__itermax)<EOL>self.__clusters = result[wrapper.fcm_package_indexer.INDEX_CLUSTERS]<EOL>self.__centers = result[wrapper.fcm_package_indexer.INDEX_CENTERS]<EOL>self.__membership = result[wrapper.fcm_package_indexer.INDEX_MEMBERSHIP]<EOL>

!
        @brief Performs cluster analysis using C/C++ implementation.


return self.__membership<EOL>

!
        @brief Returns cluster membership (probability) for each point in data.

        @return (array_like) Membership for each point in format [[Px1(c1), Px1(c2), ...], [Px2(c1), Px2(c2), ...], ...],
                 where [Px1(c1), Px1(c2), ...] membership for point x1.

        @see process()
        @see get_clusters()
        @see get_centers()


changes = numpy.sum(numpy.square(self.__centers - updated_centers), axis=<NUM_LIT:1>).T<EOL>return numpy.max(changes)<EOL>

!
        @brief Calculate changes between centers.

        @return (float) Maximum change between centers.


return self.__clusters<EOL>

!
        @brief Returns allocated clusters that consists of points that most likely (in line with membership) belong to
                these clusters.

        @remark Allocated clusters can be returned only after data processing (use method process()). Otherwise empty list is returned.

        @return (list) List of allocated clusters, each cluster contains indexes from input data.

        @see process()
        @see get_centers()
        @see get_membership()


return self.__centers<EOL>

!
        @brief Returns list of centers of allocated clusters.

        @return (array_like) Cluster centers.

        @see process()
        @see get_clusters()
        @see get_membership()


def __init__(self, data, initial_centers, **kwargs):

self.__data = data<EOL>self.__clusters = []<EOL>self.__centers = initial_centers<EOL>self.__membership = []<EOL>self.__tolerance = kwargs.get('<STR_LIT>', <NUM_LIT>)<EOL>self.__itermax = kwargs.get('<STR_LIT>', <NUM_LIT:200>)<EOL>self.__m = kwargs.get('<STR_LIT:m>', <NUM_LIT:2>)<EOL>self.__degree = <NUM_LIT> / (self.__m - <NUM_LIT:1>)<EOL>self.__ccore = kwargs.get('<STR_LIT>', True)<EOL>if self.__ccore is True:<EOL><INDENT>self.__ccore = ccore_library.workable()<EOL><DEDENT>

!
        @brief Initialize Fuzzy C-Means algorithm.

        @param[in] data (array_like): Input data that is presented as array of points (objects), each point should be represented by array_like data structure.
        @param[in] initial_centers (array_like): Initial coordinates of centers of clusters that are represented by array_like data structure: [center1, center2, ...].
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'tolerance', 'itermax', 'm').

        Keyword Args:

            - ccore (bool): Defines should be CCORE library (C++ pyclustering library) used instead of Python code or not.
            - tolerance (float): Stop condition: if maximum value of change of centers of clusters is less than tolerance then algorithm stops processing.
            - itermax (uint): Maximum number of iterations that is used for clustering process (by default: 200).
            - m (float): Hyper-parameter that controls how fuzzy the cluster will be. The higher it is, the fuzzier the cluster will be in the end.
               This parameter should be greater than 1 (by default: 2).


def process(self, collect_dynamic = False, order = <NUM_LIT>):

<EOL>self._som.train(self._data, <NUM_LIT:100>);<EOL>weights = list();<EOL>self._som_osc_table.clear();        <EOL>for i in range(self._som.size):<EOL><INDENT>if (self._som.awards[i] > <NUM_LIT:0>):<EOL><INDENT>weights.append(self._som.weights[i]);<EOL>self._som_osc_table.append(i);<EOL><DEDENT><DEDENT>self._sync = self.__create_sync_layer(weights);<EOL>self._analyser = self._sync.process(order, collect_dynamic = collect_dynamic);<EOL>return (self._analyser.time, self._analyser.output)<EOL>

!
        @brief Performs simulation of the oscillatory network.

        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.
        @param[in] order (double): Order of process synchronization that should be considered as end of clustering, destributed 0..1.

        @return (tuple) 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 get_som_clusters()
        @see get_clusters()


return self._sync<EOL>

!
        @brief The second layer of the oscillatory network based on Kuramoto model.


return self._som<EOL>

!
        @brief The first layer of the oscillatory network - self-organized feature map.


def __has_object_connection(self, oscillator_index1, oscillator_index2):

som_neuron_index1 = self._som_osc_table[oscillator_index1];<EOL>som_neuron_index2 = self._som_osc_table[oscillator_index2];<EOL>for index_object1 in self._som.capture_objects[som_neuron_index1]:<EOL><INDENT>for index_object2 in self._som.capture_objects[som_neuron_index2]:<EOL><INDENT>distance = euclidean_distance_square(self._data[index_object1], self._data[index_object2]);<EOL>if (distance <= self._radius):<EOL><INDENT>return True;<EOL><DEDENT><DEDENT><DEDENT>return False<EOL>

!
        @brief Searches for pair of objects that are encoded by specified neurons and that are connected in line with connectivity radius.

        @param[in] oscillator_index1 (uint): Index of the first oscillator in the second layer.
        @param[in] oscillator_index2 (uint): Index of the second oscillator in the second layer.

        @return (bool) True - if there is pair of connected objects encoded by specified oscillators.


start_centers = [[-<NUM_LIT>, <NUM_LIT>], [<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_WING_NUT)<EOL>


start_centers = [[<NUM_LIT:1.0>, <NUM_LIT>], [<NUM_LIT>, <NUM_LIT:0.5>], [<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_LSUN)<EOL>


start_centers = [[<NUM_LIT:1.0>, <NUM_LIT>], [<NUM_LIT>, <NUM_LIT:0.5>], [<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_LSUN, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_LSUN, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)<EOL>


start_centers = [[<NUM_LIT>, <NUM_LIT>], [<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE2, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)<EOL>template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE2, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)<EOL>


start_centers = [[<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TWO_DIAMONDS, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TWO_DIAMONDS, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)<EOL>


start_centers = [[<NUM_LIT>, <NUM_LIT>], [<NUM_LIT:0.0>, -<NUM_LIT>], [<NUM_LIT>, -<NUM_LIT>], [<NUM_LIT>, <NUM_LIT>], [-<NUM_LIT>, <NUM_LIT>], [-<NUM_LIT>, -<NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TARGET, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TARGET, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)<EOL>


start_centers = [[<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>], [<NUM_LIT>, <NUM_LIT:0.0>, <NUM_LIT:0.0>], [-<NUM_LIT>, <NUM_LIT:0.0>, <NUM_LIT:0.0>], [<NUM_LIT:0.0>, <NUM_LIT>, <NUM_LIT:0.0>], [<NUM_LIT:0.0>, -<NUM_LIT>, <NUM_LIT:0.0>], [<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT>]]<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_HEPTA, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)<EOL>template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_HEPTA, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)<EOL>


template_clustering(<NUM_LIT:0.5>, <NUM_LIT:3>, FCPS_SAMPLES.SAMPLE_GOLF_BALL)<EOL>


template_clustering(<NUM_LIT>, <NUM_LIT:2>, FCPS_SAMPLES.SAMPLE_WING_NUT)<EOL>

It's hard to choose properly parameters, but it's OK


start_centers = [[<NUM_LIT:1.0>, <NUM_LIT>], [<NUM_LIT>, <NUM_LIT>]]<EOL>template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_ELONGATE)<EOL>


def __create_canvas(self, dimension, pairs, position, **kwargs):

visible_grid = kwargs.get('<STR_LIT>', True)<EOL>visible_labels = kwargs.get('<STR_LIT>', True)<EOL>visible_axis = kwargs.get('<STR_LIT>', False)<EOL>ax = self.__figure.add_subplot(self.__grid_spec[position])<EOL>if dimension > <NUM_LIT:1>:<EOL><INDENT>if visible_labels:<EOL><INDENT>ax.set_xlabel("<STR_LIT>" % pairs[position][<NUM_LIT:0>])<EOL>ax.set_ylabel("<STR_LIT>" % pairs[position][<NUM_LIT:1>])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ax.set_ylim(-<NUM_LIT:0.5>, <NUM_LIT:0.5>)<EOL>ax.set_yticklabels([])<EOL><DEDENT>if visible_grid:<EOL><INDENT>ax.grid(True)<EOL><DEDENT>if not visible_axis:<EOL><INDENT>ax.set_yticklabels([])<EOL>ax.set_xticklabels([])<EOL><DEDENT>return ax<EOL>

!
        @brief Create new canvas with user defined parameters to display cluster or chunk of cluster on it.

        @param[in] dimension (uint): Data-space dimension.
        @param[in] pairs (list): Pair of coordinates that will be displayed on the canvas. If empty than label will not
                    be displayed on the canvas.
        @param[in] position (uint): Index position of canvas on a grid.
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'visible_axis' 'visible_labels', 'visible_grid').

        Keyword Args:

            - visible_axis (bool): Defines visibility of axes on each canvas, if True - axes are visible.
               By default axis are not displayed.
            - visible_labels (bool): Defines visibility of labels on each canvas, if True - labels is displayed.
               By default labels are displayed.
            - visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
               By default grid is displayed.

        @return (matplotlib.Axis) Canvas to display cluster of chuck of cluster.


def append_cluster_attribute(self, index_canvas, index_cluster, data, marker = None, markersize = None):

cluster_descr = self.__canvas_clusters[index_canvas][index_cluster]<EOL>attribute_marker = marker<EOL>if attribute_marker is None:<EOL><INDENT>attribute_marker = cluster_descr.marker<EOL><DEDENT>attribure_markersize = markersize<EOL>if attribure_markersize is None:<EOL><INDENT>attribure_markersize = cluster_descr.markersize<EOL><DEDENT>attribute_color = cluster_descr.color<EOL>added_attribute_cluster_descriptor = canvas_cluster_descr(data, None, attribute_marker, attribure_markersize, attribute_color)<EOL>self.__canvas_clusters[index_canvas][index_cluster].attributes.append(added_attribute_cluster_descriptor)<EOL>

!
        @brief Append cluster attribure for cluster on specific canvas.
        @details Attribute it is data that is visualized for specific cluster using its color, marker and markersize if last two is not specified.

        @param[in] index_canvas (uint): Index canvas where cluster is located.
        @param[in] index_cluster (uint): Index cluster whose attribute should be added.
        @param[in] data (list): List of points (data) that represents attribute.
        @param[in] marker (string): Marker that is used for displaying objects from cluster on the canvas.
        @param[in] markersize (uint): Size of marker.


def show(self, figure=None, invisible_axis=True, visible_grid=True, display=True, shift=None):

canvas_shift = shift<EOL>if canvas_shift is None:<EOL><INDENT>if figure is not None:<EOL><INDENT>canvas_shift = len(figure.get_axes())<EOL><DEDENT>else:<EOL><INDENT>canvas_shift = <NUM_LIT:0><EOL><DEDENT><DEDENT>if figure is not None:<EOL><INDENT>cluster_figure = figure<EOL><DEDENT>else:<EOL><INDENT>cluster_figure = plt.figure()<EOL><DEDENT>maximum_cols = self.__size_row<EOL>maximum_rows = math.ceil( (self.__number_canvases + canvas_shift) / maximum_cols)<EOL>grid_spec = gridspec.GridSpec(maximum_rows, maximum_cols)<EOL>for index_canvas in range(len(self.__canvas_clusters)):<EOL><INDENT>canvas_data = self.__canvas_clusters[index_canvas]<EOL>if len(canvas_data) == <NUM_LIT:0>:<EOL><INDENT>continue<EOL><DEDENT>dimension = self.__canvas_dimensions[index_canvas]<EOL>if (dimension == <NUM_LIT:1>) or (dimension == <NUM_LIT:2>):<EOL><INDENT>ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift])<EOL><DEDENT>else:<EOL><INDENT>ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift], projection='<STR_LIT>')<EOL><DEDENT>if len(canvas_data) == <NUM_LIT:0>:<EOL><INDENT>plt.setp(ax, visible=False)<EOL><DEDENT>for cluster_descr in canvas_data:<EOL><INDENT>self.__draw_canvas_cluster(ax, dimension, cluster_descr)<EOL>for attribute_descr in cluster_descr.attributes:<EOL><INDENT>self.__draw_canvas_cluster(ax, dimension, attribute_descr)<EOL><DEDENT><DEDENT>if invisible_axis is True:<EOL><INDENT>ax.xaxis.set_ticklabels([])<EOL>ax.yaxis.set_ticklabels([])<EOL>if (dimension == <NUM_LIT:3>):<EOL><INDENT>ax.zaxis.set_ticklabels([])<EOL><DEDENT><DEDENT>if self.__canvas_titles[index_canvas] is not None:<EOL><INDENT>ax.set_title(self.__canvas_titles[index_canvas])<EOL><DEDENT>ax.grid(visible_grid)<EOL><DEDENT>if display is True:<EOL><INDENT>plt.show()<EOL><DEDENT>return cluster_figure<EOL>

!
        @brief Shows clusters (visualize).

        @param[in] figure (fig): Defines requirement to use specified figure, if None - new figure is created for drawing clusters.
        @param[in] invisible_axis (bool): Defines visibility of axes on each canvas, if True - axes are invisible.
        @param[in] visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
        @param[in] display (bool): Defines requirement to display clusters on a stage, if True - clusters are displayed,
                    if False - plt.show() should be called by user."
        @param[in] shift (uint): Force canvas shift value - defines canvas index from which custers should be visualized.

        @return (fig) Figure where clusters are shown.


def __draw_cluster_item_multi_dimension(self, ax, pair, item, cluster_descr):

index_dimension1 = pair[<NUM_LIT:0>]<EOL>index_dimension2 = pair[<NUM_LIT:1>]<EOL>if cluster_descr.data is None:<EOL><INDENT>ax.plot(item[index_dimension1], item[index_dimension2],<EOL>color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)<EOL><DEDENT>else:<EOL><INDENT>ax.plot(cluster_descr.data[item][index_dimension1], cluster_descr.data[item][index_dimension2],<EOL>color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)<EOL><DEDENT>

!
        @brief Draw cluster chunk defined by pair coordinates in data space with dimension greater than 1.

        @param[in] ax (axis): Matplotlib axis that is used to display chunk of cluster point.
        @param[in] pair (list): Coordinate of the point that should be displayed.
        @param[in] item (list): Data point or index of data point.
        @param[in] cluster_descr (canvas_cluster_descr): Cluster description whose point is visualized.


def set_canvas_title(self, text, canvas = <NUM_LIT:0>):

if canvas > self.__number_canvases:<EOL><INDENT>raise NameError('<STR_LIT>' + canvas + '<STR_LIT>')<EOL><DEDENT>self.__canvas_titles[canvas] = text<EOL>

!
        @brief Set title for specified canvas.

        @param[in] text (string): Title for canvas.
        @param[in] canvas (uint): Index of canvas where title should be displayed.


def __draw_cluster_item_one_dimension(self, ax, item, cluster_descr):

if cluster_descr.data is None:<EOL><INDENT>ax.plot(item[<NUM_LIT:0>], <NUM_LIT:0.0>,<EOL>color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)<EOL><DEDENT>else:<EOL><INDENT>ax.plot(cluster_descr.data[item][<NUM_LIT:0>], <NUM_LIT:0.0>,<EOL>color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)<EOL><DEDENT>

!
        @brief Draw cluster point in one dimensional data space..

        @param[in] ax (axis): Matplotlib axis that is used to display chunk of cluster point.
        @param[in] item (list): Data point or index of data point.
        @param[in] cluster_descr (canvas_cluster_descr): Cluster description whose point is visualized.


def append_cluster(self, cluster, data=None, canvas=<NUM_LIT:0>, marker='<STR_LIT:.>', markersize=None, color=None):

if len(cluster) == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>if canvas > self.__number_canvases or canvas < <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>" % self.__number_canvases or canvas)<EOL><DEDENT>if color is None:<EOL><INDENT>index_color = len(self.__canvas_clusters[canvas]) % len(color_list.TITLES)<EOL>color = color_list.TITLES[index_color]<EOL><DEDENT>added_canvas_descriptor = canvas_cluster_descr(cluster, data, marker, markersize, color)<EOL>self.__canvas_clusters[canvas].append( added_canvas_descriptor )<EOL>if data is None:<EOL><INDENT>dimension = len(cluster[<NUM_LIT:0>])<EOL>if self.__canvas_dimensions[canvas] is None:<EOL><INDENT>self.__canvas_dimensions[canvas] = dimension<EOL><DEDENT>elif self.__canvas_dimensions[canvas] != dimension:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>dimension = len(data[<NUM_LIT:0>])<EOL>if self.__canvas_dimensions[canvas] is None:<EOL><INDENT>self.__canvas_dimensions[canvas] = dimension<EOL><DEDENT>elif self.__canvas_dimensions[canvas] != dimension:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>if (dimension < <NUM_LIT:1>) or (dimension > <NUM_LIT:3>):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if markersize is None:<EOL><INDENT>if (dimension == <NUM_LIT:1>) or (dimension == <NUM_LIT:2>):<EOL><INDENT>added_canvas_descriptor.markersize = self.__default_2d_marker_size<EOL><DEDENT>elif dimension == <NUM_LIT:3>:<EOL><INDENT>added_canvas_descriptor.markersize = self.__default_3d_marker_size<EOL><DEDENT><DEDENT>return len(self.__canvas_clusters[canvas]) - <NUM_LIT:1><EOL>

!
        @brief Appends cluster to canvas for drawing.

        @param[in] cluster (list): cluster that may consist of indexes of objects from the data or object itself.
        @param[in] data (list): If defines that each element of cluster is considered as a index of object from the data.
        @param[in] canvas (uint): Number of canvas that should be used for displaying cluster.
        @param[in] marker (string): Marker that is used for displaying objects from cluster on the canvas.
        @param[in] markersize (uint): Size of marker.
        @param[in] color (string): Color of marker.

        @return Returns index of cluster descriptor on the canvas.


def show(self, pair_filter=None, **kwargs):

if not len(self.__clusters) > <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>cluster_data = self.__clusters[<NUM_LIT:0>].data or self.__clusters[<NUM_LIT:0>].cluster<EOL>dimension = len(cluster_data[<NUM_LIT:0>])<EOL>acceptable_pairs = pair_filter or []<EOL>pairs = []<EOL>amount_axis = <NUM_LIT:1><EOL>axis_storage = []<EOL>if dimension > <NUM_LIT:1>:<EOL><INDENT>pairs = self.__create_pairs(dimension, acceptable_pairs)<EOL>amount_axis = len(pairs)<EOL><DEDENT>self.__figure = plt.figure()<EOL>self.__grid_spec = self.__create_grid_spec(amount_axis, kwargs.get('<STR_LIT>', <NUM_LIT:4>))<EOL>for index in range(amount_axis):<EOL><INDENT>ax = self.__create_canvas(dimension, pairs, index, **kwargs)<EOL>axis_storage.append(ax)<EOL><DEDENT>for cluster_descr in self.__clusters:<EOL><INDENT>self.__draw_canvas_cluster(axis_storage, cluster_descr, pairs)<EOL><DEDENT>plt.show()<EOL>

!
        @brief Shows clusters (visualize) in multi-dimensional space.

        @param[in] pair_filter (list): List of coordinate pairs that should be displayed. This argument is used as a filter.
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'visible_axis' 'visible_labels', 'visible_grid', 'row_size').

        Keyword Args:

            - visible_axis (bool): Defines visibility of axes on each canvas, if True - axes are visible.
               By default axis of each canvas are not displayed.
            - visible_labels (bool): Defines visibility of labels on each canvas, if True - labels is displayed.
               By default labels of each canvas are displayed.
            - visible_grid (bool): Defines visibility of grid on each canvas, if True - grid is displayed.
               By default grid of each canvas is displayed.
            - max_row_size (uint): Maximum number of canvases on one row.


return self.__clusters<EOL>

!
        @brief Returns list of allocated clusters, each cluster contains indexes of objects in list of data.

        @remark Results of clustering can be obtained using corresponding gets methods.

        @return (list) List of allocated clusters, each cluster contains indexes of objects in list of data.

        @see process()


def __init__(self, data, number_clusters, link = None, ccore = True):

self.__pointer_data = data<EOL>self.__number_clusters = number_clusters<EOL>self.__similarity = link<EOL>if self.__similarity is None:<EOL><INDENT>self.__similarity = type_link.CENTROID_LINK<EOL><DEDENT>self.__clusters = []<EOL>self.__ccore = ccore<EOL>if (self.__ccore):<EOL><INDENT>self.__ccore = ccore_library.workable()<EOL><DEDENT>if (self.__similarity == type_link.CENTROID_LINK):<EOL><INDENT>self.__centers = self.__pointer_data.copy()<EOL><DEDENT>

!
        @brief Constructor of agglomerative hierarchical algorithm.

        @param[in] data (list): Input data that is presented as a list of points (objects), each point should be represented by list, for example
                    [[0.1, 0.2], [0.4, 0.5], [1.3, 0.9]].
        @param[in] number_clusters (uint): Number of clusters that should be allocated.
        @param[in] link (type_link): Link type that is used for calculation similarity between objects and clusters, if it is not specified centroid link will be used by default.
        @param[in] ccore (bool): Defines should be CCORE (C++ pyclustering library) used instead of Python code or not (by default it is 'False').


def __calculate_nearest_distance(self, index_cluster1, index_cluster2):

candidate_minimum_distance = float('<STR_LIT>');<EOL>for index_object1 in self.__clusters[index_cluster1]:<EOL><INDENT>for index_object2 in self.__clusters[index_cluster2]:<EOL><INDENT>distance = euclidean_distance_square(self.__pointer_data[index_object1], self.__pointer_data[index_object2]);<EOL>if (distance < candidate_minimum_distance):<EOL><INDENT>candidate_minimum_distance = distance;<EOL><DEDENT><DEDENT><DEDENT>return candidate_minimum_distance<EOL>

!
        @brief Finds two nearest objects in two specified clusters and returns distance between them.

        @param[in] (uint) Index of the first cluster.
        @param[in] (uint) Index of the second cluster.

        @return The nearest euclidean distance between two clusters.


minimum_average_distance = float('<STR_LIT>');<EOL>for index_cluster1 in range(<NUM_LIT:0>, len(self.__clusters)):<EOL><INDENT>for index_cluster2 in range(index_cluster1 + <NUM_LIT:1>, len(self.__clusters)):<EOL><INDENT>candidate_average_distance = <NUM_LIT:0.0>;<EOL>for index_object1 in self.__clusters[index_cluster1]:<EOL><INDENT>for index_object2 in self.__clusters[index_cluster2]:<EOL><INDENT>candidate_average_distance += euclidean_distance_square(self.__pointer_data[index_object1], self.__pointer_data[index_object2]);<EOL><DEDENT><DEDENT>candidate_average_distance /= (len(self.__clusters[index_cluster1]) + len(self.__clusters[index_cluster2]));<EOL>if (candidate_average_distance < minimum_average_distance):<EOL><INDENT>minimum_average_distance = candidate_average_distance;<EOL>indexes = [index_cluster1, index_cluster2];<EOL><DEDENT><DEDENT><DEDENT>self.__clusters[indexes[<NUM_LIT:0>]] += self.__clusters[indexes[<NUM_LIT:1>]];  <EOL>self.__clusters.pop(indexes[<NUM_LIT:1>])<EOL>

!
        @brief Merges the most similar clusters in line with average link type.


minimum_single_distance = float('<STR_LIT>');<EOL>indexes = None;<EOL>for index_cluster1 in range(<NUM_LIT:0>, len(self.__clusters)):<EOL><INDENT>for index_cluster2 in range(index_cluster1 + <NUM_LIT:1>, len(self.__clusters)):<EOL><INDENT>candidate_minimum_distance = self.__calculate_nearest_distance(index_cluster1, index_cluster2);<EOL>if (candidate_minimum_distance < minimum_single_distance):<EOL><INDENT>minimum_single_distance = candidate_minimum_distance;<EOL>indexes = [index_cluster1, index_cluster2];<EOL><DEDENT><DEDENT><DEDENT>self.__clusters[indexes[<NUM_LIT:0>]] += self.__clusters[indexes[<NUM_LIT:1>]];  <EOL>self.__clusters.pop(indexes[<NUM_LIT:1>])<EOL>

!
        @brief Merges the most similar clusters in line with single link type.


if self.__ccore is True:<EOL><INDENT>ccore_metric = metric_wrapper.create_instance(self.__metric)<EOL>self.__clusters, self.__medians = wrapper.kmedians(self.__pointer_data, self.__medians, self.__tolerance, self.__itermax, ccore_metric.get_pointer())<EOL><DEDENT>else:<EOL><INDENT>changes = float('<STR_LIT>')<EOL>if len(self.__pointer_data[<NUM_LIT:0>]) != len(self.__medians[<NUM_LIT:0>]):<EOL><INDENT>raise NameError('<STR_LIT>')<EOL><DEDENT>iterations = <NUM_LIT:0><EOL>while changes > self.__tolerance and iterations < self.__itermax:<EOL><INDENT>self.__clusters = self.__update_clusters()<EOL>updated_centers = self.__update_medians()<EOL>changes = max([self.__metric(self.__medians[index], updated_centers[index]) for index in range(len(updated_centers))])<EOL>self.__medians = updated_centers<EOL>iterations += <NUM_LIT:1><EOL><DEDENT><DEDENT>return self<EOL>

!
        @brief Performs cluster analysis in line with rules of K-Medians algorithm.

        @return (kmedians) Returns itself (K-Medians instance).

        @remark Results of clustering can be obtained using corresponding get methods.

        @see get_clusters()
        @see get_medians()


return self.__medians<EOL>

!
        @brief Returns list of centers of allocated clusters.

        @see process()
        @see get_clusters()


medians = [[] for i in range(len(self.__clusters))]<EOL>for index in range(len(self.__clusters)):<EOL><INDENT>medians[index] = [<NUM_LIT:0.0> for i in range(len(self.__pointer_data[<NUM_LIT:0>]))]<EOL>length_cluster = len(self.__clusters[index])<EOL>for index_dimension in range(len(self.__pointer_data[<NUM_LIT:0>])):<EOL><INDENT>sorted_cluster = sorted(self.__clusters[index], key=lambda x: self.__pointer_data[x][index_dimension])<EOL>relative_index_median = int(math.floor((length_cluster - <NUM_LIT:1>) / <NUM_LIT:2>))<EOL>index_median = sorted_cluster[relative_index_median]<EOL>if (length_cluster % <NUM_LIT:2>) == <NUM_LIT:0>:<EOL><INDENT>index_median_second = sorted_cluster[relative_index_median + <NUM_LIT:1>]<EOL>medians[index][index_dimension] = (self.__pointer_data[index_median][index_dimension] + self.__pointer_data[index_median_second][index_dimension]) / <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>medians[index][index_dimension] = self.__pointer_data[index_median][index_dimension]<EOL><DEDENT><DEDENT><DEDENT>return medians<EOL>

!
        @brief Calculate medians of clusters in line with contained objects.

        @return (list) list of medians for current number of clusters.


def __init__(self, data, initial_centers, tolerance=<NUM_LIT>, ccore=True, **kwargs):

self.__pointer_data = data<EOL>self.__clusters = []<EOL>self.__medians = initial_centers[:]<EOL>self.__tolerance = tolerance<EOL>self.__itermax = kwargs.get('<STR_LIT>', <NUM_LIT:100>)<EOL>self.__metric = kwargs.get('<STR_LIT>', distance_metric(type_metric.EUCLIDEAN_SQUARE))<EOL>if self.__metric is None:<EOL><INDENT>self.__metric = distance_metric(type_metric.EUCLIDEAN_SQUARE)<EOL><DEDENT>self.__ccore = ccore and self.__metric.get_type() != type_metric.USER_DEFINED<EOL>if self.__ccore:<EOL><INDENT>self.__ccore = ccore_library.workable()<EOL><DEDENT>

!
        @brief Constructor of clustering algorithm K-Medians.

        @param[in] data (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple.
        @param[in] initial_centers (list): Initial coordinates of medians of clusters that are represented by list: [center1, center2, ...].
        @param[in] tolerance (double): Stop condition: if maximum value of change of centers of clusters is less than tolerance than algorithm will stop processing
        @param[in] ccore (bool): Defines should be CCORE library (C++ pyclustering library) used instead of Python code or not.
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'metric', 'itermax').

        Keyword Args:

            - metric (distance_metric): Metric that is used for distance calculation between two points.
            - itermax (uint): Maximum number of iterations for cluster analysis.