Splits the higher level clusters
@param {Array <Array <number>>} data - Array of points to be clustered
@param {json} options
@constructor
359059
function diana(data, options) {
                options = Object.assign({}, defaultOptions$6, options);
                if (typeof options.kind === 'string') {
                    switch (options.kind) {
                        case 'single':
                            options.kind = simpleLink$1;
                            break;
                        case 'complete':
                            options.kind = completeLink$1;
                            break;
                        case 'average':
                            options.kind = averageLink$1;
                            break;
                        case 'centroid':
                            options.kind = centroidLink$1;
                            break;
                        case 'ward':
                            options.kind = wardLink$1;
                            break;
                        default:
                            throw new RangeError('Unknown kind of similarity');
                    }
                } else if (typeof options.kind !== 'function') {
                    throw new TypeError('Undefined kind of similarity');
                }
                var tree = new Cluster_1();
                tree.children = new Array(data.length);
                tree.index = new Array(data.length);
                for (var ind = 0; ind < data.length; ind++) {
                    tree.children[ind] = new ClusterLeaf_1(ind);
                    tree.index[ind] = new ClusterLeaf_1(ind);
                }

                tree.distance = intrDist(tree.index, data, options.dist);
                var m, M, clId,
                    dist, rebel;
                var list = [tree];
                while (list.length > 0) {
                    M = 0;
                    clId = 0;
                    for (var i = 0; i < list.length; i++) {
                        m = 0;
                        for (var j = 0; j < list[i].length; j++) {
                            for (var l = (j + 1); l < list[i].length; l++) {
                                m = Math.max(options.dist(data[list[i].index[j].index], data[list[i].index[l].index]), m);
                            }
                        }
                        if (m > M) {
                            M = m;
                            clId = i;
                        }
                    }
                    M = 0;
                    if (list[clId].index.length === 2) {
                        list[clId].children = [list[clId].index[0], list[clId].index[1]];
                        list[clId].distance = options.dist(data[list[clId].index[0].index], data[list[clId].index[1].index]);
                    } else if (list[clId].index.length === 3) {
                        list[clId].children = [list[clId].index[0], list[clId].index[1], list[clId].index[2]];
                        var d = [
                            options.dist(data[list[clId].index[0].index], data[list[clId].index[1].index]),
                            options.dist(data[list[clId].index[1].index], data[list[clId].index[2].index])
                        ];
                        list[clId].distance = (d[0] + d[1]) / 2;
                    } else {
                        var C = new Cluster_1();
                        var sG = new Cluster_1();
                        var splitting = [new Array(list[clId].index.length), []];
                        for (var spl = 0; spl < splitting[0].length; spl++) {
                            splitting[0][spl] = spl;
                        }
                        for (var ii = 0; ii < splitting[0].length; ii++) {
                            dist = 0;
                            for (var jj = 0; jj < splitting[0].length; jj++) {
                                if (ii !== jj) {
                                    dist += options.dist(data[list[clId].index[splitting[0][jj]].index], data[list[clId].index[splitting[0][ii]].index]);
                                }
                            }
                            dist /= (splitting[0].length - 1);
                            if (dist > M) {
                                M = dist;
                                rebel = ii;
                            }
                        }
                        splitting[1] = [rebel];
                        splitting[0].splice(rebel, 1);
                        dist = diff(splitting, data, options.dist);
                        while (dist.d > 0) {
                            splitting[1].push(splitting[0][dist.p]);
                            splitting[0].splice(dist.p, 1);
                            dist = diff(splitting, data, options.dist);
                        }
                        var fData = new Array(splitting[0].length);
                        C.index = new Array(splitting[0].length);
                        for (var e = 0; e < fData.length; e++) {
                            fData[e] = data[list[clId].index[splitting[0][e]].index];
                            C.index[e] = list[clId].index[splitting[0][e]];
                            C.children[e] = list[clId].index[splitting[0][e]];
                        }
                        var sData = new Array(splitting[1].length);
                        sG.index = new Array(splitting[1].length);
                        for (var f = 0; f < sData.length; f++) {
                            sData[f] = data[list[clId].index[splitting[1][f]].index];
                            sG.index[f] = list[clId].index[splitting[1][f]];
                            sG.children[f] = list[clId].index[splitting[1][f]];
                        }
                        C.distance = intrDist(C.index, data, options.dist);
                        sG.distance = intrDist(sG.index, data, options.dist);
                        list.push(C);
                        list.push(sG);
                        list[clId].children = [C, sG];
                    }
                    list.splice(clId, 1);
                }
                return tree;
            }
