docs: public static void recomputeCovarianceMatrices(Relation<? extends NumberVector> relation, WritableDataStore<double[]> probClusterIGivenX, List<? extends EMClusterModel<?>> models, double prior) {
      final int k = models.size();
      boolean needsTwoPass = false;
      for(EMClusterModel<?> m : models) {
        m.beginEStep();
        needsTwoPass |= m.needsTwoPass();
      }
      // First pass, only for two-pass models.
      if(needsTwoPass) {
        for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
          double[] clusterProbabilities = probClusterIGivenX.get(iditer);
          NumberVector instance = relation.get(iditer);
          for(int i = 0; i < clusterProbabilities.length; i++) {
            final double prob = clusterProbabilities[i];
            if(prob > 1e-10) {
              models.get(i).firstPassE(instance, prob);
            }
          }
        }
        for(EMClusterModel<?> m : models) {
          m.finalizeFirstPassE();
        }
      }
      double[] wsum = new double[k];
      for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
        double[] clusterProbabilities = probClusterIGivenX.get(iditer);
        NumberVector instance = relation.get(iditer);
        for(int i = 0; i < clusterProbabilities.length; i++) {
          final double prob = clusterProbabilities[i];
          if(prob > 1e-10) {
            models.get(i).updateE(instance, prob);
          }
          wsum[i] += prob;
        }
      }
      for(int i = 0; i < models.size(); i++) {
        // MLE / MAP
        final double weight = prior <= 0. ? wsum[i] / relation.size() : (wsum[i] + prior - 1) / (relation.size() + prior * k - k);
        models.get(i).finalizeEStep(weight, prior);
      }
    }