docs: protected void optimizeSNE(AffinityMatrix pij, double[][] sol) {
      final int size = pij.size();
      if(size * 3L * dim > 0x7FFF_FFFAL) {
        throw new AbortException("Memory exceeds Java array size limit.");
      }
      // Meta information on each point; joined for memory locality.
      // Gradient, Momentum, and learning rate
      // For performance, we use a flat memory layout!
      double[] meta = new double[size * 3 * dim];
      final int dim3 = dim * 3;
      for(int off = 2 * dim; off < meta.length; off += dim3) {
        Arrays.fill(meta, off, off + dim, 1.); // Initial learning rate
      }
      // Affinity matrix in projected space
      double[][] qij = new double[size][size];
  
      FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("Iterative Optimization", iterations, LOG) : null;
      Duration timer = LOG.isStatistics() ? LOG.newDuration(this.getClass().getName() + ".runtime.optimization").begin() : null;
      // Optimize
      for(int it = 0; it < iterations; it++) {
        double qij_sum = computeQij(qij, sol);
        computeGradient(pij, qij, 1. / qij_sum, sol, meta);
        updateSolution(sol, meta, it);
        LOG.incrementProcessed(prog);
      }
      LOG.ensureCompleted(prog);
      if(timer != null) {
        LOG.statistics(timer.end());
      }
    }