16989
function polygonToPSLG(loops, options) {
  if(!Array.isArray(loops)) {
    throw new Error('poly-to-pslg: Error, invalid polygon')
  }
  if(loops.length === 0) {
    return {
      points: [],
      edges:  []
    }
  }

  options = options || {}

  var nested = true
  if('nested' in options) {
    nested = !!options.nested
  } else if(loops[0].length === 2 && typeof loops[0][0] === 'number') {
    //Hack:  If use doesn't pass in a loop, then try to guess if it is nested
    nested = false
  }
  if(!nested) {
    loops = [loops]
  }

  //First we just unroll all the points in the dumb/obvious way
  var points = []
  var edges = []
  for(var i=0; i<loops.length; ++i) {
    var loop = loops[i]
    var offset = points.length
    for(var j=0; j<loop.length; ++j) {
      points.push(loop[j])
      edges.push([ offset+j, offset+(j+1)%loop.length ])
    }
  }

  //Then we run snap rounding to clean up self intersections and duplicate verts
  var clean = 'clean' in options ? true : !!options.clean
  if(clean) {
    cleanPSLG(points, edges)
  }

  //Finally, we return the resulting PSLG
  return {
    points: points,
    edges:  edges
  }
}
970657
function(data, options) {
            for (var property in data) {
                if (!this.__hasProperty(property.split('.')[0])) {
                    continue;
                }

                var value = data[property];

                if (_.isUndefined(value) || _.isNull(value)) {
                    this.__removePropertyValue(property, options);
                }
                else if (_.isObject(value) && _.isEmpty(value)) {
                    this.__clearPropertyValue(property, options)
                }
                else {
                    this.__setPropertyValue(property, value, options);
                }
            }
            return this;
        }
1346354
@Override protected Split ltSplit(int col, Data d, int[] dist, int distWeight, Random rand) {
    final int[] distL = new int[d.classes()], distR = dist.clone();
    final double upperBoundReduction = upperBoundReduction(d.classes());
    double maxReduction = -1;
    int bestSplit = -1;
    int totL = 0, totR = 0;     // Totals in the distribution
    int classL = 0, classR = 0; // Count of non-zero classes in the left/right distributions
    for (int e: distR) { // All zeros for the left, but need to compute for the right
      totR += e;
      if( e != 0 ) classR++;
    }
    // For this one column, look at all his split points and find the one with the best gain.
    for (int i = 0; i < _columnDists[col].length - 1; ++i) {
      int [] cdis = _columnDists[col][i];
      for (int j = 0; j < distL.length; ++j) {
        int v = cdis[j];
        if( v == 0 ) continue;              // No rows with this class
        totL     += v;  totR     -= v;
        if( distL[j]== 0 ) classL++; // One-time transit from zero to non-zero for class j
        distL[j] += v;  distR[j] -= v;
        if( distR[j]== 0 ) classR--; // One-time transit from non-zero to zero for class j
      }
      if (totL == 0) continue;  // Totals are zero ==> this will not actually split anything
      if (totR == 0) continue;  // Totals are zero ==> this will not actually split anything

      // Compute gain.
      // If the distribution has only 1 class, the gain will be zero.
      double eL = 0, eR = 0;
      if( classL > 1 ) for (int e: distL) eL += gain(e,totL);
      if( classR > 1 ) for (int e: distR) eR += gain(e,totR);
      double eReduction = upperBoundReduction - ( (eL * totL + eR * totR) / (totL + totR) );

      if (eReduction == maxReduction) {
        // For now, don't break ties.  Most ties are because we have several
        // splits with NO GAIN.  This happens *billions* of times in a standard
        // covtype RF, because we have >100K leaves per tree (and 50 trees and
        // 54 columns per leave and however many bins per column), and most
        // leaves have no gain at most split points.
        //if (rand.nextInt(10)<2) bestSplit=i;
      } else if (eReduction > maxReduction) {
        bestSplit = i;  maxReduction = eReduction;
      }
    }
    return bestSplit == -1
            ? Split.impossible(Utils.maxIndex(dist,_random))
            : Split.split(col,bestSplit,maxReduction);
  }
