Instruction:
Can you create a Python 3 function that
rebuilds the tree with encoded points till specified point from input data space.

Response:
def __rebuild_tree(self, index_point):
        """!
        @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.

        """

        rebuild_result = False;
        increased_diameter = self.__tree.threshold * self.__diameter_multiplier;

        tree = None;

        while(rebuild_result is False):
            # increase diameter and rebuild tree
            if (increased_diameter == 0.0):
                increased_diameter = 1.0;

            # build tree with update parameters
            tree = cftree(self.__tree.branch_factor, self.__tree.max_entries, increased_diameter, self.__tree.type_measurement);

            for index_point in range(0, index_point + 1):
                point = self.__pointer_data[index_point];
                tree.insert_cluster([point]);

                if (tree.amount_entries > self.__entry_size_limit):
                    increased_diameter *= self.__diameter_multiplier;
                    continue;

            # Re-build is successful.
            rebuild_result = True;

        return tree;


Instruction:
Given the following Python 3 function, write the documentation
def __find_nearest_cluster_features(self):

        minimum_distance = float("Inf");
        index1 = 0;
        index2 = 0;

        for index_candidate1 in range(0, len(self.__features)):
            feature1 = self.__features[index_candidate1];
            for index_candidate2 in range(index_candidate1 + 1, len(self.__features)):
                feature2 = self.__features[index_candidate2];

                distance = feature1.get_distance(feature2, self.__measurement_type);
                if (distance < minimum_distance):
                    minimum_distance = distance;

                    index1 = index_candidate1;
                    index2 = index_candidate2;

        return [index1, index2];

Response: Find pair of nearest CF entries.


Instruction:
How would you explain what the following Python 3 function does
def __get_nearest_feature(self, point, feature_collection):

        minimum_distance = float("Inf");
        index_nearest_feature = -1;

        for index_entry in range(0, len(feature_collection)):
            point_entry = cfentry(1, linear_sum([ point ]), square_sum([ point ]));

            distance = feature_collection[index_entry].get_distance(point_entry, self.__measurement_type);
            if (distance < minimum_distance):
                minimum_distance = distance;
                index_nearest_feature = index_entry;

        return (minimum_distance, index_nearest_feature);

Response: Returns the nearest feature for the specified point.


Instruction:
Make a summary of the following Python 3 code
def __read_answer_from_line(self, index_point, line):

        if line[0] == 'n':
            self.__noise.append(index_point)
        else:
            index_cluster = int(line)
            if index_cluster >= len(self.__clusters):
                self.__clusters.append([index_point])
            else:
                self.__clusters[index_cluster].append(index_point)

Response: Read information about point from a specific line and place it to the appropriate cluster or noise list.


Instruction:
Can you generate the documentation for the following Python 3 function
def __read_answer(self):

        if self.__clusters is not None:
            return

        file = open(self.__answer_path, 'r')

        self.__clusters, self.__noise = [], []

        index_point = 0
        for line in file:
            self.__read_answer_from_line(index_point, line)
            index_point += 1

        file.close()

Response: Read information about proper clusters and noises from the file.


Instruction:
Can you tell what is the following Python 3 function doing
def append_cluster(self, cluster, data = None, marker = '.', markersize = None, color = None):
        if len(cluster) == 0:
            raise ValueError("Empty cluster is provided.")

        markersize = markersize or 5
        if color is None:
            index_color = len(self.__clusters) % len(color_list.TITLES)
            color = color_list.TITLES[index_color]

        cluster_descriptor = canvas_cluster_descr(cluster, data, marker, markersize, color)
        self.__clusters.append(cluster_descriptor)

Response: Append a cluster to the list of clusters.


Instruction:
How would you explain what the following Python 3 function does
def append_clusters(self, clusters, data=None, marker='.', markersize=None):

        for cluster in clusters:
            self.append_cluster(cluster, data, marker, markersize)

Response: Append a list of clusters to the end of the list.


Instruction:
How would you explain what the following Python 3 function does
def show(self, pair_filter=None, **kwargs):

        if not len(self.__clusters) > 0:
            raise ValueError("There is no non-empty clusters for visualization.")

        cluster_data = self.__clusters[0].data or self.__clusters[0].cluster
        dimension = len(cluster_data[0])

        acceptable_pairs = pair_filter or []
        pairs = []
        amount_axis = 1
        axis_storage = []

        if dimension > 1:
            pairs = self.__create_pairs(dimension, acceptable_pairs)
            amount_axis = len(pairs)

        self.__figure = plt.figure()
        self.__grid_spec = self.__create_grid_spec(amount_axis, kwargs.get('max_row_size', 4))

        for index in range(amount_axis):
            ax = self.__create_canvas(dimension, pairs, index, **kwargs)
            axis_storage.append(ax)

        for cluster_descr in self.__clusters:
            self.__draw_canvas_cluster(axis_storage, cluster_descr, pairs)

        plt.show()

Response: Displays clusters in multi - dimensional space.


Instruction:
How would you explain what the following Python 3 function does
def __create_grid_spec(self, amount_axis, max_row_size):
        row_size = amount_axis
        if row_size > max_row_size:
            row_size = max_row_size

        col_size = math.ceil(amount_axis / row_size)
        return gridspec.GridSpec(col_size, row_size)

Response: Create a grid specification for the given amount of canvases on a given axis.


Instruction:
Explain what the following Python 3 code does
def __create_pairs(self, dimension, acceptable_pairs):
        if len(acceptable_pairs) > 0:
            return acceptable_pairs

        return list(itertools.combinations(range(dimension), 2))

Response: Create coordinate pairs that should be displayed.


Instruction:
Given the following Python 3 function, write the documentation
def __create_canvas(self, dimension, pairs, position, **kwargs):
        visible_grid = kwargs.get('visible_grid', True)
        visible_labels = kwargs.get('visible_labels', True)
        visible_axis = kwargs.get('visible_axis', False)

        ax = self.__figure.add_subplot(self.__grid_spec[position])

        if dimension > 1:
            if visible_labels:
                ax.set_xlabel("x%d" % pairs[position][0])
                ax.set_ylabel("x%d" % pairs[position][1])
        else:
            ax.set_ylim(-0.5, 0.5)
            ax.set_yticklabels([])

        if visible_grid:
            ax.grid(True)

        if not visible_axis:
            ax.set_yticklabels([])
            ax.set_xticklabels([])

        return ax

Response: Create a new canvas with user defined parameters to display cluster or chunk of cluster on it.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def __draw_canvas_cluster(self, axis_storage, cluster_descr, pairs):

        for index_axis in range(len(axis_storage)):
            for item in cluster_descr.cluster:
                if len(pairs) > 0:
                    self.__draw_cluster_item_multi_dimension(axis_storage[index_axis], pairs[index_axis], item, cluster_descr)
                else:
                    self.__draw_cluster_item_one_dimension(axis_storage[index_axis], item, cluster_descr)

Response: Draw a single or multiple cluster in a canvas.


Instruction:
Create a Python 3 function for
drawing a single cluster chunk defined by pair coordinates in data space with dimension greater than 1.

