Source:
private GmmModel init(Dataset<EmptyContext, GmmPartitionData> dataset) { try { if (initialMeans == null) { List<List<Vector>> randomMeansSets = Stream.of(dataset.compute( selectNRandomXsMapper(countOfComponents), GmmTrainer::selectNRandomXsReducer )).map(Arrays::asList).collect(Collectors.toList()); A.ensure( randomMeansSets.stream().mapToInt(List::size).sum() >= countOfComponents, "There is not enough data in dataset for select N random means" ); initialMeans = new Vector[countOfComponents]; int j = 0; for (int i = 0; i < countOfComponents; ) { List<Vector> randomMeansPart = randomMeansSets.get(j); if (!randomMeansPart.isEmpty()) { initialMeans[i] = randomMeansPart.remove(0); i++; } j = (j + 1) % randomMeansSets.size(); } } dataset.compute(data -> GmmPartitionData.estimateLikelihoodClusters(data, initialMeans)); List<Matrix> initialCovs = CovarianceMatricesAggregator.computeCovariances( dataset, VectorUtils.of(DoubleStream.generate(() -> 1. / countOfComponents).limit(countOfComponents).toArray()), initialMeans ); List<MultivariateGaussianDistribution> distributions = new ArrayList<>(); for (int i = 0; i < countOfComponents; i++) distributions.add(new MultivariateGaussianDistribution(initialMeans[i], initialCovs.get(i))); return new GmmModel( VectorUtils.of(DoubleStream.generate(() -> 1. / countOfComponents).limit(countOfComponents).toArray()), distributions ); } catch (SingularMatrixException | IllegalArgumentException e) { String msg = "Cannot construct non-singular covariance matrix by data. " + "Try to select other initial means or other model trainer"; environment.logger().log(MLLogger.VerboseLevel.HIGH, msg); throw new RuntimeException(msg, e); } }

Target:
private Optional<GmmModel> init(Dataset<EmptyContext, GmmPartitionData> dataset) { int countOfTries = 0; while (true) { try { if (initialMeans == null) { List<List<Vector>> randomMeansSets = Stream.of(dataset.compute( selectNRandomXsMapper(countOfComponents), GmmTrainer::selectNRandomXsReducer )).map(this::asList).collect(Collectors.toList()); A.ensure( randomMeansSets.stream().mapToInt(List::size).sum() >= countOfComponents, "There is not enough data in dataset for select N random means" ); initialMeans = new Vector[countOfComponents]; int j = 0; for (int i = 0; i < countOfComponents; ) { List<Vector> randomMeansPart = randomMeansSets.get(j); if (!randomMeansPart.isEmpty()) { initialMeans[i] = randomMeansPart.remove(0); i++; } j = (j + 1) % randomMeansSets.size(); } } dataset.compute(data -> GmmPartitionData.estimateLikelihoodClusters(data, initialMeans)); List<Matrix> initialCovs = CovarianceMatricesAggregator.computeCovariances( dataset, VectorUtils.fill(1. / countOfComponents, countOfComponents), initialMeans ); if (initialCovs.isEmpty()) return Optional.empty(); List<MultivariateGaussianDistribution> distributions = new ArrayList<>(); for (int i = 0; i < countOfComponents; i++) distributions.add(new MultivariateGaussianDistribution(initialMeans[i], initialCovs.get(i))); return Optional.of(new GmmModel( VectorUtils.of(DoubleStream.generate(() -> 1. / countOfComponents).limit(countOfComponents).toArray()), distributions )); } catch (SingularMatrixException | IllegalArgumentException e) { String msg = "Cannot construct non-singular covariance matrix by data. " + "Try to select other initial means or other model trainer [number of tries = " + countOfTries + "]"; environment.logger().log(MLLogger.VerboseLevel.HIGH, msg); countOfTries += 1; initialMeans = null; if (countOfTries >= maxCountOfInitTries) throw new RuntimeException(msg, e); } } }