900738
public static <T, U> JavaPairRDD<T, U>[] balancedRandomSplit(int totalObjectCount, int numObjectsPerSplit,
                    JavaPairRDD<T, U> data) {
        return balancedRandomSplit(totalObjectCount, numObjectsPerSplit, data, new Random().nextLong());
    }
756883
private void setInitialPartitions(double[][] pointArray, int k) {
		if (pointArray.length < k) {
			System.err.println("cannot cluster less than k points into k clusters...");
			System.exit(0);
		}
		
		// select randomly k initial means
		// TODO: choose more stable initialization (comment: this is run several times (with different random seeds), i.e. the worst case should not occur)
        Random random = new Random(randomSeed);
		TreeSet<Integer> usedPoints = new TreeSet<Integer>();
		int nextIndex;
		for (int i = 0; i < k; i++) {
			nextIndex = ((Double)(Math.floor(random.nextDouble() * n))).intValue();
			if (usedPoints.contains(nextIndex)) {
				i--;
				continue;
			} else {
				for (int d = 0; d < dim; d++) {
					clusterMeans[i][d] = pointArray[nextIndex][d];
				}
			}
		}
		
		// set pCgivenX=1 for the closest C for each point
		int minDistIndex = 0;
		double minDist, currentDist;
		for (int x = 0; x < pointArray.length; x++) {
			minDist = Double.MAX_VALUE;
			for (int i = 0; i < k; i++) {
				currentDist = euclideanDistance(clusterMeans[i], pointArray[x]);
				if (currentDist < minDist) {
					minDist = currentDist;
					minDistIndex = i;
				}
			}
			pCgivenX[minDistIndex][x] = 1.0;
		}
	}
505274
private Node buildNode(double[][] data, int begin, int end) {
        int d = data[0].length;

        // Allocate the node
        Node node = new Node(d);

        // Fill in basic info
        node.count = end - begin;
        node.index = begin;

        // Calculate the bounding box
        double[] lowerBound = new double[d];
        double[] upperBound = new double[d];

        for (int i = 0; i < d; i++) {
            lowerBound[i] = data[index[begin]][i];
            upperBound[i] = data[index[begin]][i];
        }

        for (int i = begin + 1; i < end; i++) {
            for (int j = 0; j < d; j++) {
                double c = data[index[i]][j];
                if (lowerBound[j] > c) {
                    lowerBound[j] = c;
                }
                if (upperBound[j] < c) {
                    upperBound[j] = c;
                }
            }
        }

        // Calculate bounding box stats
        double maxRadius = -1;
        int splitIndex = -1;
        for (int i = 0; i < d; i++) {
            node.center[i] = (lowerBound[i] + upperBound[i]) / 2;
            node.radius[i] = (upperBound[i] - lowerBound[i]) / 2;
            if (node.radius[i] > maxRadius) {
                maxRadius = node.radius[i];
                splitIndex = i;
            }
        }

        // If the max spread is 0, make this a leaf node
        if (maxRadius < 1E-10) {
            node.lower = node.upper = null;
            System.arraycopy(data[index[begin]], 0, node.sum, 0, d);

            if (end > begin + 1) {
                int len = end - begin;
                for (int i = 0; i < d; i++) {
                    node.sum[i] *= len;
                }
            }

            node.cost = 0;
            return node;
        }

        // Partition the data around the midpoint in this dimension. The
        // partitioning is done in-place by iterating from left-to-right and
        // right-to-left in the same way that partioning is done in quicksort.
        double splitCutoff = node.center[splitIndex];
        int i1 = begin, i2 = end - 1, size = 0;
        while (i1 <= i2) {
            boolean i1Good = (data[index[i1]][splitIndex] < splitCutoff);
            boolean i2Good = (data[index[i2]][splitIndex] >= splitCutoff);

            if (!i1Good && !i2Good) {
                int temp = index[i1];
                index[i1] = index[i2];
                index[i2] = temp;
                i1Good = i2Good = true;
            }

            if (i1Good) {
                i1++;
                size++;
            }

            if (i2Good) {
                i2--;
            }
        }

        // Create the child nodes
        node.lower = buildNode(data, begin, begin + size);
        node.upper = buildNode(data, begin + size, end);

        // Calculate the new sum and opt cost
        for (int i = 0; i < d; i++) {
            node.sum[i] = node.lower.sum[i] + node.upper.sum[i];
        }

        double[] mean = new double[d];
        for (int i = 0; i < d; i++) {
            mean[i] = node.sum[i] / node.count;
        }

        node.cost = getNodeCost(node.lower, mean) + getNodeCost(node.upper, mean);
        return node;
    }