Response:
def __draw_cluster_item_multi_dimension(self, ax, pair, item, cluster_descr):
        """!
        @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.

        """

        index_dimension1 = pair[0]
        index_dimension2 = pair[1]

        if cluster_descr.data is None:
            ax.plot(item[index_dimension1], item[index_dimension2],
                    color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
        else:
            ax.plot(cluster_descr.data[item][index_dimension1], cluster_descr.data[item][index_dimension2],
                    color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)


Instruction:
Can you generate the documentation for the following Python 3 function
def __draw_cluster_item_one_dimension(self, ax, item, cluster_descr):

        if cluster_descr.data is None:
            ax.plot(item[0], 0.0,
                    color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)
        else:
            ax.plot(cluster_descr.data[item][0], 0.0,
                    color=cluster_descr.color, marker=cluster_descr.marker, markersize=cluster_descr.markersize)

Response: Draws one dimensional cluster point in one dimensional data space.


Instruction:
Can you write a function in Python 3 where it
adds a new cluster to the canvas for drawing.

Response:
def append_cluster(self, cluster, data=None, canvas=0, marker='.', markersize=None, color=None):
        """!
        @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.

        """

        if len(cluster) == 0:
            return

        if canvas > self.__number_canvases or canvas < 0:
            raise ValueError("Canvas index '%d' is out of range [0; %d]." % self.__number_canvases or canvas)

        if color is None:
            index_color = len(self.__canvas_clusters[canvas]) % len(color_list.TITLES)
            color = color_list.TITLES[index_color]

        added_canvas_descriptor = canvas_cluster_descr(cluster, data, marker, markersize, color)
        self.__canvas_clusters[canvas].append( added_canvas_descriptor )

        if data is None:
            dimension = len(cluster[0])
            if self.__canvas_dimensions[canvas] is None:
                self.__canvas_dimensions[canvas] = dimension
            elif self.__canvas_dimensions[canvas] != dimension:
                raise ValueError("Only clusters with the same dimension of objects can be displayed on canvas.")

        else:
            dimension = len(data[0])
            if self.__canvas_dimensions[canvas] is None:
                self.__canvas_dimensions[canvas] = dimension
            elif self.__canvas_dimensions[canvas] != dimension:
                raise ValueError("Only clusters with the same dimension of objects can be displayed on canvas.")

        if (dimension < 1) or (dimension > 3):
            raise ValueError("Only objects with size dimension 1 (1D plot), 2 (2D plot) or 3 (3D plot) "
                             "can be displayed. For multi-dimensional data use 'cluster_visualizer_multidim'.")

        if markersize is None:
            if (dimension == 1) or (dimension == 2):
                added_canvas_descriptor.markersize = self.__default_2d_marker_size
            elif dimension == 3:
                added_canvas_descriptor.markersize = self.__default_3d_marker_size

        return len(self.__canvas_clusters[canvas]) - 1


Instruction:
Explain what the following Python 3 code does
def append_cluster_attribute(self, index_canvas, index_cluster, data, marker = None, markersize = None):

        cluster_descr = self.__canvas_clusters[index_canvas][index_cluster]
        attribute_marker = marker
        if attribute_marker is None:
            attribute_marker = cluster_descr.marker

        attribure_markersize = markersize
        if attribure_markersize is None:
            attribure_markersize = cluster_descr.markersize

        attribute_color = cluster_descr.color

        added_attribute_cluster_descriptor = canvas_cluster_descr(data, None, attribute_marker, attribure_markersize, attribute_color)
        self.__canvas_clusters[index_canvas][index_cluster].attributes.append(added_attribute_cluster_descriptor)

Response: Append a cluster attribute to the list of attributes that are visualized for specific cluster on specific canvas.


Instruction:
Here you have a function in Python 3, explain what it does
def set_canvas_title(self, text, canvas = 0):

        if canvas > self.__number_canvases:
            raise NameError('Canvas does ' + canvas + ' not exists.')

        self.__canvas_titles[canvas] = text

Response: Set the title for the specified canvas.


Instruction:
Write a Python 3 function for
displaying the custers in a figure.

Response:
def show(self, figure=None, invisible_axis=True, visible_grid=True, display=True, shift=None):
        """!
        @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.

        """

        canvas_shift = shift
        if canvas_shift is None:
            if figure is not None:
                canvas_shift = len(figure.get_axes())
            else:
                canvas_shift = 0

        if figure is not None:
            cluster_figure = figure
        else:
            cluster_figure = plt.figure()

        maximum_cols = self.__size_row
        maximum_rows = math.ceil( (self.__number_canvases + canvas_shift) / maximum_cols)

        grid_spec = gridspec.GridSpec(maximum_rows, maximum_cols)

        for index_canvas in range(len(self.__canvas_clusters)):
            canvas_data = self.__canvas_clusters[index_canvas]
            if len(canvas_data) == 0:
                continue

            dimension = self.__canvas_dimensions[index_canvas]

            #ax = axes[real_index];
            if (dimension == 1) or (dimension == 2):
                ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift])
            else:
                ax = cluster_figure.add_subplot(grid_spec[index_canvas + canvas_shift], projection='3d')

            if len(canvas_data) == 0:
                plt.setp(ax, visible=False)

            for cluster_descr in canvas_data:
                self.__draw_canvas_cluster(ax, dimension, cluster_descr)

                for attribute_descr in cluster_descr.attributes:
                    self.__draw_canvas_cluster(ax, dimension, attribute_descr)

            if invisible_axis is True:
                ax.xaxis.set_ticklabels([])
                ax.yaxis.set_ticklabels([])

                if (dimension == 3):
                    ax.zaxis.set_ticklabels([])

            if self.__canvas_titles[index_canvas] is not None:
                ax.set_title(self.__canvas_titles[index_canvas])

            ax.grid(visible_grid)

        if display is True:
            plt.show()

        return cluster_figure


Instruction:
Explain what the following Python 3 code does
def __draw_canvas_cluster(self, ax, dimension, cluster_descr):

        cluster = cluster_descr.cluster
        data = cluster_descr.data
        marker = cluster_descr.marker
        markersize = cluster_descr.markersize
        color = cluster_descr.color

        for item in cluster:
            if dimension == 1:
                if data is None:
                    ax.plot(item[0], 0.0, color = color, marker = marker, markersize = markersize)
                else:
                    ax.plot(data[item][0], 0.0, color = color, marker = marker, markersize = markersize)

            elif dimension == 2:
                if data is None:
                    ax.plot(item[0], item[1], color = color, marker = marker, markersize = markersize)
                else:
                    ax.plot(data[item][0], data[item][1], color = color, marker = marker, markersize = markersize)

            elif dimension == 3:
                if data is None:
                    ax.scatter(item[0], item[1], item[2], c = color, marker = marker, s = markersize)
                else:
                    ax.scatter(data[item][0], data[item][1], data[item][2], c = color, marker = marker, s = markersize)

Response: Draws the specified canvas cluster descriptor.


Instruction:
Can you generate the documentation for the following Python 3 function
def gaussian(data, mean, covariance):
    dimension = float(len(data[0]))

    if dimension != 1.0:
        inv_variance = numpy.linalg.pinv(covariance)
    else:
        inv_variance = 1.0 / covariance

    divider = (pi * 2.0) ** (dimension / 2.0) * numpy.sqrt(numpy.linalg.norm(covariance))
    if divider != 0.0:
        right_const = 1.0 / divider
    else:
        right_const = float('inf')

    result = []

    for point in data:
        mean_delta = point - mean
        point_gaussian = right_const * numpy.exp( -0.5 * mean_delta.dot(inv_variance).dot(numpy.transpose(mean_delta)) )
        result.append(point_gaussian)

    return result

Response: Calculates the gaussian function for each point in data using the specified mean and variance or covariance matrix in case of multi - dimensional data.


Instruction:
Create a Python 3 function for
initializing the parameters for the EM algorithm.

Response:
def initialize(self, init_type = ema_init_type.KMEANS_INITIALIZATION):
        """!
        @brief Calculates initial parameters for EM algorithm: means and covariances using
                specified strategy.

        @param[in] init_type (ema_init_type): Strategy for initialization.

        @return (float|list, float|numpy.array) Initial means and variance (covariance matrix in case multi-dimensional data).

        """
        if init_type == ema_init_type.KMEANS_INITIALIZATION:
            return self.__initialize_kmeans()

        elif init_type == ema_init_type.RANDOM_INITIALIZATION:
            return self.__initialize_random()

        raise NameError("Unknown type of EM algorithm initialization is specified.")


Instruction:
Here you have a function in Python 3, explain what it does
def __calculate_initial_clusters(self, centers):

        clusters = [[] for _ in range(len(centers))]
        for index_point in range(len(self.__sample)):
            index_optim, dist_optim = -1, 0.0

            for index in range(len(centers)):
                dist = euclidean_distance_square(self.__sample[index_point], centers[index])

                if (dist < dist_optim) or (index is 0):
                    index_optim, dist_optim = index, dist

            clusters[index_optim].append(index_point)

        return clusters

