private double[] mutate(CMAParamSet params, double[] x, double[][] range, int count) {
   int dim = range.length;
   if (!Mathematics.isInRange(params.meanX, range)) { // TODO Im not sure why this can happen...
     System.err.println("Error in MutateESRankMuCMA.mutate !");
     Mathematics.projectToRange(params.meanX, range);
   }
   //		System.out.println("--- In mutate!");
   if (params != null && (params.firstAdaptionDone)) {
     double[] sampl = new double[dim]; // generate scaled random vector (D * z)
     for (int i = 0; i < dim; ++i) {
       sampl[i] = Math.sqrt(params.eigenvalues[i]) * RNG.gaussianDouble(1.);
       if (Double.isNaN(sampl[i])) sampl[i] = 0;
     }
     //			System.out.println("Sampling around " + BeanInspector.toString(meanX));
     /* add mutation (sigma * B * (D*z)) */
     addMutationStep(params, x, sampl);
     int cnt = 0;
     while (!Mathematics.isInRange(x, range)) {
       //			     % You may handle constraints here. You may either resample
       //			    % arz(:,k) and/or multiply it with a factor between -1 and 1
       //			    % (the latter will decrease the overall step size) and
       //			    % recalculate arx accordingly. Do not change arx or arz in any
       //			    % other way.
       // multiply sampl by a no in [-1,1] and try again
       double r; // actually we use [-1,-0.5] or [0.5, 1]
       cnt++;
       if (cnt > 10 * x.length) {
         // well... lets give it up. Probably the meanX is close to the bounds in several
         // dimensions
         // which is unlikely to be solved by random sampling.
         //					if (!Mathematics.isInRange(params.meanX, range)) {
         //						System.err.println("Error in MutateESRankMuCMA.mutate !"); break;
         //					}
         r = 0;
       } else {
         r = RNG.randomDouble(-0.5, 0.5);
         if (Math.abs(r) < 0.5) r += Math.signum(r) * 0.5; // r is in [-1,-0.5] or [0.5,1]
       }
       //				System.out.println("Reducing step by " + r + " for " +
       // BeanInspector.toString(params.meanX));
       Mathematics.svMult(r, sampl, sampl);
       addMutationStep(params, x, sampl);
     }
   } else {
     if (params == null) {
       System.err.println(
           "Error in MutateESRankMuCMA: parameter set was null! Skipping mutation...");
     } // no valid meanX yet, so just do a gaussian jump with sigma
     for (int i = 0; i < dim; ++i) {
       x[i] += RNG.gaussianDouble(getSigma(params, i));
       checkValidDouble(x[i]);
     }
   }
   if (!Mathematics.isInRange(params.meanX, range)) {
     System.err.println("Error B in MutateESRankMuCMA.mutate !");
   }
   if (TRACE_1) System.out.println("mutated indy: " + BeanInspector.toString(x));
   return x;
 }
  private double[] mutateOrig(CMAParamSet params, double[] x, double[][] range, int count) {
    int dim = range.length;
    int maxRetries;

    if (checkRange) maxRetries = 100 * dim;
    else maxRetries = 0; // take the first sample, not matter in or out of range
    do { // this is a loop in case that the range needs to be checked and the current sampling fails
         // to keep the range
      if (params != null && (params.firstAdaptionDone)) {
        double[] sampl = new double[dim]; // generate scaled random vector (D * z)
        for (int i = 0; i < dim; ++i) {
          sampl[i] = Math.sqrt(params.eigenvalues[i]) * RNG.gaussianDouble(1.);
          if (Double.isNaN(sampl[i])) sampl[i] = 0;
        }
        //			System.out.println("Sampling around " + BeanInspector.toString(meanX));
        /* add mutation (sigma * B * (D*z)) */
        for (int i = 0; i < dim; ++i) {
          double sum = 0.;
          for (int j = 0; j < dim; ++j) sum += params.mB.get(i, j) * sampl[j];
          x[i] = params.meanX[i] + getSigma(params, i) * sum;
          checkValidDouble(x[i]);
        }
      } else {
        if (params == null) {
          System.err.println(
              "Error in MutateESRankMuCMA: parameter set was null! Skipping mutation...");
        } // no valid meanX yet, so just do a gaussian jump with sigma
        for (int i = 0; i < dim; ++i) {
          x[i] += RNG.gaussianDouble(getSigma(params, i));
          checkValidDouble(x[i]);
        }
      }
    } while ((maxRetries--) > 0 && !(Mathematics.isInRange(x, range)));
    if (checkRange && !(Mathematics.isInRange(x, range)))
      return repairMutation(x, range); // allow some nice tries before using brute force
    else return x;
  }