1089218
function (options) {
		var ret,
			series = this.series,
			pointArrayMap = series.pointArrayMap || ['y'],
			valueCount = pointArrayMap.length,
			firstItemType,
			i = 0,
			j = 0;

		if (typeof options === 'number' || options === null) {
			ret = { y: options };

		} else if (isArray(options)) {
			ret = {};
			// with leading x value
			if (options.length > valueCount) {
				firstItemType = typeof options[0];
				if (firstItemType === 'string') {
					ret.name = options[0];
				} else if (firstItemType === 'number') {
					ret.x = options[0];
				}
				i++;
			}
			while (j < valueCount) {
				ret[pointArrayMap[j++]] = options[i++];
			}			
		} else if (typeof options === 'object') {
			ret = options;

			// This is the fastest way to detect if there are individual point dataLabels that need 
			// to be considered in drawDataLabels. These can only occur in object configs.
			if (options.dataLabels) {
				series._hasPointLabels = true;
			}

			// Same approach as above for markers
			if (options.marker) {
				series._hasPointMarkers = true;
			}
		}
		return ret;
	}
979504
function chooseInitialCenters(points) {

    // Convert to list for indexed access. Make it unmodifiable, since removal of items
    // would screw up the logic of this method.
    var pointList = points;
    // The number of points in the list.
    var numPoints = pointList.length;

    // Set the corresponding element in this array to indicate when
    // elements of pointList are no longer available.
    var taken = new Array(numPoints);
    for (var i = 0; i < taken.length; i++) {
      taken[i] = false;
    }

    // The resulting list of initial centers.
    var resultSet = [];

    // Choose one center uniformly at random from among the data points.
    var firstPointIndex = nextInt(numPoints);
    var firstPoint = pointList[firstPointIndex];
    resultSet.push(new CentroidCluster(firstPoint));
    // Must mark it as taken
    taken[firstPointIndex] = true;

    // To keep track of the minimum distance squared of elements of
    // pointList to elements of resultSet.

    var minDistSquared = new Float32Array(numPoints);

    // Initialize the elements.  Since the only point in resultSet is firstPoint,
    // this is very easy.
    for (var i = 0; i < numPoints; i++) {
      if (i !== firstPointIndex) { // That point isn't considered
        var d = distance(firstPoint, pointList[i]);
        minDistSquared[i] = d * d;
      }
    }

    while (resultSet.length < k) {
      // Sum up the squared distances for the points in pointList not
      // already taken.
      var distSqSum = 0.0;

      for (var i = 0; i < numPoints; i++) {
        if (!taken[i]) {
          distSqSum += minDistSquared[i];
        }
      }

      // Add one new data point as a center. Each point x is chosen with
      // probability proportional to D(x)2
      var r = nextDouble() * distSqSum;

      // The index of the next point to be added to the resultSet.
      var nextPointIndex = -1;

      // Sum through the squared min distances again, stopping when
      // sum >= r.
      var sum = 0.0;
      for (var i = 0; i < numPoints; i++) {
        if (!taken[i]) {
          sum += minDistSquared[i];
          if (sum >= r) {
            nextPointIndex = i;
            break;
          }
        }
      }

      // If it's not set to >= 0, the point wasn't found in the previous
      // for loop, probably because distances are extremely small.  Just pick
      // the last available point.
      if (nextPointIndex === -1) {
        for (var i = numPoints - 1; i >= 0; i--) {
          if (!taken[i]) {
            nextPointIndex = i;
            break;
          }
        }
      }

      // We found one.
      if (nextPointIndex >= 0) {

        var p = pointList[nextPointIndex];

        resultSet.push(new CentroidCluster(p));

        // Mark it as taken.
        taken[nextPointIndex] = true;

        if (resultSet.length < k) {
          // Now update elements of minDistSquared.  We only have to compute
          // the distance to the new center to do this.
          for (var j = 0; j < numPoints; j++) {
            // Only have to worry about the points still not taken.
            if (!taken[j]) {
              var d = distance(p, pointList[j]);
              var d2 = d * d;
              if (d2 < minDistSquared[j]) {
                minDistSquared[j] = d2;
              }
            }
          }
        }

      } else {
        // None found --
        // Break from the while loop to prevent
        // an infinite loop.
        break;
      }
    }
    return resultSet;
  }