Response: Calculates the Euclidean distance to each point from each cluster and returns a list of clusters.


Instruction:
Given the following Python 3 function, write the documentation
def notify(self, means, covariances, clusters):
        self.__means_evolution.append(means)
        self.__covariances_evolution.append(covariances)
        self.__clusters_evolution.append(clusters)

Response: This method is used by the algorithm to notify observer about changes where the algorithm should provide new values.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def show_clusters(clusters, sample, covariances, means, figure = None, display = True):

        visualizer = cluster_visualizer()
        visualizer.append_clusters(clusters, sample)

        if figure is None:
            figure = visualizer.show(display = False)
        else:
            visualizer.show(figure = figure, display = False)

        if len(sample[0]) == 2:
            ema_visualizer.__draw_ellipses(figure, visualizer, clusters, covariances, means)

        if display is True:
            plt.show()

        return figure

Response: Displays clusters in case of two - dimensional dataset draws their ellipses.


Instruction:
How would you explain what the following Python 3 function does
def animate_cluster_allocation(data, observer, animation_velocity = 75, movie_fps = 1, save_movie = None):

        figure = plt.figure()

        def init_frame():
            return frame_generation(0)

        def frame_generation(index_iteration):
            figure.clf()

            figure.suptitle("EM algorithm (iteration: " + str(index_iteration) +")", fontsize = 18, fontweight = 'bold')

            clusters = observer.get_evolution_clusters()[index_iteration]
            covariances = observer.get_evolution_covariances()[index_iteration]
            means = observer.get_evolution_means()[index_iteration]

            ema_visualizer.show_clusters(clusters, data, covariances, means, figure, False)
            figure.subplots_adjust(top = 0.85)

            return [ figure.gca() ]

        iterations = len(observer)
        cluster_animation = animation.FuncAnimation(figure, frame_generation, iterations, interval = animation_velocity, init_func = init_frame, repeat_delay = 5000)

        if save_movie is not None:
            cluster_animation.save(save_movie, writer = 'ffmpeg', fps = movie_fps, bitrate = 1500)
        else:
            plt.show()

Response: Animate the cluster allocation of the EM algorithm.


Instruction:
Create a Python 3 function to
calculate the Euclidean distance between two arrays using numpy.

Response:
def euclidean_distance_numpy(object1, object2):
    """!
    @brief Calculate Euclidean distance between two objects using numpy.

    @param[in] object1 (array_like): The first array_like object.
    @param[in] object2 (array_like): The second array_like object.

    @return (double) Euclidean distance between two objects.

    """
    return numpy.sum(numpy.sqrt(numpy.square(object1 - object2)), axis=1).T


Instruction:
How would you implement a function in Python 3 that
calculates the Euclidean distance between two vectors.

Response:
def euclidean_distance_square(point1, point2):
    """!
    @brief Calculate square Euclidean distance between two vectors.

    \f[
    dist(a, b) = \sum_{i=0}^{N}(a_{i} - b_{i})^{2};
    \f]

    @param[in] point1 (array_like): The first vector.
    @param[in] point2 (array_like): The second vector.

    @return (double) Square Euclidean distance between two vectors.

    @see euclidean_distance, manhattan_distance, chebyshev_distance

    """
    distance = 0.0
    for i in range(len(point1)):
        distance += (point1[i] - point2[i]) ** 2.0

    return distance


Instruction:
Write a Python 3 script to
calculate the square Euclidean distance between two arrays using numpy.

Response:
def euclidean_distance_square_numpy(object1, object2):
    """!
    @brief Calculate square Euclidean distance between two objects using numpy.

    @param[in] object1 (array_like): The first array_like object.
    @param[in] object2 (array_like): The second array_like object.

    @return (double) Square Euclidean distance between two objects.

    """
    return numpy.sum(numpy.square(object1 - object2), axis=1).T


Instruction:
Explain what the following Python 3 code does
def manhattan_distance(point1, point2):
    distance = 0.0
    dimension = len(point1)

    for i in range(dimension):
        distance += abs(point1[i] - point2[i])

    return distance

Response: Calculates the Manhattan distance between two vectors.


Instruction:
How would you code a function in Python 3 to
calculate the Manhattan distance between two arrays using numpy.

Response:
def manhattan_distance_numpy(object1, object2):
    """!
    @brief Calculate Manhattan distance between two objects using numpy.

    @param[in] object1 (array_like): The first array_like object.
    @param[in] object2 (array_like): The second array_like object.

    @return (double) Manhattan distance between two objects.

    """
    return numpy.sum(numpy.absolute(object1 - object2), axis=1).T


Instruction:
Create a Python 3 function to
calculate the Chebyshev distance between two vectors.

Response:
def chebyshev_distance(point1, point2):
    """!
    @brief Calculate Chebyshev distance between between two vectors.

    \f[
    dist(a, b) = \max_{}i\left (\left | a_{i} - b_{i} \right |\right );
    \f]

    @param[in] point1 (array_like): The first vector.
    @param[in] point2 (array_like): The second vector.

    @return (double) Chebyshev distance between two vectors.

    @see euclidean_distance_square, euclidean_distance, minkowski_distance

    """
    distance = 0.0
    dimension = len(point1)

    for i in range(dimension):
        distance = max(distance, abs(point1[i] - point2[i]))

    return distance


Instruction:
Can you tell what is the following Python 3 function doing
def chebyshev_distance_numpy(object1, object2):
    return numpy.max(numpy.absolute(object1 - object2), axis=1).T

Response: Calculates the Chebyshev distance between two arrays using numpy.


Instruction:
How would you explain what the following Python 3 function does
def minkowski_distance(point1, point2, degree=2):
    distance = 0.0
    for i in range(len(point1)):
        distance += (point1[i] - point2[i]) ** degree

    return distance ** (1.0 / degree)

Response: Calculates the Minkowski distance between two points.


Instruction:
Can you implement a function in Python 3 that
calculates the Minkowski distance between two arrays using numpy.

Response:
def minkowski_distance_numpy(object1, object2, degree=2):
    """!
    @brief Calculate Minkowski distance between objects using numpy.

    @param[in] object1 (array_like): The first array_like object.
    @param[in] object2 (array_like): The second array_like object.
    @param[in] degree (numeric): Degree of that is used for Minkowski distance.

    @return (double) Minkowski distance between two object.

    """
    return numpy.sum(numpy.power(numpy.power(object1 - object2, degree), 1/degree), axis=1).T


Instruction:
Create a Python 3 function to
calculate the Canberra distance between two objects using numpy.

Response:
def canberra_distance_numpy(object1, object2):
    """!
    @brief Calculate Canberra distance between two objects using numpy.

    @param[in] object1 (array_like): The first vector.
    @param[in] object2 (array_like): The second vector.

    @return (float) Canberra distance between two objects.

    """
    with numpy.errstate(divide='ignore', invalid='ignore'):
        result = numpy.divide(numpy.abs(object1 - object2), numpy.abs(object1) + numpy.abs(object2))

    if len(result.shape) > 1:
        return numpy.sum(numpy.nan_to_num(result), axis=1).T
    else:
        return numpy.sum(numpy.nan_to_num(result))


Instruction:
Can you implement a function in Python 3 that
calculates the Chi square distance between two vectors.

Response:
def chi_square_distance(point1, point2):
    """!
    @brief Calculate Chi square distance between two vectors.

    \f[
    dist(a, b) = \sum_{i=0}^{N}\frac{\left ( a_{i} - b_{i} \right )^{2}}{\left | a_{i} \right | + \left | b_{i} \right |};
    \f]

    @param[in] point1 (array_like): The first vector.
    @param[in] point2 (array_like): The second vector.

    @return (float) Chi square distance between two objects.

    """
    distance = 0.0
    for i in range(len(point1)):
        divider = abs(point1[i]) + abs(point2[i])
        if divider == 0.0:
            continue

        distance += ((point1[i] - point2[i]) ** 2.0) / divider

    return distance


