docs: @Override
    public void computeDensityEstimator() {
      // Compute scalarization values
      this.scalWrapper.execute(getSolutionList());
      scaleToPositive();
  
      // Distance matrix
      double[][] distanceMatrix;
      if (normalizeObjectives) {
        FrontNormalizer normalizer = new FrontNormalizer(getSolutionList());
        distanceMatrix = SolutionListUtils.distanceMatrix(normalizer.normalize(getSolutionList()));
      } else
        distanceMatrix = SolutionListUtils.distanceMatrix(getSolutionList());
  
      // Set fitness based on replacement strategy
      double[] energyVector = energyVector(distanceMatrix);
      double[] replacementVector = replacementVector(distanceMatrix);
      // Flag for memorizing whether solution can improve archive
      boolean eligible = false;
      for (int i = 0; i < replacementVector.length; i++) {
        // New solution is better than incumbent
        if (replacementVector[i] < energyVector[i]) {
          eligible = true;
          switch (replacementStrategy) {
            case BEST_FEASIBLE_POSITION:
              // Energy decrease is maximal if replacement energy is
              // minimized. This is why the the negated entry in
              // replacementVector is the corresponding fitness.
              fitness.setAttribute(archive.get(i), -replacementVector[i]);
              break;
            case LARGEST_DIFFERENCE:
              fitness.setAttribute(archive.get(i), energyVector[i]);
              break;
            case WORST_IN_ARCHIVE:
              fitness.setAttribute(archive.get(i), energyVector[i] - replacementVector[i]);
              break;
          }
        } else {
          // If archive member is not eligible for replacement, make sure
          // it is retained in any case.
          archive.get(i).setAttribute(fitness.getAttributeIdentifier(), -Double.MAX_VALUE);
        }
        if (eligible) {
          // New solution is always retained
          fitness.setAttribute(archive.get(maxSize), -Double.MAX_VALUE);
        } else {
          // New solution is rejected in any case
          fitness.setAttribute(archive.get(maxSize), Double.MAX_VALUE);
        }
      }
    }