517349
public org.apache.hadoop.mapred.InputSplit[]
        getSplits(JobConf job, int numSplits) throws IOException {
        try {

            String oper = AerospikeConfigUtil.getInputOperation(job);
            String host = AerospikeConfigUtil.getInputHost(job);
            int port = AerospikeConfigUtil.getInputPort(job);
            String namespace = AerospikeConfigUtil.getInputNamespace(job);
            String setName = AerospikeConfigUtil.getInputSetName(job);
            String[] binNames = AerospikeConfigUtil.getInputBinNames(job);
            String numrangeBin = "";
            long numrangeBegin = 0;
            long numrangeEnd = 0;
            if (oper.equals("numrange")) {
                numrangeBin = AerospikeConfigUtil.getInputNumRangeBin(job);
                numrangeBegin = AerospikeConfigUtil.getInputNumRangeBegin(job);
                numrangeEnd = AerospikeConfigUtil.getInputNumRangeEnd(job);
            }
            
            log.info(String.format("using: %s %d %s %s",
                                   host, port, namespace, setName));

            AerospikeClient client =
                AerospikeClientSingleton.getInstance(new ClientPolicy(),
                                                     host, port);
            Node[] nodes = client.getNodes();
            int nsplits = nodes.length;
            if (nsplits == 0) {
                throw new IOException("no Aerospike nodes found");
            }
            log.info(String.format("found %d nodes", nsplits));
            AerospikeSplit[] splits = new AerospikeSplit[nsplits];
            for (int ii = 0; ii < nsplits; ii++) {
                Node node = nodes[ii];
                String nodeName = node.getName();

                // We want to avoid 127.0.0.1 as a hostname
                // because this value will be transferred to a
                // different hadoop node to be processed.
                //
                Host[] aliases = node.getAliases();
                Host nodehost = aliases[0];
                if (aliases.length > 1) {
                    for (int jj = 0; jj < aliases.length; ++jj) {
                        if (!aliases[jj].name.equals("127.0.0.1")) {
                            nodehost = aliases[jj];
                            break;
                        }
                    }
                }
                splits[ii] = new AerospikeSplit(oper, nodeName,
                                                nodehost.name, nodehost.port,
                                                namespace, setName, binNames,
                                                numrangeBin, numrangeBegin,
                                                numrangeEnd);
                log.info("split: " + splits[ii]);
            }
            return splits;
        }
        catch (Exception ex) {
            throw new IOException("exception in getSplits", ex);
        }
    }