Instruction:
How would you implement a function in Python 3 that
enables numpy usage for the current time - domain entry.

Response:
def enable_numpy_usage(self):
        """!
        @brief Start numpy for distance calculation.
        @details Useful in case matrices to increase performance. No effect in case of type_metric.USER_DEFINED type.

        """
        self.__numpy = True
        if self.__type != type_metric.USER_DEFINED:
            self.__calculator = self.__create_distance_calculator()


Instruction:
Make a summary of the following Python 3 code
def __create_distance_calculator_numpy(self):
        if self.__type == type_metric.EUCLIDEAN:
            return euclidean_distance_numpy

        elif self.__type == type_metric.EUCLIDEAN_SQUARE:
            return euclidean_distance_square_numpy

        elif self.__type == type_metric.MANHATTAN:
            return manhattan_distance_numpy

        elif self.__type == type_metric.CHEBYSHEV:
            return chebyshev_distance_numpy

        elif self.__type == type_metric.MINKOWSKI:
            return lambda object1, object2: minkowski_distance_numpy(object1, object2, self.__args.get('degree', 2))

        elif self.__type == type_metric.CANBERRA:
            return canberra_distance_numpy

        elif self.__type == type_metric.CHI_SQUARE:
            return chi_square_distance_numpy

        elif self.__type == type_metric.USER_DEFINED:
            return self.__func

        else:
            raise ValueError("Unknown type of metric: '%d'", self.__type)

Response: Creates a function that returns the distance metric calculator that uses numpy.


Instruction:
How would you implement a function in Python 3 that
returns the number of oscillations in the specified time series.

Response:
def extract_number_oscillations(self, index, amplitude_threshold):
        """!
        @brief Extracts number of oscillations of specified oscillator.

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

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

        """

        return pyclustering.utils.extract_number_oscillations(self.__amplitude, index, amplitude_threshold);


Instruction:
Here you have a function in Python 3, explain what it does
def show_output_dynamic(fsync_output_dynamic):

        pyclustering.utils.draw_dynamics(fsync_output_dynamic.time, fsync_output_dynamic.output, x_title = "t", y_title = "amplitude");

Response: Show the dynamic output of each oscillator during simulation.


Instruction:
Write a Python 3 function for
simulating the dynamic of the object.

Response:
def simulate(self, steps, time, collect_dynamic = False):
        """!
        @brief Performs static simulation of oscillatory network.

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

        @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' is True, than return dynamic for the whole simulation time,
                 otherwise returns only last values (last step of simulation) of output dynamic.

        @see simulate()
        @see simulate_dynamic()

        """

        dynamic_amplitude, dynamic_time = ([], []) if collect_dynamic is False else ([self.__amplitude], [0]);

        step = time / steps;
        int_step = step / 10.0;

        for t in numpy.arange(step, time + step, step):
            self.__amplitude = self.__calculate(t, step, int_step);

            if collect_dynamic is True:
                dynamic_amplitude.append([ numpy.real(amplitude)[0] for amplitude in self.__amplitude ]);
                dynamic_time.append(t);

        if collect_dynamic is False:
            dynamic_amplitude.append([ numpy.real(amplitude)[0] for amplitude in self.__amplitude ]);
            dynamic_time.append(time);

        output_sync_dynamic = fsync_dynamic(dynamic_amplitude, dynamic_time);
        return output_sync_dynamic;


Instruction:
Write a Python 3 script to
calculate the new amplitudes for the given time step and returns a list of new states.

Response:
def __calculate(self, t, step, int_step):
        """!
        @brief Calculates new amplitudes for oscillators in the network in line with current step.

        @param[in] t (double): Time of simulation.
        @param[in] step (double): Step of solution at the end of which states of oscillators should be calculated.
        @param[in] int_step (double): Step differentiation that is used for solving differential equation.

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

        """

        next_amplitudes = [0.0] * self._num_osc;

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

        return next_amplitudes;


Instruction:
Create a Python 3 function to
calculate the constant oscillator property that is based on frequency and radius.

Response:
def __oscillator_property(self, index):
        """!
        @brief Calculate Landau-Stuart oscillator constant property that is based on frequency and radius.

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

        @return (double) Oscillator property.

        """

        return numpy.array(1j * self.__frequency[index] + self.__radius[index]**2, dtype = numpy.complex128, ndmin = 1);


Instruction:
How would you implement a function in Python 3 that
calculates the Landau - Stuart state of the specified oscillator.

Response:
def __landau_stuart(self, amplitude, index):
        """!
        @brief Calculate Landau-Stuart state.

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

        @return (double) Landau-Stuart state.

        """

        return (self.__properties[index] - numpy.absolute(amplitude) ** 2) * amplitude;


Instruction:
Explain what the following Python 3 code does
def __synchronization_mechanism(self, amplitude, index):

        sync_influence = 0.0;

        for k in range(self._num_osc):
            if self.has_connection(index, k) is True:
                amplitude_neighbor = numpy.array(self.__amplitude[k], dtype = numpy.complex128, ndmin = 1);
                sync_influence += amplitude_neighbor - amplitude;

        return sync_influence * self.__coupling_strength / self._num_osc;

Response: Calculates the synchronization part using Kuramoto synchronization mechanism.


Instruction:
Can you tell what is the following Python 3 function doing
def __calculate_amplitude(self, amplitude, t, argv):

        z = amplitude.view(numpy.complex);
        dzdt = self.__landau_stuart(z, argv) + self.__synchronization_mechanism(z, argv);

        return dzdt.view(numpy.float64);

Response: Calculates the new amplitude value for particular oscillator that is defined by index that is in argv.


Instruction:
Make a summary of the following Python 3 code
def small_mind_image_recognition():
    images = [];
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_M;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_I;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_N;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_D;

    template_recognition_image(images, 100, 10, 0.2);

Response: Trains network using letters M I N D and recognize each of them with and without noise.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def small_abc_image_recognition():
    images = [];
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_A;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_B;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_C;

    template_recognition_image(images, 250, 25);

Response: Trains network using letters A B C and recognize each of them with and without noise.


Instruction:
Here you have a function in Python 3, explain what it does
def small_ftk_image_recognition():
    images = [];
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_F;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_T;
    images += IMAGE_SYMBOL_SAMPLES.LIST_IMAGES_SYMBOL_K;

    template_recognition_image(images, 100, 10, 0.2);

Response: Trains network using letters F T K and recognize each of them with and without noise.


Instruction:
How would you code a function in Python 3 to
convert chromosome to cluster representation

Response:
def get_clusters_representation(chromosome, count_clusters=None):
        """ Convert chromosome to cluster representation:
                chromosome : [0, 1, 1, 0, 2, 3, 3]
                clusters: [[0, 3], [1, 2], [4], [5, 6]]
        """

        if count_clusters is None:
            count_clusters = ga_math.calc_count_centers(chromosome)

        # Initialize empty clusters
        clusters = [[] for _ in range(count_clusters)]

        # Fill clusters with index of data
        for _idx_data in range(len(chromosome)):
            clusters[chromosome[_idx_data]].append(_idx_data)

        return clusters


Instruction:
Can you write a function in Python 3 where it
calculates centres of chromosomes.

Response:
def get_centres(chromosomes, data, count_clusters):
        """!
        """

        centres = ga_math.calc_centers(chromosomes, data, count_clusters)

        return centres


Instruction:
How would you code a function in Python 3 to
calculate the centers of the data in the cluster.

Response:
def calc_centers(chromosomes, data, count_clusters=None):
        """!
        """

        if count_clusters is None:
            count_clusters = ga_math.calc_count_centers(chromosomes[0])

        # Initialize center
        centers = np.zeros(shape=(len(chromosomes), count_clusters, len(data[0])))

        for _idx_chromosome in range(len(chromosomes)):

            # Get count data in clusters
            count_data_in_cluster = np.zeros(count_clusters)

            # Next data point
            for _idx in range(len(chromosomes[_idx_chromosome])):

                cluster_num = chromosomes[_idx_chromosome][_idx]

                centers[_idx_chromosome][cluster_num] += data[_idx]
                count_data_in_cluster[cluster_num] += 1

            for _idx_cluster in range(count_clusters):
                if count_data_in_cluster[_idx_cluster] != 0:
                    centers[_idx_chromosome][_idx_cluster] /= count_data_in_cluster[_idx_cluster]

        return centers


