/**
  * Checks the type of all the fuzzy sets.
  *
  * @param l The list where the fuzzy sets are.
  * @return 1 if all discrete, 2 if all piecewise, 3 if all continuous or 0 if all the sets are not
  *     the same type.
  */
 public static int allType(LogoList l) {
   int discrete = 0;
   int piecewise = 0;
   int continuous = 0;
   // Count the type of all the fuzzy sets inside the list
   for (Object o : l) {
     FuzzySet f = (FuzzySet) o;
     if (f.isContinuous()) {
       if (f instanceof PiecewiseLinearSet) {
         piecewise++;
       }
       continuous++;
     } else {
       discrete++;
     }
   }
   // If all the sets of the list are discrete return 1
   if (discrete == l.size()) {
     return 1;
   }
   // If all the sets of the list are piecewise return 2
   // Check first piecewise linear cause piecewise linear is also
   // continuous
   if (piecewise == l.size()) {
     return 2;
   }
   // If all the sets of the list are continuous return 3
   if (continuous == l.size()) {
     return 3;
   }
   // If the sets are mixed return 0;
   return 0;
 }
 /**
  * Calculate the parameters and the universe of continuous sets.
  *
  * @param l Logolist containing all the fuzzysets.
  * @return A tuple containing the resulting parameters(List<FuzzySet>) and the universe(double[]).
  */
 public static Tuple<FuzzySet> continuousParamsUniverse(LogoList l) {
   List<FuzzySet> params = new ArrayList<FuzzySet>();
   // Get and add the first fuzzy set
   FuzzySet f = (FuzzySet) l.first();
   params.add(f);
   // Get the universe of the first fuzzy set
   double[] universe = f.getUniverse();
   // Iterate over all the fuzzy sets
   for (int i = 1; i < l.size(); i++) {
     // Add fuzzy sets as parameters to the new set
     f = (FuzzySet) l.get(i);
     params.add(f);
     // Calculate the new universe
     universe = DegreeOfFulfillment.andInterval(universe, f.getUniverse());
   }
   return new Tuple<FuzzySet>(params, universe);
 }
 /**
  * This method respond to the call from Netlogo and returns the middle of the maximum values of a
  * fuzzy set.
  *
  * @param arg0 Arguments from Netlogo call, in this case a list.
  * @param arg1 Context of Netlogo when the call was done.
  * @return A number with the middle of maxima of the fuzzy set.
  */
 @Override
 public Object report(Argument[] arg0, Context arg1) throws ExtensionException, LogoException {
   FuzzySet f = (FuzzySet) arg0[0].get();
   double[] universe = f.getUniverse();
   double maximum = Double.NEGATIVE_INFINITY;
   double maximum2 = Double.NEGATIVE_INFINITY;
   double maxVal = Double.NEGATIVE_INFINITY;
   boolean twoMax = false;
   // If universe empty
   if (universe.length == 0) {
     new ExtensionException("You have tried to compute the FOM of an empty set");
   }
   // If continuous but not piecewise
   if (f.isContinuous() && !(f instanceof PiecewiseLinearSet)) {
     // First number to evaluate
     double x = universe[0];
     // Number of points to evaluate(Depends on resolution)
     double steps =
         Math.floor(1 + ((universe[1] - universe[0]) * SupportFunctions.getResolution()));
     double eval = 0;
     for (int i = 0; i < steps; i++) {
       eval = f.evaluate(x);
       // if bigger than the stored max value, save the x, update max
       // value and set false the two-maximum-found boolean
       if (eval > maxVal) {
         maximum = x;
         maxVal = eval;
         twoMax = false;
       } else if (eval == maxVal) { // if equal to the stored max value,
         // save the x in the second maximum
         // and set the boolean to true
         maximum2 = x;
         twoMax = true;
       }
       // Increment 1/Resolution times
       x = x + (1 / SupportFunctions.getResolution());
     }
   } else {
     PointSet ps = (PointSet) f;
     for (double[] point : ps.getParameters()) {
       double y = point[1];
       // if bigger than the stored max value, save the x, update max
       // value and set false the two-maximum-found boolean
       if (y > maxVal) {
         maximum = point[0];
         maxVal = y;
         twoMax = false;
       } else if (y == maxVal) { // if equal to the stored max value,
         // save the x in the second maximum
         // and set the boolean to true
         maximum2 = point[0];
         twoMax = true;
       }
     }
   }
   if (twoMax) {
     return (maximum + maximum2) / 2;
   } else {
     return maximum;
   }
 }