162353
void unionTreeCoreset(int k,int n_1,int n_2,int d, Point[] setA,Point[] setB, Point[] centres, MTRandom clustererRandom) {
		//printf("Computing coreset...\n");
		//total number of points
		int n = n_1+n_2;

		//choose the first centre (each point has the same probability of being choosen)
		
		//stores, how many centres have been choosen yet
		int choosenPoints = 0; 
		
		//only choose from the n-i points not already choosen
		int j = clustererRandom.nextInt(n-choosenPoints); 

		//copy the choosen point
		if(j < n_1){
			//copyPointWithoutInit(&setA[j],&centres[choosenPoints]);
			centres[choosenPoints] = setA[j].clone();
		} else {
			j = j - n_1;
			//copyPointWithoutInit(&setB[j],&centres[choosenPoints]);
			centres[choosenPoints] = setB[j].clone();
		}
		treeNode root = new treeNode(setA,setB,n_1,n_2, centres[choosenPoints],choosenPoints); //??
		choosenPoints = 1;
		
		//choose the remaining points
		while(choosenPoints < k){
			if(root.cost > 0.0){
				treeNode leaf = selectNode(root, clustererRandom);
				Point centre = chooseCentre(leaf, clustererRandom);
				split(leaf,centre,choosenPoints);
				//copyPointWithoutInit(centre,&centres[choosenPoints]);
				centres[choosenPoints] = centre;
			} else {
				//create a dummy point
				//copyPointWithoutInit(root.centre,&centres[choosenPoints]);
				centres[choosenPoints] = root.centre;
				int l;
				for(l=0;l<root.centre.dimension;l++){
					centres[choosenPoints].coordinates[l] = -1 * 1000000;
				}
				centres[choosenPoints].id = -1;
				centres[choosenPoints].weight = 0.0;
				centres[choosenPoints].squareSum = 0.0;
			}
			
			choosenPoints++;
		}

		//free the tree
		freeTree(root);

		//recalculate clustering features
		int i;
		for(i=0;i<n;i++){
				
			if(i < n_1) {
				
				int index = setA[i].centreIndex;
				if(centres[index].id != setA[i].id){
					centres[index].weight += setA[i].weight;
					centres[index].squareSum += setA[i].squareSum;
					int l;
					for(l=0;l<centres[index].dimension;l++){
						if(setA[i].weight != 0.0){
							centres[index].coordinates[l] += setA[i].coordinates[l];
						}
					}
				}
			} else {
				
				int index = setB[i-n_1].centreIndex;
				if(centres[index].id != setB[i-n_1].id){
					centres[index].weight += setB[i-n_1].weight;
					centres[index].squareSum += setB[i-n_1].squareSum;
					int l;
					for(l=0;l<centres[index].dimension;l++){
						if(setB[i-n_1].weight != 0.0){
							centres[index].coordinates[l] += setB[i-n_1].coordinates[l];
						}
					}
				}
			}
		}
	}
805993
private void divide(int[] idx, double[] data, ArrayList<int[]> ret, int start, int end, int depth) {
    if(depth == 0) {
      int[] a = Arrays.copyOfRange(idx, start, end);
      Arrays.sort(a);
      ret.add(a);
      return;
    }
    final int count = end - start;
    if(count == 0) {
      // Corner case, that should barely happen. But for ties, we currently
      // Do not yet assure that it doesn't happen!
      for(int j = 1 << depth; j > 0; --j) {
        ret.add(new int[0]);
      }
      return;
    }
    double m = 0.;
    for(int i = start; i < end; i++) {
      m += data[i];
    }
    m /= count;
    int pos = Arrays.binarySearch(data, start, end, m);
    if(pos >= 0) {
      // Ties: try to choose the most central element.
      final int opt = (start + end) >> 1;
      while(data[pos] == m) {
        if(pos < opt) {
          pos++;
        }
        else if(pos > opt) {
          pos--;
        }
        else {
          break;
        }
      }
    }
    else {
      pos = (-pos - 1);
    }
    divide(idx, data, ret, start, pos, depth - 1);
    divide(idx, data, ret, pos, end, depth - 1);
  }