Instruction:
Write a Python 3 function for
calculating the probability vector of a set of fitness functions.

Response:
def calc_probability_vector(fitness):
        """!
        """

        if len(fitness) == 0:
            raise AttributeError("Has no any fitness functions.")

        # Get 1/fitness function
        inv_fitness = np.zeros(len(fitness))

        #
        for _idx in range(len(inv_fitness)):

            if fitness[_idx] != 0.0:
                inv_fitness[_idx] = 1.0 / fitness[_idx]
            else:
                inv_fitness[_idx] = 0.0

        # Initialize vector
        prob = np.zeros(len(fitness))

        # Initialize first element
        prob[0] = inv_fitness[0]

        # Accumulate values in probability vector
        for _idx in range(1, len(inv_fitness)):
            prob[_idx] = prob[_idx - 1] + inv_fitness[_idx]

        # Normalize
        prob /= prob[-1]

        ga_math.set_last_value_to_one(prob)

        return prob


Instruction:
Can you generate the documentation for the following Python 3 function
def set_last_value_to_one(probabilities):

        # Start from the last elem
        back_idx = - 1

        # All values equal to the last elem should be set to 1
        last_val = probabilities[back_idx]

        # for all elements or if a elem not equal to the last elem
        for _ in range(-1, -len(probabilities) - 1):
            if probabilities[back_idx] == last_val:
                probabilities[back_idx] = 1
            else:
                break

Response: Update the last same probabilities to one.


Instruction:
Can you tell what is the following Python 3 function doing
def cluster_sample1():
    "Start with wrong number of clusters."
    start_centers = [[3.7, 5.5]]
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE1, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE1, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Start with wrong number of clusters.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def cluster_sample2():
    "Start with wrong number of clusters."
    start_centers = [[3.5, 4.8], [2.6, 2.5]]
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE2, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE2, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Start with wrong number of clusters.


Instruction:
Create a Python 3 function for
starting with wrong number of clusters.

Response:
def cluster_sample3():
    "Start with wrong number of clusters."
    start_centers = [[0.2, 0.1], [4.0, 1.0]]
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE3, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE3, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)


Instruction:
Create a Python 3 function for
starting with wrong number of clusters.

Response:
def cluster_sample5():
    "Start with wrong number of clusters."
    start_centers = [[0.0, 1.0], [0.0, 0.0]]
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE5, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_SIMPLE5, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def cluster_elongate():
    "Not so applicable for this sample"
    start_centers = [[1.0, 4.5], [3.1, 2.7]]
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_ELONGATE, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, SIMPLE_SAMPLES.SAMPLE_ELONGATE, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Not so applicable for this sample


Instruction:
Explain what the following Python 3 code does
def cluster_lsun():
    "Not so applicable for this sample"
    start_centers = [[1.0, 3.5], [2.0, 0.5], [3.0, 3.0]]
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_LSUN, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_LSUN, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Not so applicable for this sample


Instruction:
Make a summary of the following Python 3 code
def cluster_target():
    "Not so applicable for this sample"
    start_centers = [[0.2, 0.2], [0.0, -2.0], [3.0, -3.0], [3.0, 3.0], [-3.0, 3.0], [-3.0, -3.0]]
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TARGET, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TARGET, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Not so applicable for this sample


Instruction:
How would you explain what the following Python 3 function does
def cluster_two_diamonds():
    "Start with wrong number of clusters."
    start_centers = [[0.8, 0.2]]
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TWO_DIAMONDS, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_TWO_DIAMONDS, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)

Response: Start with wrong number of clusters.


Instruction:
Implement a Python 3 function for
starting with wrong number of clusters.

Response:
def cluster_hepta():
    "Start with wrong number of clusters."
    start_centers = [[0.0, 0.0, 0.0], [3.0, 0.0, 0.0], [-2.0, 0.0, 0.0], [0.0, 3.0, 0.0], [0.0, -3.0, 0.0], [0.0, 0.0, 2.5]]
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_HEPTA, criterion = splitting_type.BAYESIAN_INFORMATION_CRITERION)
    template_clustering(start_centers, FCPS_SAMPLES.SAMPLE_HEPTA, criterion = splitting_type.MINIMUM_NOISELESS_DESCRIPTION_LENGTH)


Instruction:
Write a Python 3 function for
calculating new connectivity radius.

Response:
def __calculate_radius(self, number_neighbors, radius):
        """!
        @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.

        """

        if (number_neighbors >= len(self._osc_loc)):
            return radius * self.__increase_persent + radius;

        return average_neighbor_distance(self._osc_loc, number_neighbors);


Instruction:
Can you generate the documentation for the following Python 3 function
def __store_dynamic(self, dyn_phase, dyn_time, analyser, begin_state):

        if (begin_state is True):
            dyn_time.append(0);
            dyn_phase.append(analyser.output[0]);

        else:
            dyn_phase.append(analyser.output[len(analyser.output) - 1]);
            dyn_time.append(len(dyn_time));

Response: Store the specified state of a specific dynamic of Sync network to hSync.


Instruction:
Write a Python 3 script for
changing the type of clusters encoding to specified type.

Response:
def set_encoding(self, encoding):
        """!
        @brief Change clusters encoding to specified type (index list, object list, labeling).

        @param[in] encoding (type_encoding): New type of clusters representation.

        """

        if(encoding == self.__type_representation):
            return;

        if (self.__type_representation == type_encoding.CLUSTER_INDEX_LABELING):
            if (encoding == type_encoding.CLUSTER_INDEX_LIST_SEPARATION):
                self.__clusters = self.__convert_label_to_index();

            else:
                self.__clusters = self.__convert_label_to_object();

        elif (self.__type_representation == type_encoding.CLUSTER_INDEX_LIST_SEPARATION):
            if (encoding == type_encoding.CLUSTER_INDEX_LABELING):
                self.__clusters = self.__convert_index_to_label();

            else:
                self.__clusters = self.__convert_index_to_object();

        else:
            if (encoding == type_encoding.CLUSTER_INDEX_LABELING):
                self.__clusters = self.__convert_object_to_label();

            else:
                self.__clusters = self.__convert_object_to_index();

        self.__type_representation = encoding;


Instruction:
Can you generate a brief explanation for the following Python 3 code
def process(self):

        if self.__ccore is True:
            (self.__clusters, self.__noise) = wrapper.dbscan(self.__pointer_data, self.__eps, self.__neighbors, self.__data_type)

        else:
            if self.__data_type == 'points':
                self.__kdtree = kdtree(self.__pointer_data, range(len(self.__pointer_data)))

            for i in range(0, len(self.__pointer_data)):
                if self.__visited[i] is False:
                    cluster = self.__expand_cluster(i)
                    if cluster is not None:
                        self.__clusters.append(cluster)

            for i in range(0, len(self.__pointer_data)):
                if self.__belong[i] is False:
                    self.__noise.append(i)

Response: This method is called by the class constructor when the class is instantiated.


Instruction:
How would you code a function in Python 3 to
return a list of indexes that belong to the same cluster and list of points that are not noise.

Response:
def __expand_cluster(self, index_point):
        """!
        @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.

        """

        cluster = None
        self.__visited[index_point] = True
        neighbors = self.__neighbor_searcher(index_point)

        if len(neighbors) >= self.__neighbors:
            cluster = [index_point]

            self.__belong[index_point] = True

            for i in neighbors:
                if self.__visited[i] is False:
                    self.__visited[i] = True

                    next_neighbors = self.__neighbor_searcher(i)

                    if len(next_neighbors) >= self.__neighbors:
                        neighbors += [k for k in next_neighbors if ( (k in neighbors) == False) and k != index_point]

                if self.__belong[i] is False:
                    cluster.append(i)
                    self.__belong[i] = True

        return cluster


