docs: public Clustering<Model> run(Database database, Relation<V> relation) {
      // current dimensionality associated with each seed
      int dim_c = RelationUtil.dimensionality(relation);
  
      if(dim_c < l) {
        throw new IllegalStateException("Dimensionality of data < parameter l! " + "(" + dim_c + " < " + l + ")");
      }
  
      // current number of seeds
      int k_c = Math.min(relation.size(), k_i * k);
  
      // pick k0 > k points from the database
      List<ORCLUSCluster> clusters = initialSeeds(relation, k_c);
  
      double beta = FastMath.exp(-FastMath.log(dim_c / (double) l) * FastMath.log(1 / alpha) / FastMath.log(k_c / (double) k));
  
      IndefiniteProgress cprogress = LOG.isVerbose() ? new IndefiniteProgress("Current number of clusters:", LOG) : null;
  
      while(k_c > k) {
        // find partitioning induced by the seeds of the clusters
        assign(relation, clusters);
  
        // determine current subspace associated with each cluster
        for(ORCLUSCluster cluster : clusters) {
          if(cluster.objectIDs.size() > 0) {
            cluster.basis = findBasis(relation, cluster, dim_c);
          }
        }
  
        // reduce number of seeds and dimensionality associated with
        // each seed
        k_c = (int) Math.max(k, k_c * alpha);
        dim_c = (int) Math.max(l, dim_c * beta);
        merge(relation, clusters, k_c, dim_c, cprogress);
        if(cprogress != null) {
          cprogress.setProcessed(clusters.size(), LOG);
        }
      }
      assign(relation, clusters);
  
      LOG.setCompleted(cprogress);
  
      // get the result
      Clustering<Model> r = new Clustering<>("ORCLUS clustering", "orclus-clustering");
      for(ORCLUSCluster c : clusters) {
        r.addToplevelCluster(new Cluster<Model>(c.objectIDs, ClusterModel.CLUSTER));
      }
      return r;
    }