private void eidgendecomposition(CMAEvolutionaryAlgorithm algorithm, int N, int flgforce) {

    if (countCUpdatesSinceEigenupdate == 0 && flgforce < 2) {
      return;
    }

    if (!algorithm.getFlgDiag()
        && flgforce <= 0
        && countCUpdatesSinceEigenupdate < 1.0 / algorithm.getCcov() / N / 5.0) {
      return;
    }

    if (algorithm.getFlgDiag()) {
      for (int i = 0; i < N; i++) {
        algorithm.getDiag()[i] = Math.sqrt(algorithm.getC()[i][i]);
      }
      algorithm.setCountCupdatesSinceEigenupdate(0);

    } else {
      // set B <- C
      for (int i = 0; i < N; i++) {
        for (int j = 0; j <= i; j++) {
          algorithm.getB()[i][j] = algorithm.getB()[j][i] = algorithm.getC()[i][j];
        }
      }

      // eigendecomposition:
      double[] offdiag = new double[N];
      tred2(N, algorithm.getB(), algorithm.getDiag(), offdiag);
      tql2(N, algorithm.getDiag(), offdiag, algorithm.getB());
      checkEigenSystem(N, algorithm.getC(), algorithm.getDiag(), algorithm.getB());

      for (int i = 0; i < N; i++) {
        if (algorithm.getDiag()[i] < 0.0) {
          if (algorithm.isDebug()) {
            System.err.println("ERROR - An eigenvalue has become negative.");
          }
        }
        algorithm.getDiag()[i] = Math.sqrt(algorithm.getDiag()[i]);
      }
      algorithm.setCountCupdatesSinceEigenupdate(0);
    }

    /*
     * TODO: Check if necessary
     */
    if (StatUtils.min(algorithm.getDiag()) == 0.0) {
      algorithm.setAxisRatio(Double.POSITIVE_INFINITY);
    } else {
      algorithm.setAxisRatio(
          StatUtils.max(algorithm.getDiag()) / StatUtils.min(algorithm.getDiag()));
    }
  } // eigendecomposition