Instruction:
Write a Python 3 function for
returning the neighbors of the specified object in case of sequence of points.

Response:
def __neighbor_indexes_points(self, index_point):
        """!
        @brief Return neighbors of the specified object in case of sequence of points.

        @param[in] index_point (uint): Index point whose neighbors are should be found.

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

        """
        kdnodes = self.__kdtree.find_nearest_dist_nodes(self.__pointer_data[index_point], self.__eps)
        return [node_tuple[1].payload for node_tuple in kdnodes if node_tuple[1].payload != index_point]


Instruction:
Make a summary of the following Python 3 code
def __neighbor_indexes_distance_matrix(self, index_point):
        distances = self.__pointer_data[index_point]
        return [index_neighbor for index_neighbor in range(len(distances))
                if ((distances[index_neighbor] <= self.__eps) and (index_neighbor != index_point))]

Response: Returns neighbors of the specified object in case of distance matrix.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def generate(self):
        data_points = []

        for index_cluster in range(self.__amount_clusters):
            for _ in range(self.__cluster_sizes[index_cluster]):
                point = self.__generate_point(index_cluster)
                data_points.append(point)

        return data_points

Response: Generates data points in line with generator parameters.


Instruction:
Can you generate the documentation for the following Python 3 function
def __generate_point(self, index_cluster):
        return [ random.gauss(self.__cluster_centers[index_cluster][index_dimension],
                              self.__cluster_width[index_cluster] / 2.0)
                 for index_dimension in range(self.__dimension) ]

Response: Generate a new point in line with normal distribution and cluster parameters.


Instruction:
Can you generate the documentation for the following Python 3 function
def __generate_cluster_centers(self, width):
        centers = []
        default_offset = max(width) * 4.0
        for i in range(self.__amount_clusters):
            center = [ random.gauss(i * default_offset, width[i] / 2.0) for _ in range(self.__dimension) ]
            centers.append(center)

        return centers

Response: Generate centers in line with normal distribution.


Instruction:
Write a Python 3 function for
reading a graph from a file in GRPR format.

Response:
def read_graph(filename):
    """!
    @brief Read graph from file in GRPR format.

    @param[in] filename (string): Path to file with graph in GRPR format.

    @return (graph) Graph that is read from file.

    """

    file = open(filename, 'r');

    comments = "";
    space_descr = [];
    data = [];
    data_type = None;

    map_data_repr = dict();   # Used as a temporary buffer only when input graph is represented by edges.

    for line in file:
        if (line[0] == 'c' or line[0] == 'p'):
            comments += line[1:];

        elif (line[0] == 'r'):
            node_coordinates = [float(val) for val in line[1:].split()];
            if (len(node_coordinates) != 2):
                raise NameError('Invalid format of space description for node (only 2-dimension space is supported)');

            space_descr.append( [float(val) for val in line[1:].split()] );

        elif (line[0] == 'm'):
            if ( (data_type is not None) and (data_type != 'm') ):
                raise NameError('Invalid format of graph representation (only one type should be used)');

            data_type = 'm';
            data.append( [float(val) for val in line[1:].split()] );

        elif (line[0] == 'v'):
            if ( (data_type is not None) and (data_type != 'v') ):
                raise NameError('Invalid format of graph representation (only one type should be used)');

            data_type = 'v';
            data.append( [float(val) for val in line[1:].split()] );

        elif (line[0] == 'e'):
            if ( (data_type is not None) and (data_type != 'e') ):
                raise NameError('Invalid format of graph representation (only one type should be used)');

            data_type = 'e';
            vertices = [int(val) for val in line[1:].split()];

            if (vertices[0] not in map_data_repr):
                map_data_repr[ vertices[0] ] = [ vertices[1] ];
            else:
                map_data_repr[ vertices[0] ].append(vertices[1])

            if (vertices[1] not in map_data_repr):
                map_data_repr[ vertices[1] ] = [ vertices[0] ];
            else:
                map_data_repr[ vertices[1] ].append(vertices[0]);

        elif (len(line.strip()) == 0): continue;

        else:
            print(line);
            raise NameError('Invalid format of file with graph description');

    # In case of edge representation result should be copied.
    if (data_type == 'e'):
        for index in range(len(map_data_repr)):
            data.append([0] * len(map_data_repr));

            for index_neighbour in map_data_repr[index + 1]:
                data[index][index_neighbour - 1] = 1;

    file.close();

    # Set graph description
    graph_descr = None;
    if (data_type == 'm'): graph_descr = type_graph_descr.GRAPH_MATRIX_DESCR;
    elif (data_type == 'v'): graph_descr = type_graph_descr.GRAPH_VECTOR_DESCR;
    elif (data_type == 'e'): graph_descr = type_graph_descr.GRAPH_MATRIX_DESCR;
    else:
        raise NameError('Invalid format of file with graph description');

    if (space_descr != []):
        if (len(data) != len(space_descr)):
            raise NameError("Invalid format of file with graph - number of nodes is different in space representation and graph description");

    return graph(data, graph_descr, space_descr, comments);


Instruction:
Make a summary of the following Python 3 code
def draw_graph(graph_instance, map_coloring = None):

    if (graph_instance.space_description is None):
        raise NameError("The graph haven't got representation in space");

    if (map_coloring is not None):
        if (len(graph_instance) != len(map_coloring)):
            raise NameError("Size of graph should be equal to size coloring map");

    fig = plt.figure();
    axes = fig.add_subplot(111);

    available_colors = ['#00a2e8', '#22b14c', '#ed1c24',
                        '#fff200', '#000000', '#a349a4',
                        '#ffaec9', '#7f7f7f', '#b97a57',
                        '#c8bfe7', '#880015', '#ff7f27',
                        '#3f48cc', '#c3c3c3', '#ffc90e',
                        '#efe4b0', '#b5e61d', '#99d9ea',
                        '#7092b4', '#ffffff'];

    if (map_coloring is not None):
        if (len(map_coloring) > len(available_colors)):
            raise NameError('Impossible to represent colored graph due to number of specified colors.');

    x_maximum = -float('inf');
    x_minimum = float('inf');
    y_maximum = -float('inf');
    y_minimum = float('inf');

    for i in range(0, len(graph_instance.space_description), 1):
        if (graph_instance.type_graph_descr == type_graph_descr.GRAPH_MATRIX_DESCR):
            for j in range(i, len(graph_instance.space_description), 1):    # draw connection between two points only one time
                if (graph_instance.data[i][j] == 1):
                    axes.plot([graph_instance.space_description[i][0], graph_instance.space_description[j][0]], [graph_instance.space_description[i][1], graph_instance.space_description[j][1]], 'k-', linewidth = 1.5);

        elif (graph_instance.type_graph_descr == type_graph_descr.GRAPH_VECTOR_DESCR):
            for j in graph_instance.data[i]:
                if (i > j):     # draw connection between two points only one time
                    axes.plot([graph_instance.space_description[i][0], graph_instance.space_description[j][0]], [graph_instance.space_description[i][1], graph_instance.space_description[j][1]], 'k-', linewidth = 1.5);

        color_node = 'b';
        if (map_coloring is not None):
            color_node = colors.hex2color(available_colors[map_coloring[i]]);

        axes.plot(graph_instance.space_description[i][0], graph_instance.space_description[i][1], color = color_node, marker = 'o', markersize = 20);

        if (x_maximum < graph_instance.space_description[i][0]): x_maximum = graph_instance.space_description[i][0];
        if (x_minimum > graph_instance.space_description[i][0]): x_minimum = graph_instance.space_description[i][0];
        if (y_maximum < graph_instance.space_description[i][1]): y_maximum = graph_instance.space_description[i][1];
        if (y_minimum > graph_instance.space_description[i][1]): y_minimum = graph_instance.space_description[i][1];

    plt.xlim(x_minimum - 0.5, x_maximum + 0.5);
    plt.ylim(y_minimum - 0.5, y_maximum + 0.5);

    plt.show();

