<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def density_separation(X, labels, cluster_id1, cluster_id2, internal_nodes1, internal_nodes2, core_distances1, core_distances2, metric='euclidean', **kwd_args):
 """ Compute the density separation between two clusters. This is the minimum all-points mutual reachability distance between pairs of points, one from internal nodes of MSTs of each cluster. Parameters X : array (n_samples, n_features) or (n_samples, n_samples) The input data of the clustering. This can be the data, or, if metric is set to `precomputed` the pairwise distance matrix used for the clustering. labels : array (n_samples) The label array output by the clustering, providing an integral cluster label to each data point, with -1 for noise points. cluster_id1 : integer The first cluster label to compute separation between. cluster_id2 : integer The second cluster label to compute separation between. internal_nodes1 : array The vertices of the MST for `cluster_id1` that were internal vertices. internal_nodes2 : array The vertices of the MST for `cluster_id2` that were internal vertices. core_distances1 : array (size of cluster_id1,) The all-points-core_distances of all points in the cluster specified by cluster_id1. core_distances2 : array (size of cluster_id2,) The all-points-core_distances of all points in the cluster specified by cluster_id2. metric : string The metric used to compute distances for the clustering (and to be re-used in computing distances for mr distance). If set to `precomputed` then X is assumed to be the precomputed distance matrix between samples. **kwd_args : Extra arguments to pass to the distance computation for other metrics, such as minkowski, Mahanalobis etc. Returns ------- The 'density separation' between the clusters specified by `cluster_id1` and `cluster_id2`. References Moulavi, D., Jaskowiak, P.A., Campello, R.J., Zimek, A. and Sander, J., 2014. Density-Based Clustering Validation. In SDM (pp. 839-847). """

    if metric == 'precomputed':
        sub_select = X[labels == cluster_id1, :][:, labels == cluster_id2]
        distance_matrix = sub_select[internal_nodes1, :][:, internal_nodes2]
    else:
        cluster1 = X[labels == cluster_id1][internal_nodes1]
        cluster2 = X[labels == cluster_id2][internal_nodes2]
        distance_matrix = cdist(cluster1, cluster2, metric, **kwd_args)

    core_dist_matrix1 = np.tile(core_distances1[internal_nodes1],
                                (distance_matrix.shape[1], 1)).T
    core_dist_matrix2 = np.tile(core_distances2[internal_nodes2],
                                (distance_matrix.shape[0], 1))

    mr_dist_matrix = np.dstack([distance_matrix,
                                core_dist_matrix1,
                                core_dist_matrix2]).max(axis=-1)

    return mr_dist_matrix.min()