289017
public static INDArray buildFromData(List<DataPoint> data) {
        INDArray ret = Nd4j.create(data.size(), data.get(0).getD());
        for (int i = 0; i < ret.slices(); i++)
            ret.putSlice(i, data.get(i).getPoint());
        return ret;
    }
866567
private void init(final Map<DistributedDataSetPartition, InputSplit[]> splitsPerPartition) {
    final Pair<InputSplit[], DistributedDataSetPartition[]>
                                      splitsAndPartitions = getSplitsAndPartitions(splitsPerPartition);
    final InputSplit[] splits = splitsAndPartitions.getFirst();
    final DistributedDataSetPartition[] partitions = splitsAndPartitions.getSecond();
    Validate.isTrue(splits.length == partitions.length);
    for (int splitNum = 0; splitNum < splits.length; splitNum++) {
      LOG.log(Level.FINE, "Processing split: " + splitNum);
      final InputSplit split = splits[splitNum];
      final NumberedSplit<InputSplit> numberedSplit = new NumberedSplit<>(split, splitNum,
          partitions[splitNum]);
      unallocatedSplits.add(numberedSplit);
      updateLocations(numberedSplit);
    }
    if (LOG.isLoggable(Level.FINE)) {
      for (final Map.Entry<String, BlockingQueue<NumberedSplit<InputSplit>>> locSplit : locationToSplits.entrySet()) {
        LOG.log(Level.FINE, locSplit.getKey() + ": " + locSplit.getValue().toString());
      }
    }
  }
86169
def split(self, spike_ids=None, spike_clusters_rel=0):
        """"""
        if spike_ids is None:
            spike_ids = self.emit('request_split', single=True)
            spike_ids = np.asarray(spike_ids, dtype=np.int64)
            assert spike_ids.dtype == np.int64
            assert spike_ids.ndim == 1
        if len(spike_ids) == 0:
            msg = ("You first need to select spikes in the feature "
                   "view with a few Ctrl+Click around the spikes "
                   "that you want to split.")
            self.emit('error', msg)
            return
        self.clustering.split(spike_ids,
                              spike_clusters_rel=spike_clusters_rel)
        self._global_history.action(self.clustering)
903445
public void split() {
    if(hasChildren()) {
      return;
    }

    final boolean issplit = (maxSplitDimension >= (getDimensionality() - 1));
    final int childLevel = issplit ? level + 1 : level;
    final int splitDim = issplit ? 0 : maxSplitDimension + 1;
    final double splitPoint = getMin(splitDim) + (getMax(splitDim) - getMin(splitDim)) * .5;

    // left and right child
    for(int i = 0; i < 2; i++) {
      double[] min = SpatialUtil.getMin(this); // clone
      double[] max = SpatialUtil.getMax(this); // clone

      // right child
      if(i == 0) {
        min[splitDim] = splitPoint;
      }
      // left child
      else {
        max[splitDim] = splitPoint;
      }

      ModifiableDBIDs childIDs = split.determineIDs(getIDs(), new HyperBoundingBox(min, max), d_min, d_max);
      if(childIDs != null) {
        // right child
        if(i == 0) {
          rightChild = new CASHInterval(min, max, split, childIDs, splitDim, childLevel, d_min, d_max);
        }
        // left child
        else {
          leftChild = new CASHInterval(min, max, split, childIDs, splitDim, childLevel, d_min, d_max);
        }
      }
    }

    if(LOG.isDebuggingFine()) {
      StringBuilder msg = new StringBuilder();
      msg.append("Child level ").append(childLevel).append(",  split Dim   ").append(splitDim);
      if(leftChild != null) {
        msg.append("\nleft   ").append(leftChild);
      }
      if(rightChild != null) {
        msg.append("\nright   ").append(rightChild);
      }
      LOG.fine(msg.toString());
    }
  }
122597
function split(separator, data, limit) {
	var data = ""+data,
	    results = data.split(separator);
	if(!limit) return results;
	if(results.length <= limit) return results;
	var separators = data.match(new RegExp(separator.source, "g"));
	results[limit-1] = join(results.slice(limit-1), separators.slice(limit-1));
	results.length = limit;
	return results;
}