Response: Draws a single graph.


Instruction:
Make a summary of the following Python 3 code
def process(self):
        if self.__ccore is True:
            self.__process_by_ccore()
        else:
            self.__process_by_python()

        return self

Response: A method that processes the cluster by the Fuzzy C - Means algorithm.


Instruction:
Implement a function in Python 3 to
process the cluster by C ++ implementation.

Response:
def __process_by_ccore(self):
        """!
        @brief Performs cluster analysis using C/C++ implementation.

        """
        result = wrapper.fcm_algorithm(self.__data, self.__centers, self.__m, self.__tolerance, self.__itermax)

        self.__clusters = result[wrapper.fcm_package_indexer.INDEX_CLUSTERS]
        self.__centers = result[wrapper.fcm_package_indexer.INDEX_CENTERS]
        self.__membership = result[wrapper.fcm_package_indexer.INDEX_MEMBERSHIP]


Instruction:
Can you tell what is the following Python 3 function doing
def __process_by_python(self):
        self.__data = numpy.array(self.__data)
        self.__centers = numpy.array(self.__centers)

        self.__membership = numpy.zeros((len(self.__data), len(self.__centers)))

        change = float('inf')
        iteration = 0

        while change > self.__tolerance and iteration < self.__itermax:
            self.__update_membership()
            centers = self.__calculate_centers()
            change = self.__calculate_changes(centers)

            self.__centers = centers
            iteration += 1

        self.__extract_clusters()

Response: This method is used by the cluster analysis process_by_python method.


Instruction:
Make a summary of the following Python 3 code
def __calculate_centers(self):
        dimension = self.__data.shape[1]
        centers = numpy.zeros((len(self.__centers), dimension))

        for i in range(len(self.__centers)):
            # multiplication '@' requires python version 3.5
            centers[i] = numpy.divide(self.__membership[:, i] @ self.__data, numpy.sum(self.__membership[:, i]))

        return centers

Response: Calculate center using membership of each cluster.


Instruction:
How would you explain what the following Python 3 function does
def __update_membership(self):
        data_difference = numpy.zeros((len(self.__centers), len(self.__data)))

        for i in range(len(self.__centers)):
            data_difference[i] = numpy.sum(numpy.square(self.__data - self.__centers[i]), axis=1)

        for i in range(len(self.__data)):
            for j in range(len(self.__centers)):
                divider = sum([pow(data_difference[j][i] / data_difference[k][i], self.__degree) for k in range(len(self.__centers)) if data_difference[k][i] != 0.0])

                if divider != 0.0:
                    self.__membership[i][j] = 1.0 / divider
                else:
                    self.__membership[i][j] = 1.0

Response: Update membership for each point in line with current cluster centers.


Instruction:
Given the following Python 3 function, write the documentation
def __calculate_changes(self, updated_centers):
        changes = numpy.sum(numpy.square(self.__centers - updated_centers), axis=1).T
        return numpy.max(changes)

Response: Calculate the change between the centers and the updated centers.


Instruction:
Implement a Python 3 function for
collecting the best chromosome and its fitness function s value.

Response:
def collect_global_best(self, best_chromosome, best_fitness_function):
        """!
        @brief Stores the best chromosome and its fitness function's value.

        @param[in] best_chromosome (list): The best chromosome that were observed.
        @param[in] best_fitness_function (float): Fitness function value of the best chromosome.

        """

        if not self._need_global_best:
            return

        self._global_best_result['chromosome'].append(best_chromosome)
        self._global_best_result['fitness_function'].append(best_fitness_function)


Instruction:
Implement a function in Python 3 to
collect the best chromosome for current specific iteration and its fitness function.

Response:
def collect_population_best(self, best_chromosome, best_fitness_function):
        """!
        @brief Stores the best chromosome for current specific iteration and its fitness function's value.

        @param[in] best_chromosome (list): The best chromosome on specific iteration.
        @param[in] best_fitness_function (float): Fitness function value of the chromosome.

        """

        if not self._need_population_best:
            return

        self._best_population_result['chromosome'].append(best_chromosome)
        self._best_population_result['fitness_function'].append(best_fitness_function)


Instruction:
Explain what the following Python 3 code does
def collect_mean(self, fitness_functions):

        if not self._need_mean_ff:
            return

        self._mean_ff_result.append(np.mean(fitness_functions))

Response: Collect the average value of fitness functions among chromosomes on specific iteration.


Instruction:
Write a Python 3 function that can
display the evolution of fitness function for the current best chromosome and the current best chromosome and the average value among all chromosomes.

Response:
def show_evolution(observer, start_iteration = 0, stop_iteration=None, ax=None, display=True):
        """!
        @brief Displays evolution of fitness function for the best chromosome, for the current best chromosome and
                average value among all chromosomes.

        @param[in] observer (ga_observer): Genetic algorithm observer that was used for collecting evolution in the algorithm and
                    where whole required information for visualization is stored.
        @param[in] start_iteration (uint): Iteration from that evolution should be shown.
        @param[in] stop_iteration (uint): Iteration after that evolution shouldn't be shown.
        @param[in] ax (Axes): Canvas where evolution should be displayed.
        @param[in] display (bool): If 'True' then visualization of the evolution will be shown by the function.
                    This argument should be 'False' if you want to add something else to the canvas and display it later.

        @return (Axis) Canvas where evolution was shown.

        """

        if (ax is None):
            _, ax = plt.subplots(1)
            ax.set_title("Evolution")

        if stop_iteration is None:
            stop_iteration = len(observer)

        line_best, = ax.plot(observer.get_global_best()['fitness_function'][start_iteration:stop_iteration], 'r')
        line_current, = ax.plot(observer.get_population_best()['fitness_function'][start_iteration:stop_iteration], 'k')
        line_mean, = ax.plot(observer.get_mean_fitness_function()[start_iteration:stop_iteration], 'c')

        if start_iteration < (stop_iteration - 1):
            ax.set_xlim([start_iteration, (stop_iteration - 1)])

        ax.set_xlabel("Iteration")
        ax.set_ylabel("Fitness function")
        ax.legend([line_best, line_current, line_mean], ["The best pop.", "Cur. best pop.", "Average"], prop={'size': 10})
        ax.grid()

        if display is True:
            plt.show()

        return ax


Instruction:
Write a Python 3 script to
show allocated clusters by the genetic algorithm.

Response:
def show_clusters(data, observer, marker='.', markersize=None):
        """!
        @brief Shows allocated clusters by the genetic algorithm.

        @param[in] data (list): Input data that was used for clustering process by the algorithm.
        @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
        @param[in] marker (char): Type of marker that should be used for object (point) representation.
        @param[in] markersize (uint): Size of the marker that is used for object (point) representation.

        @note If you have clusters instead of observer then 'cluster_visualizer' can be used for visualization purposes.

        @see cluster_visualizer

        """

        figure = plt.figure()
        ax1 = figure.add_subplot(121)

        clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][-1])

        visualizer = cluster_visualizer(1, 2)
        visualizer.append_clusters(clusters, data, 0, marker, markersize)
        visualizer.show(figure, display=False)

        ga_visualizer.show_evolution(observer, 0, None, ax1, True)


Instruction:
Write a Python 3 script for
animating clustering process of genetic clustering algorithm.

