@Override
  public MetaData getGeneratedMetaData() throws OperatorException {
    ExampleSetMetaData emd = new ExampleSetMetaData();
    AttributeMetaData amd = new AttributeMetaData("label", Ontology.NOMINAL, Attributes.LABEL_NAME);
    emd.addAttribute(amd);
    int desirendNumberOfAttributes = getParameterAsInt(PARAMETER_NUMBER_ATTRIBUTES);
    double mean = getParameterAsDouble(PARAMETER_SPARSE_FRACTION);
    if (desirendNumberOfAttributes > 20) {
      emd.attributesAreSuperset();
      // first ten
      for (int i = 1; i < 11; i++) {
        AttributeMetaData newAMD = new AttributeMetaData("att" + i, Ontology.REAL);
        newAMD.setValueRange(new Range(0, 1), SetRelation.EQUAL);
        newAMD.setMean(new MDReal(mean));
        emd.addAttribute(newAMD);
      }
      // last ten
      for (int i = desirendNumberOfAttributes - 10; i <= desirendNumberOfAttributes; i++) {
        AttributeMetaData newAMD = new AttributeMetaData("att" + i, Ontology.REAL);
        newAMD.setValueRange(new Range(0, 1), SetRelation.EQUAL);
        newAMD.setMean(new MDReal(mean));
        emd.addAttribute(newAMD);
      }

    } else {
      for (int i = 0; i < desirendNumberOfAttributes; i++) {
        AttributeMetaData newAMD = new AttributeMetaData("att" + (i + 1), Ontology.REAL);
        newAMD.setValueRange(new Range(0, 1), SetRelation.EQUAL);
        newAMD.setMean(new MDReal(mean));
        emd.addAttribute(newAMD);
      }
    }
    return emd;
  }
 @Override
 protected ExampleSetMetaData modifyMetaData(ExampleSetMetaData exampleSetMetaData)
     throws UndefinedParameterError {
   AttributeMetaData label = exampleSetMetaData.getLabelMetaData();
   if (label != null) {
     if (label.isNumerical() && getParameterAsDouble(PARAMETER_LABEL_NOISE) > 0) {
       label.setValueSetRelation(SetRelation.SUPERSET);
     }
   }
   double defaultNoise = getParameterAsDouble(PARAMETER_DEFAULT_ATTRIBUTE_NOISE);
   if (defaultNoise > 0) {
     for (AttributeMetaData amd : exampleSetMetaData.getAllAttributes()) {
       if (!amd.isSpecial()) {
         if (amd.isNumerical()) {
           amd.setValueSetRelation(SetRelation.SUPERSET);
         }
       }
     }
   }
   int numberOfRandomAttributes = getParameterAsInt(PARAMETER_RANDOM_ATTRIBUTES);
   for (int i = 0; i < numberOfRandomAttributes; i++) {
     AttributeMetaData amd =
         new AttributeMetaData("random" + ((i == 0) ? "" : i + ""), Ontology.REAL);
     amd.setValueRange(
         new Range(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY), SetRelation.SUBSET);
     exampleSetMetaData.addAttribute(amd);
   }
   return exampleSetMetaData;
 }
 @Override
 protected MetaData modifyMetaData(ExampleSetMetaData metaData) {
   AttributeMetaData weightAttribute =
       new AttributeMetaData(Attributes.WEIGHT_NAME, Ontology.REAL, Attributes.WEIGHT_NAME);
   weightAttribute.setValueRange(getWeightAttributeRange(), getWeightAttributeValueRelation());
   metaData.addAttribute(weightAttribute);
   return metaData;
 }
  @Override
  public ExampleSetMetaData applyOnFilteredMetaData(ExampleSetMetaData metaData) {
    for (AttributeMetaData amd : metaData.getAllAttributes()) {
      if (amd.isNumerical() && !amd.isSpecial()) {
        Range range = amd.getValueRange();
        amd.setValueRange(
            new Range(0, Math.max(Math.abs(range.getLower()), Math.abs(range.getUpper()))),
            amd.getValueSetRelation());
        amd.getMean().setUnkown();
      }
    }

    return metaData;
  }
  @Override
  public ExampleSetMetaData applyOnFilteredMetaData(ExampleSetMetaData emd) {
    boolean round = getParameterAsBoolean(PARAMETER_ROUND);

    for (AttributeMetaData amd : emd.getAllAttributes()) {
      if ((Ontology.ATTRIBUTE_VALUE_TYPE.isA(amd.getValueType(), Ontology.NUMERICAL))
          && (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(amd.getValueType(), Ontology.INTEGER))) {
        amd.setType(Ontology.INTEGER);
      }
      if (round) {
        amd.setValueRange(
            new Range(
                Math.round(amd.getValueRange().getLower()),
                Math.round(amd.getValueRange().getUpper())),
            SetRelation.EQUAL);
      } else {
        amd.setValueRange(
            new Range((long) amd.getValueRange().getLower(), (long) amd.getValueRange().getUpper()),
            SetRelation.EQUAL);
      }
    }
    return emd;
  }