Response:
def animate_cluster_allocation(data, observer, animation_velocity=75, movie_fps=5, save_movie=None):
        """!
        @brief Animate clustering process of genetic clustering algorithm.
        @details This method can be also used for rendering movie of clustering process and 'ffmpeg' is required for that purpuse.

        @param[in] data (list): Input data that was used for clustering process by the algorithm.
        @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
                    Be sure that whole information was collected by the observer.
        @param[in] animation_velocity (uint): Interval between frames in milliseconds (for run-time animation only).
        @param[in] movie_fps (uint): Defines frames per second (for rendering movie only).
        @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.

        """

        figure = plt.figure()

        def init_frame():
            return frame_generation(0)

        def frame_generation(index_iteration):
            figure.clf()

            figure.suptitle("Clustering genetic algorithm (iteration: " + str(index_iteration) + ")", fontsize=18, fontweight='bold')

            visualizer = cluster_visualizer(4, 2, ["The best pop. on step #" + str(index_iteration), "The best population"])

            local_minimum_clusters = ga_math.get_clusters_representation(observer.get_population_best()['chromosome'][index_iteration])
            visualizer.append_clusters(local_minimum_clusters, data, 0)

            global_minimum_clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][index_iteration])
            visualizer.append_clusters(global_minimum_clusters, data, 1)

            ax1 = plt.subplot2grid((2, 2), (1, 0), colspan=2)
            ga_visualizer.show_evolution(observer, 0, index_iteration + 1, ax1, False)

            visualizer.show(figure, shift=0, display=False)
            figure.subplots_adjust(top=0.85)

            return [figure.gca()]

        iterations = len(observer)
        cluster_animation = animation.FuncAnimation(figure, frame_generation, iterations, interval=animation_velocity, init_func=init_frame, repeat_delay=5000)

        if save_movie is not None:
            cluster_animation.save(save_movie, writer='ffmpeg', fps=movie_fps, bitrate=1500)
        else:
            plt.show()


Instruction:
Given the following Python 3 function, write the documentation
def process(self):

        # Initialize population
        chromosomes = self._init_population(self._count_clusters, len(self._data), self._chromosome_count)

        # Initialize the Best solution
        best_chromosome, best_ff, first_fitness_functions \
            = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)

        # Save best result into observer
        if self._observer is not None:
            self._observer.collect_global_best(best_chromosome, best_ff)
            self._observer.collect_population_best(best_chromosome, best_ff)
            self._observer.collect_mean(first_fitness_functions)

        # Next population
        for _ in range(self._population_count):

            # Select
            chromosomes = self._select(chromosomes, self._data, self._count_clusters, self._select_coeff)

            # Crossover
            self._crossover(chromosomes)

            # Mutation
            self._mutation(chromosomes, self._count_clusters, self._count_mutation_gens, self._coeff_mutation_count)

            # Update the Best Solution
            new_best_chromosome, new_best_ff, fitness_functions \
                = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)

            # Get best chromosome
            if new_best_ff < best_ff:
                best_ff = new_best_ff
                best_chromosome = new_best_chromosome

            # Save best result into observer
            if self._observer is not None:
                self._observer.collect_global_best(best_chromosome, best_ff)
                self._observer.collect_population_best(new_best_chromosome, new_best_ff)
                self._observer.collect_mean(fitness_functions)

        # Save result
        self._result_clustering['best_chromosome'] = best_chromosome
        self._result_clustering['best_fitness_function'] = best_ff

        return best_chromosome, best_ff

Response: This method processes the genetic clustering algorithm in line with rule of genetic clustering algorithm.


Instruction:
Implement a Python 3 function for
selecting new chromosomes based on the given data.

Response:
def _select(chromosomes, data, count_clusters, select_coeff):
        """!
        @brief Performs selection procedure where new chromosomes are calculated.

        @param[in] chromosomes (numpy.array): Chromosomes

        """

        # Calc centers
        centres = ga_math.get_centres(chromosomes, data, count_clusters)

        # Calc fitness functions
        fitness = genetic_algorithm._calc_fitness_function(centres, data, chromosomes)

        for _idx in range(len(fitness)):
            fitness[_idx] = math.exp(1 + fitness[_idx] * select_coeff)

        # Calc probability vector
        probabilities = ga_math.calc_probability_vector(fitness)

        # Select P chromosomes with probabilities
        new_chromosomes = np.zeros(chromosomes.shape, dtype=np.int)

        # Selecting
        for _idx in range(len(chromosomes)):
            new_chromosomes[_idx] = chromosomes[ga_math.get_uniform(probabilities)]

        return new_chromosomes


Instruction:
Can you tell what is the following Python 3 function doing
def _mutation(chromosomes, count_clusters, count_gen_for_mutation, coeff_mutation_count):

        # Count gens in Chromosome
        count_gens = len(chromosomes[0])

        # Get random chromosomes for mutation
        random_idx_chromosomes = np.array(range(len(chromosomes)))
        np.random.shuffle(random_idx_chromosomes)

        #
        for _idx_chromosome in range(int(len(random_idx_chromosomes) * coeff_mutation_count)):

            #
            for _ in range(count_gen_for_mutation):

                # Get random gen
                gen_num = np.random.randint(count_gens)

                # Set random cluster
                chromosomes[random_idx_chromosomes[_idx_chromosome]][gen_num] = np.random.randint(count_clusters)

Response: This function is used to generate random cluster and mutation chromosomes.


Instruction:
Create a Python 3 function to
return a crossover mask that can be used to crossover a pair of chromosomes.

Response:
def _get_crossover_mask(mask_length):
        """!
        @brief Crossover mask to crossover a pair of chromosomes.

        @param[in] mask_length (uint): Length of the mask.

        """

        # Initialize mask
        mask = np.zeros(mask_length)

        # Set a half of array to 1
        mask[:int(int(mask_length) / 2)] = 1

        # Random shuffle
        np.random.shuffle(mask)

        return mask


Instruction:
Write a Python 3 function that can
initialize the first population as a uniform random choice.

Response:
def _init_population(count_clusters, count_data, chromosome_count):
        """!
        @brief Returns first population as a uniform random choice.

        @param[in] count_clusters (uint): Amount of clusters that should be allocated.
        @param[in] count_data (uint): Data size that is used for clustering process.
        @param[in] chromosome_count (uint):Amount of chromosome that is used for clustering.

        """

        population = np.random.randint(count_clusters, size=(chromosome_count, count_data))

        return population


Instruction:
Can you generate the documentation for the following Python 3 function
def _calc_fitness_function(centres, data, chromosomes):

        # Get count of chromosomes and clusters
        count_chromosome = len(chromosomes)

        # Initialize fitness function values
        fitness_function = np.zeros(count_chromosome)

        # Calc fitness function for each chromosome
        for _idx_chromosome in range(count_chromosome):

            # Get centers for a selected chromosome
            centres_data = np.zeros(data.shape)

            # Fill data centres
            for _idx in range(len(data)):
                centres_data[_idx] = centres[_idx_chromosome][chromosomes[_idx_chromosome][_idx]]

            # Get City Block distance for a chromosome
            fitness_function[_idx_chromosome] += np.sum(abs(data - centres_data))

        return fitness_function

Response: Calculates the fitness function values for each chromosome correspondingly.


Instruction:
Can you implement a function in Python 3 that
gets the distance between two clusters in line with the given type.

Response:
def get_distance(self, entry, type_measurement):
        """!
        @brief Calculates distance between two clusters in line with measurement type.

        @details In case of usage CENTROID_EUCLIDIAN_DISTANCE square euclidian distance will be returned.
                 Square root should be taken from the result for obtaining real euclidian distance between
                 entries.

        @param[in] entry (cfentry): Clustering feature to which distance should be obtained.
        @param[in] type_measurement (measurement_type): Distance measurement algorithm between two clusters.

        @return (double) Distance between two clusters.

        """

        if (type_measurement is measurement_type.CENTROID_EUCLIDEAN_DISTANCE):
            return euclidean_distance_square(entry.get_centroid(), self.get_centroid());

        elif (type_measurement is measurement_type.CENTROID_MANHATTAN_DISTANCE):
            return manhattan_distance(entry.get_centroid(), self.get_centroid());

        elif (type_measurement is measurement_type.AVERAGE_INTER_CLUSTER_DISTANCE):
            return self.__get_average_inter_cluster_distance(entry);

        elif (type_measurement is measurement_type.AVERAGE_INTRA_CLUSTER_DISTANCE):
            return self.__get_average_intra_cluster_distance(entry);

        elif (type_measurement is measurement_type.VARIANCE_INCREASE_DISTANCE):
            return self.__get_variance_increase_distance(entry);

        else:
            assert 0;