Repository: incubator-samoa
Updated Branches:
  refs/heads/master dbc3aab13 -> 26c219124


http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/Instances.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/Instances.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/Instances.java
index f7fb0d3..04fde39 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/Instances.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/Instances.java
@@ -1,9 +1,7 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
 package org.apache.samoa.instances;
 
+import java.io.InputStream;
+
 /*
  * #%L
  * SAMOA
@@ -28,56 +26,84 @@ import java.io.Reader;
 import java.io.Serializable;
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Random;
-import java.io.InputStream;
 
-/**
- * 
- * @author abifet
- */
 public class Instances implements Serializable {
 
-  public static final String ARFF_RELATION = "@relation";
-  public static final String ARFF_DATA = "@data";
+  /**
+   * The keyword used to denote the start of an arff header
+   */
+  public final static String ARFF_RELATION = "@relation";
+
+  /**
+   * The keyword used to denote the start of the arff data section
+   */
+  public final static String ARFF_DATA = "@data";
 
+  private static final long serialVersionUID = 8110510475535581577L;
+  /**
+   * The instance information.
+   */
   protected InstanceInformation instanceInformation;
   /**
    * The instances.
    */
   protected List<Instance> instances;
 
-  transient protected Loader loader;
-
   protected static enum AVRO_ENCODING_FORMAT {
     JSON, BINARY
   }
 
   protected int classAttribute;
 
-  public Instances(InstancesHeader modelContext) {
-    throw new UnsupportedOperationException("Not yet implemented");
-  }
+  /**
+   * A Hash that stores the indices of features.
+   */
+  protected HashMap<String, Integer> hsAttributesIndices;
+
+  transient protected Loader loader;
 
+  /**
+   * Instantiates a new instances.
+   *
+   * @param chunk the chunk
+   */
   public Instances(Instances chunk) {
-    this.instanceInformation = chunk.instanceInformation();
-    // this.relationName = chunk.relationName;
-    // this.attributes = chunk.attributes;
-    this.instances = chunk.instances;
+    this(chunk, chunk.numInstances());
+    chunk.copyInstances(0, this, chunk.numInstances());
   }
 
+  /**
+   * Instantiates a new instances.
+   */
   public Instances() {
-    // this.instanceInformation = chunk.instanceInformation();
-    // this.relationName = chunk.relationName;
-    // this.attributes = chunk.attributes;
-    // this.instances = chunk.instances;
   }
 
+  /**
+   * Instantiates a new instances.
+   *
+   * @param reader the reader
+   * @param size the size
+   * @param classAttribute the class attribute
+   */
   public Instances(Reader reader, int size, int classAttribute) {
-    this.classAttribute = classAttribute;
-    loader = new ArffLoader(reader, 0, classAttribute);
+    this.loader = new ArffLoader(reader, 0, classAttribute);
     this.instanceInformation = loader.getStructure();
-    this.instances = new ArrayList<>();
+    this.instances = new ArrayList<Instance>();
+  }
+
+  /**
+   * Instantiates a new instances.
+   *
+   * @param reader the reader
+   * @param range
+   */
+  public Instances(Reader reader, Range range) {
+    this.loader = new ArffLoader(reader, 0, classAttribute);//new 
MultiTargetArffLoader(reader, range);
+    this.instanceInformation = loader.getStructure();
+    this.instances = new ArrayList<Instance>();
   }
 
   public Instances(InputStream inputStream, int classAttribute, String 
encodingFormat) {
@@ -92,110 +118,337 @@ public class Instances implements Serializable {
     this.instances = new ArrayList<>();
   }
 
+  /**
+   * Instantiates a new instances.
+   *
+   * @param chunk the chunk
+   * @param capacity the capacity
+   */
   public Instances(Instances chunk, int capacity) {
-    this(chunk);
+    this.instanceInformation = chunk.instanceInformation();
+    if (capacity < 0) {
+      capacity = 0;
+    }
+    this.instances = new ArrayList<Instance>(capacity);
   }
 
+  /**
+   * Instantiates a new instances.
+   *
+   * @param st the st
+   * @param v the v
+   * @param capacity the capacity
+   */
   public Instances(String st, List<Attribute> v, int capacity) {
-
     this.instanceInformation = new InstanceInformation(st, v);
-    this.instances = new ArrayList<>();
+    this.instances = new ArrayList<Instance>(capacity);
   }
 
-  public Instances(Instances chunk, int i, int j) {
-    throw new UnsupportedOperationException("Not yet implemented");
+  /**
+   * Instantiates a new instances.
+   *
+   * @param chunk the chunk
+   * @param first the first instance
+   * @param toCopy the j
+   */
+  public Instances(Instances chunk, int first, int toCopy) {
+
+    this(chunk, toCopy);
+
+    if ((first < 0) || ((first + toCopy) > chunk.numInstances())) {
+      throw new IllegalArgumentException("Parameters first and/or toCopy out "
+          + "of range");
+    }
+    chunk.copyInstances(first, this, toCopy);
   }
 
-  public Instances(StringReader st, int v) {
-    throw new UnsupportedOperationException("Not yet implemented");
+  /**
+   * Instantiates a new instances.
+   *
+   * @param st the st
+   * @param capacity the capacity
+   */
+  public Instances(StringReader st, int capacity) {
+    this.instances = new ArrayList<Instance>(capacity);
   }
 
-  // Information Instances
+  //Information Instances
+  /**
+   * Sets the relation name.
+   *
+   * @param string the new relation name
+   */
   public void setRelationName(String string) {
     this.instanceInformation.setRelationName(string);
   }
 
+  /**
+   * Gets the relation name.
+   *
+   * @return the relation name
+   */
   public String getRelationName() {
     return this.instanceInformation.getRelationName();
   }
 
+  /**
+   * Class index.
+   *
+   * @return the int
+   */
   public int classIndex() {
     return this.instanceInformation.classIndex();
   }
 
+  /**
+   * Sets the class index.
+   *
+   * @param classIndex the new class index
+   */
   public void setClassIndex(int classIndex) {
     this.instanceInformation.setClassIndex(classIndex);
   }
 
+  /**
+   * Class attribute.
+   *
+   * @return the attribute
+   */
   public Attribute classAttribute() {
     return this.instanceInformation.classAttribute();
   }
 
+  /**
+   * Num attributes.
+   *
+   * @return the int
+   */
   public int numAttributes() {
     return this.instanceInformation.numAttributes();
   }
 
+  /**
+   * Attribute.
+   *
+   * @param w the w
+   * @return the attribute
+   */
   public Attribute attribute(int w) {
     return this.instanceInformation.attribute(w);
   }
 
+  /**
+   * Num classes.
+   *
+   * @return the int
+   */
   public int numClasses() {
     return this.instanceInformation.numClasses();
   }
 
+  /**
+   * Delete attribute at.
+   *
+   * @param integer the integer
+   */
   public void deleteAttributeAt(Integer integer) {
     this.instanceInformation.deleteAttributeAt(integer);
   }
 
+  /**
+   * Insert attribute at.
+   *
+   * @param attribute the attribute
+   * @param i the i
+   */
   public void insertAttributeAt(Attribute attribute, int i) {
+    if (this.instanceInformation == null) {
+      this.instanceInformation = new InstanceInformation();
+    }
     this.instanceInformation.insertAttributeAt(attribute, i);
   }
 
-  // List of Instances
+  //List of Instances
+  /**
+   * Instance.
+   *
+   * @param num the num
+   * @return the instance
+   */
   public Instance instance(int num) {
     return this.instances.get(num);
   }
 
+  /**
+   * Num instances.
+   *
+   * @return the int
+   */
   public int numInstances() {
     return this.instances.size();
   }
 
+  /**
+   * Adds the.
+   *
+   * @param inst the inst
+   */
   public void add(Instance inst) {
-    this.instances.add(inst.copy());
+    this.instances.add(inst);
   }
 
+  /**
+   * Randomize.
+   *
+   * @param random the random
+   */
   public void randomize(Random random) {
     for (int j = numInstances() - 1; j > 0; j--) {
       swap(j, random.nextInt(j + 1));
     }
   }
 
+  /**
+   * Stratify.
+   *
+   * @param numFolds the num folds
+   */
   public void stratify(int numFolds) {
-    throw new UnsupportedOperationException("Not yet implemented");
+
+    if (classAttribute().isNominal()) {
+
+      // sort by class
+      int index = 1;
+      while (index < numInstances()) {
+        Instance instance1 = instance(index - 1);
+        for (int j = index; j < numInstances(); j++) {
+          Instance instance2 = instance(j);
+          if ((instance1.classValue() == instance2.classValue())
+              || (instance1.classIsMissing()
+                  && instance2.classIsMissing())) {
+            swap(index, j);
+            index++;
+          }
+        }
+        index++;
+      }
+      stratStep(numFolds);
+    }
   }
 
-  public Instances trainCV(int numFolds, int n, Random random) {
-    throw new UnsupportedOperationException("Not yet implemented");
+  protected void stratStep(int numFolds) {
+    ArrayList<Instance> newVec = new 
ArrayList<Instance>(this.instances.size());
+    int start = 0, j;
+
+    // create stratified batch
+    while (newVec.size() < numInstances()) {
+      j = start;
+      while (j < numInstances()) {
+        newVec.add(instance(j));
+        j = j + numFolds;
+      }
+      start++;
+    }
+    this.instances = newVec;
   }
 
-  public Instances testCV(int numFolds, int n) {
-    throw new UnsupportedOperationException("Not yet implemented");
+  /**
+   * Train cv.
+   *
+   * @param numFolds the num folds
+   * @param numFold
+   * @param random the random
+   * @return the instances
+   */
+  public Instances trainCV(int numFolds, int numFold, Random random) {
+    Instances train = trainCV(numFolds, numFold);
+    train.randomize(random);
+    return train;
   }
 
-  /*
-   * public Instances dataset() { throw new
-   * UnsupportedOperationException("Not yet implemented"); }
+  public Instances trainCV(int numFolds, int numFold) {
+    int numInstForFold, first, offset;
+    Instances train;
+
+    numInstForFold = numInstances() / numFolds;
+    if (numFold < numInstances() % numFolds) {
+      numInstForFold++;
+      offset = numFold;
+    } else {
+      offset = numInstances() % numFolds;
+    }
+    train = new Instances(this, numInstances() - numInstForFold);
+    first = numFold * (numInstances() / numFolds) + offset;
+    copyInstances(0, train, first);
+    copyInstances(first + numInstForFold, train,
+        numInstances() - first - numInstForFold);
+    return train;
+  }
+
+  protected void copyInstances(int from, Instances dest, int num) {
+    for (int i = 0; i < num; i++) {
+      dest.add(instance(from + i));
+    }
+  }
+
+  /**
+   * Test cv.
+   *
+   * @param numFolds the num folds
+   * @param numFold the num fold
+   * @return the instances
+   */
+  public Instances testCV(int numFolds, int numFold) {
+
+    int numInstForFold, first, offset;
+    Instances test;
+
+    numInstForFold = numInstances() / numFolds;
+    if (numFold < numInstances() % numFolds) {
+      numInstForFold++;
+      offset = numFold;
+    } else {
+      offset = numInstances() % numFolds;
+    }
+    test = new Instances(this, numInstForFold);
+    first = numFold * (numInstances() / numFolds) + offset;
+    copyInstances(first, test, numInstForFold);
+    return test;
+  }
+
+  /*  public Instances dataset() {
+     throw new UnsupportedOperationException("Not yet implemented");
+     }*/
+  /**
+   * Mean or mode.
+   *
+   * @param j the j
+   * @return the double
    */
   public double meanOrMode(int j) {
-    throw new UnsupportedOperationException("Not yet implemented"); // CobWeb
+    throw new UnsupportedOperationException("Not yet implemented"); //CobWeb
   }
 
+  /**
+   * Read instance.
+   *
+   * @param fileReader the file reader
+   * @return true, if successful
+   */
   public boolean readInstance(Reader fileReader) {
 
+    //ArffReader arff = new ArffReader(reader, this, m_Lines, 1);
     if (loader == null) {
       loader = new ArffLoader(fileReader, 0, this.classAttribute);
     }
-    return readInstance();
+    Instance inst = loader.readInstance();
+    if (inst != null) {
+      inst.setDataset(this);
+      add(inst);
+      return true;
+    } else {
+      return false;
+    }
   }
 
   public boolean readInstance() {
@@ -210,16 +463,37 @@ public class Instances implements Serializable {
     }
   }
 
+  /**
+   * Delete.
+   */
   public void delete() {
-    this.instances = new ArrayList<>();
+    this.instances = new ArrayList<Instance>();
   }
 
+  /**
+   * Delete.
+   */
+  public void delete(int index) {
+    this.instances.remove(index);
+  }
+
+  /**
+   * Swap.
+   *
+   * @param i the i
+   * @param j the j
+   */
   public void swap(int i, int j) {
     Instance in = instances.get(i);
     instances.set(i, instances.get(j));
     instances.set(j, in);
   }
 
+  /**
+   * Instance information.
+   *
+   * @return the instance information
+   */
   private InstanceInformation instanceInformation() {
     return this.instanceInformation;
   }
@@ -234,32 +508,122 @@ public class Instances implements Serializable {
     return null;
   }
 
-  @Override
+  public int size() {
+    return this.numInstances();
+  }
+
+  public void set(int i, Instance inst) {
+    this.instances.set(i, inst);
+  }
+
+  public Instance get(int k) {
+    return this.instance(k);
+  }
+
+  public void setRangeOutputIndices(Range range) {
+    this.instanceInformation.setRangeOutputIndices(range);
+
+  }
+
+  public void setAttributes(List<Attribute> v) {
+    if (this.instanceInformation == null) {
+      this.instanceInformation = new InstanceInformation();
+    }
+    this.instanceInformation.setAttributes(v);
+  }
+
+  public void setAttributes(List<Attribute> v, List<Integer> indexValues) {
+    if (this.instanceInformation == null) {
+      this.instanceInformation = new InstanceInformation();
+    }
+    this.instanceInformation.setAttributes(v, indexValues);
+  }
+
+  /**
+   * Returns the dataset as a string in ARFF format. Strings are quoted if
+   * they contain whitespace characters, or if they are a question mark.
+   *
+   * @return the dataset in ARFF format as a string
+   */
   public String toString() {
-    StringBuilder text = new StringBuilder();
 
-    for (int i = 0; i < numInstances(); i++) {
-      text.append(instance(i).toString());
-      if (i < numInstances() - 1) {
-        text.append('\n');
-      }
+    StringBuffer text = new StringBuffer();
+
+    text.append(ARFF_RELATION).append(" ").
+    
append(Utils.quote(this.instanceInformation.getRelationName())).append("\n\n");
+    for (int i = 0; i < numAttributes(); i++) {
+      text.append(attribute(i).toString()).append("\n");
     }
+    text.append("\n").append(ARFF_DATA).append("\n");
+
+    text.append(stringWithoutHeader());
     return text.toString();
   }
 
-  // toString() with header
+  /**
+   * Returns the dataset as a string in ARFF format. Strings are quoted if
+   * they contain whitespace characters, or if they are a question mark.
+   *
+   * @return the dataset in ARFF format as a string
+   */
   public String toStringArff() {
-    StringBuilder text = new StringBuilder();
 
-    text.append(ARFF_RELATION).append(" ")
-        .append(Utils.quote(getRelationName())).append("\n\n");
+    StringBuffer text = new StringBuffer();
+
+    text.append(ARFF_RELATION).append(" ").
+    
append(Utils.quote(this.instanceInformation.getRelationName())).append("\n\n");
     for (int i = 0; i < numAttributes(); i++) {
       text.append(attribute(i).toString()).append("\n");
     }
     text.append("\n").append(ARFF_DATA).append("\n");
 
-    text.append(toString());
+    text.append(stringWithoutHeader());
+    return text.toString();
+  }
+
+  /**
+   * Returns the instances in the dataset as a string in ARFF format. Strings
+   * are quoted if they contain whitespace characters, or if they are a
+   * question mark.
+   *
+   * @return the dataset in ARFF format as a string
+   */
+  protected String stringWithoutHeader() {
+
+    StringBuffer text = new StringBuffer();
+
+    for (int i = 0; i < numInstances(); i++) {
+      text.append(instance(i));
+      if (i < numInstances() - 1) {
+        text.append('\n');
+      }
+    }
     return text.toString();
 
   }
+
+  /**
+   * Returns the index of an Attribute.
+   *
+   * @param att, the attribute.
+   */
+  protected int indexOf(Attribute att) {
+    if (this.hsAttributesIndices == null || 
!this.hsAttributesIndices.containsKey(att.name)) {
+      computeAttributesIndices();
+    }
+
+    return this.hsAttributesIndices.get(att.name());
+  }
+
+  /**
+   * Completes the hashset with attributes indices.
+   */
+  private void computeAttributesIndices() {
+    this.hsAttributesIndices = new HashMap<String, Integer>();
+    // iterates through all existing attributes
+    // and sets an unique identifier for each one of them
+    for (int i = 0; i < this.numAttributes(); i++) {
+      hsAttributesIndices.put(this.attribute(i).name(), i);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/InstancesHeader.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/InstancesHeader.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/InstancesHeader.java
index a5d5a74..c32cf88 100644
--- 
a/samoa-instances/src/main/java/org/apache/samoa/instances/InstancesHeader.java
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/InstancesHeader.java
@@ -20,12 +20,6 @@ package org.apache.samoa.instances;
  * #L%
  */
 
-/**
- * Class for storing the header or context of a data stream. It allows to know 
the number of attributes and classes.
- * 
- * @author Richard Kirkby ([email protected])
- * @version $Revision: 7 $
- */
 public class InstancesHeader extends Instances {
 
   private static final long serialVersionUID = 1L;
@@ -38,14 +32,6 @@ public class InstancesHeader extends Instances {
     super();
   }
 
-  /*
-   * @Override public boolean add(Instance i) { throw new
-   * UnsupportedOperationException(); }
-   * 
-   * @Override public boolean readInstance(Reader r) throws IOException { throw
-   * new UnsupportedOperationException(); }
-   */
-
   public static String getClassNameString(InstancesHeader context) {
     if (context == null) {
       return "[class]";
@@ -59,7 +45,7 @@ public class InstancesHeader extends Instances {
       return "<class " + (classLabelIndex + 1) + ">";
     }
     return "<class " + (classLabelIndex + 1) + ":"
-        + context.classAttribute().value(classLabelIndex) + ">";
+    + context.classAttribute().value(classLabelIndex) + ">";
   }
 
   // is impervious to class index changes - attIndex is true attribute index
@@ -72,7 +58,17 @@ public class InstancesHeader extends Instances {
     int instAttIndex = attIndex < context.classIndex() ? attIndex
         : attIndex + 1;
     return "[att " + (attIndex + 1) + ":"
-        + context.attribute(instAttIndex).name() + "]";
+    + context.attribute(instAttIndex).name() + "]";
+  }
+
+  public static String getInputAttributeNameString(InstancesHeader context,
+      int attIndex) {
+    if ((context == null) || (attIndex >= context.numInputAttributes())) {
+      return "[att " + (attIndex + 1) + "]";
+    }
+    int instAttIndex = attIndex;
+    return "[att " + (attIndex + 1) + ":"
+    + context.inputAttribute(instAttIndex).name() + "]";
   }
 
   // is impervious to class index changes - attIndex is true attribute index
@@ -107,17 +103,23 @@ public class InstancesHeader extends Instances {
     return Double.toString(value);
   }
 
-  // add autom.
-  /*
-   * public int classIndex() { throw new
-   * UnsupportedOperationException("Not yet implemented"); }
-   * 
-   * public int numAttributes() { throw new
-   * UnsupportedOperationException("Not yet implemented"); }
-   * 
-   * @Override public Attribute attribute(int nPos) { throw new
-   * UnsupportedOperationException("Not yet implemented"); }
-   * 
-   * public int numClasses() { return 0; }
-   */
+  public Attribute inputAttribute(int w) {
+    return this.instanceInformation.inputAttribute(w);
+  }
+
+  public Attribute outputAttribute(int w) {
+    return this.instanceInformation.outputAttribute(w);
+  }
+
+  public int numInputAttributes() {
+    return this.instanceInformation.numInputAttributes();
+  }
+
+  public int numOutputAttributes() {
+    return this.instanceInformation.numOutputAttributes();
+  }
+
+  public InstanceInformation getInstanceInformation() {
+    return this.instanceInformation;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/Loader.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/Loader.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/Loader.java
index 7e04fbb..65835f1 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/Loader.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/Loader.java
@@ -22,12 +22,6 @@ package org.apache.samoa.instances;
 
 import java.io.Serializable;
 
-/**
- * Loads Instances from streams of different types of Input Formats e.g ARFF & 
AVRO
- * 
- * @author jayadeepj
- */
-
 public interface Loader extends Serializable {
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelInstance.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelInstance.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelInstance.java
new file mode 100644
index 0000000..9567c90
--- /dev/null
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelInstance.java
@@ -0,0 +1,25 @@
+package org.apache.samoa.instances;
+
+/*
+ * #%L
+ * SAMOA
+ * %%
+ * Copyright (C) 2014 - 2015 Apache Software Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface MultiLabelInstance extends Instance {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelPrediction.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelPrediction.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelPrediction.java
new file mode 100644
index 0000000..0b51c56
--- /dev/null
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiLabelPrediction.java
@@ -0,0 +1,139 @@
+package org.apache.samoa.instances;
+
+/*
+ * #%L
+ * SAMOA
+ * %%
+ * Copyright (C) 2014 - 2015 Apache Software Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+public class MultiLabelPrediction implements Prediction, Serializable {
+  protected ArrayList< ArrayList<Double> > prediction;
+
+  public MultiLabelPrediction() {
+    this(0);
+  }
+
+  public MultiLabelPrediction(int numOutputAttributes) {
+    prediction = new ArrayList< ArrayList<Double> >();
+    for (int i=0; i<numOutputAttributes;i++)
+      prediction.add(new ArrayList<Double>());
+  }
+
+  @Override
+  public int numOutputAttributes() {
+    return prediction.size();
+  }
+
+  @Override
+  public int numClasses(int outputAttributeIndex) {
+    int ret = 0;
+    if (prediction.size() > outputAttributeIndex) {
+      ret =  prediction.get(outputAttributeIndex).size();
+    }
+    return ret;
+  }
+
+  @Override
+  public double[] getVotes(int outputAttributeIndex) {
+    int s = prediction.get(outputAttributeIndex).size();
+    double ret[] = null;
+    if (prediction.size() > outputAttributeIndex) {
+      ArrayList<Double> aux = prediction.get(outputAttributeIndex);
+      ret = new double[s];
+      for (int i =0;i < s;i++) {
+        ret[i] = aux.get(i).doubleValue();
+      }
+    }
+
+    return ret;
+  }
+
+  @Override
+  public double[] getVotes() {
+    return getVotes(0);
+  }
+
+  @Override
+  public double getVote(int outputAttributeIndex, int classIndex) {
+    double ret = 0.0;
+    if (prediction.size() > outputAttributeIndex) {
+      ret = (classIndex >= 0 && classIndex < 
prediction.get(outputAttributeIndex).size()) ?
+          prediction.get(outputAttributeIndex).get(classIndex) : 0;
+    }
+    return ret;
+  }
+
+  @Override
+  public void setVotes(int outputAttributeIndex, double[] votes) {
+    for(int i=0; i<votes.length; i++) {
+      if (i >= prediction.get(outputAttributeIndex).size()) {
+        prediction.get(outputAttributeIndex).ensureCapacity(i+1);
+        while (prediction.get(outputAttributeIndex).size() < i+1) {
+          prediction.get(outputAttributeIndex).add(0.0);
+        }
+      }
+
+      prediction.get(outputAttributeIndex).set(i,votes[i]);
+    }
+  }
+
+  @Override
+  public void setVotes(double[] votes) {
+    setVotes(0, votes);
+  }
+
+  @Override
+  public void setVote(int outputAttributeIndex, int classIndex, double vote) {
+    if (outputAttributeIndex >= prediction.get(outputAttributeIndex).size()) {
+      prediction.get(outputAttributeIndex).ensureCapacity(classIndex+1);
+      while (prediction.get(outputAttributeIndex).size() < classIndex+1) {
+        prediction.get(outputAttributeIndex).add(0.0);
+      }
+    }
+
+    prediction.get(outputAttributeIndex).set(classIndex, vote);
+  }
+
+  @Override
+  public String toString(){
+    StringBuffer sb= new StringBuffer();
+    for (int i=0; i<prediction.size(); i++){
+      sb.append("Out " + i + ": ");
+      for (int c=0; c<prediction.get(i).size(); c++)
+      {
+        sb.append(((int)(prediction.get(i).get(c)*1000)/1000.0)+ " ");
+      }
+    }
+    return sb.toString();
+  }
+
+  @Override
+  public boolean hasVotesForAttribute(int outputAttributeIndex) {
+    if(prediction.size()<(outputAttributeIndex+1))
+      return false;
+    return (prediction.get(outputAttributeIndex).size()==0) ? false : true;
+  }
+
+  @Override
+  public int size() {
+    return prediction.size();
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/MultiTargetArffLoader.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/MultiTargetArffLoader.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiTargetArffLoader.java
new file mode 100644
index 0000000..0e9a8fa
--- /dev/null
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/MultiTargetArffLoader.java
@@ -0,0 +1,47 @@
+package org.apache.samoa.instances;
+
+/*
+ * #%L
+ * SAMOA
+ * %%
+ * Copyright (C) 2014 - 2015 Apache Software Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.io.Reader;
+
+public class MultiTargetArffLoader extends ArffLoader {
+
+  public MultiTargetArffLoader(Reader reader) {
+    super(reader);
+  }
+
+  public MultiTargetArffLoader(Reader reader, Range range) {
+    super(reader, range);
+  }
+
+  @Override
+  protected Instance newSparseInstance(double d, double[] res) {
+    return new SparseInstance(d, res); // TODO
+  }
+
+  @Override
+  protected Instance newDenseInstance(int numAttributes) {
+    // numAttributes is this.instanceInformation.numAttributes()
+    this.range.setUpper(numAttributes);
+    return new DenseInstance(numAttributes);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/Prediction.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/Prediction.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/Prediction.java
new file mode 100644
index 0000000..059e912
--- /dev/null
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/Prediction.java
@@ -0,0 +1,110 @@
+package org.apache.samoa.instances;
+
+/*
+ * #%L
+ * SAMOA
+ * %%
+ * Copyright (C) 2014 - 2015 Apache Software Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+public interface Prediction {
+
+  /**
+   * Number of output attributes.
+   *
+   * @return the number of output attributes
+   */
+  public int numOutputAttributes();
+
+  /**
+   * Different output attributes may have different number of classes.
+   * Regressors have one class per output attribute.
+   *
+   * @return the number of classes for attribute attributeIndex
+   */
+  public int numClasses(int outputAttributeIndex);
+
+  /*
+   * The predictions for each output attribute.
+   *
+   * @return the classes for each output attribute
+   *//*
+       public double [] getPrediction();
+    */
+
+  /**
+   * The votes for a given output attribute
+   *
+   * @return the votes for a given output attribute outputAttributeIndex.
+   */
+  public double [] getVotes(int outputAttributeIndex);
+
+  /**
+   * The vote assigned to a class of an output attribute
+   *
+   * @return the vote for an output attribute outputAttributeIndex and a class 
classIndex.
+   */
+  public double getVote(int outputAttributeIndex, int classIndex);
+
+  /**
+   * Sets the votes for a given output attribute
+   *
+   */
+  public void setVotes(int outputAttributeIndex, double [] votes);
+
+  /**
+   * Sets the votes for the first output attribute
+   *
+   */
+  public void setVotes(double[] votes);
+
+  /**
+   * Sets the vote for class of a given output attribute
+   *
+   */
+  public void setVote(int outputAttributeIndex, int classIndex, double vote);
+
+  /**
+   * The votes for the first output attribute
+   *
+   * @return the votes for the first output attribute outputAttributeIndex.
+   */
+  double[] getVotes();
+
+  /**
+   * Checks if there are votes for a given output attribute
+   *
+   * @return the votes for the first output attribute outputAttributeIndex.
+   */
+  boolean hasVotesForAttribute(int outputAttributeIndex);
+
+
+  /**
+   * The size of the prediction, that is the number of output attributes
+   *
+   * @return the votes for the first output attribute outputAttributeIndex.
+   */
+  public int size();
+
+  /**
+   * The text of the prediction, that is the description of the values of the 
prediction
+   *
+   * @return the text
+   */
+  public String toString();
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/Range.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/Range.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/Range.java
new file mode 100644
index 0000000..52d036f
--- /dev/null
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/Range.java
@@ -0,0 +1,114 @@
+package org.apache.samoa.instances;
+
+/*
+ * #%L
+ * SAMOA
+ * %%
+ * Copyright (C) 2014 - 2015 Apache Software Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.io.Serializable;
+
+public class Range implements Serializable {
+
+  //Only works for ranges "start-end"
+  private int start = 0;
+  private int end = 0;
+  private int upperLimit = 0;
+  private final String rangeText;
+
+  public Range(String range) {
+    this.rangeText = range;
+    //this.setRange(range); //needs upperLimit
+  }
+
+  /**
+   * Sets the range from a string representation.
+   *
+   * @param range the start and end string
+   *
+   */
+  public void setRange(String range) {
+    String single = range.trim();
+    int hyphenIndex = range.indexOf('-');
+
+    if (hyphenIndex > 0) {
+      this.start = rangeSingle(range.substring(0, hyphenIndex));
+      this.end = rangeSingle(range.substring(hyphenIndex + 1));
+    } else {
+      int number = rangeSingle(range);
+      if (number >= 0) { // first n attributes
+        this.start = 0;
+        this.end = number;
+      } else { // last n attributes
+        this.start = this.upperLimit + number > 0 ? this.upperLimit + number : 
0;
+        this.end = this.upperLimit - 1;
+      }
+    }
+  }
+
+  /**
+   * Translates a single string selection into it's internal 0-based
+   * equivalent.
+   *
+   * @param single the string representing the selection (eg: 1 first last)
+   * @return the number corresponding to the selected value
+   */
+  protected /*@pure@*/ int rangeSingle(/*@non_null@*/String singleSelection) {
+
+    String single = singleSelection.trim();
+    if (single.toLowerCase().equals("first")) {
+      return 0;
+    }
+    if (single.toLowerCase().equals("last") || 
single.toLowerCase().equals("-1")) {
+      return -1;
+    }
+    int index = Integer.parseInt(single);
+    if (index >= 1) { //Non for negatives
+      index--;
+    }
+    return index;
+  }
+
+  boolean isInRange(int value) {
+    boolean ret = false;
+    if (value >= start && value <= end) {
+      ret = true;
+    }
+    return ret;
+  }
+
+  int getSelectionLength() {
+    return end - start + 1;
+  }
+
+  public void setUpper(int attributeNumber) {
+    this.upperLimit = attributeNumber;
+    this.setRange(this.rangeText);
+  }
+
+  //JD
+  public int getStart() {
+    return start;
+  }
+
+  //JD
+
+  public int getEnd() {
+    return end;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/SingleClassInstanceData.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SingleClassInstanceData.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SingleClassInstanceData.java
deleted file mode 100644
index dfb8474..0000000
--- 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SingleClassInstanceData.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.apache.samoa.instances;
-
-/*
- * #%L
- * SAMOA
- * %%
- * Copyright (C) 2014 - 2015 Apache Software Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-/**
- * 
- * @author abifet
- */
-public class SingleClassInstanceData implements InstanceData {
-
-  protected double classValue;
-
-  @Override
-  public int numAttributes() {
-    return 1;
-  }
-
-  @Override
-  public double value(int instAttIndex) {
-    return classValue;
-  }
-
-  @Override
-  public boolean isMissing(int indexAttribute) {
-    return Double.isNaN(this.value(indexAttribute));
-  }
-
-  @Override
-  public int numValues() {
-    return 1;
-  }
-
-  @Override
-  public int index(int i) {
-    return 0;
-  }
-
-  @Override
-  public double valueSparse(int i) {
-    return value(i);
-  }
-
-  @Override
-  public boolean isMissingSparse(int indexAttribute) {
-    return Double.isNaN(this.value(indexAttribute));
-  }
-
-  /*
-   * @Override public double value(Attribute attribute) { return
-   * this.classValue; }
-   */
-
-  @Override
-  public double[] toDoubleArray() {
-    double[] array = { this.classValue };
-    return array;
-  }
-
-  @Override
-  public void setValue(int m_numAttributes, double d) {
-    this.classValue = d;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/SingleLabelInstance.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SingleLabelInstance.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SingleLabelInstance.java
deleted file mode 100644
index d69a0f5..0000000
--- 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SingleLabelInstance.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.apache.samoa.instances;
-
-/*
- * #%L
- * SAMOA
- * %%
- * Copyright (C) 2014 - 2015 Apache Software Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-/**
- * 
- * @author abifet
- */
-// public int[] m_AttValues; // for DataPoint
-
-public class SingleLabelInstance implements Instance {
-
-  protected double weight;
-
-  protected InstanceData instanceData;
-
-  protected InstanceData classData;
-
-  // Fast implementation without using Objects
-  // protected double[] attributeValues;
-  // protected double classValue;
-
-  protected InstancesHeader instanceInformation;
-
-  public SingleLabelInstance() {
-    // necessary for kryo serializer
-  }
-
-  public SingleLabelInstance(SingleLabelInstance inst) {
-    this.weight = inst.weight;
-    this.instanceData = inst.instanceData; // copy
-    this.classData = inst.classData; // copy
-    // this.classValue = inst.classValue;
-    // this.attributeValues = inst.attributeValues;
-    this.instanceInformation = inst.instanceInformation;
-  }
-
-  // Dense
-  public SingleLabelInstance(double weight, double[] res) {
-    this.weight = weight;
-    this.instanceData = new DenseInstanceData(res);
-    // this.attributeValues = res;
-    this.classData = new SingleClassInstanceData();
-    // this.classValue = Double.NaN;
-
-  }
-
-  // Sparse
-  public SingleLabelInstance(double weight, double[] attributeValues,
-      int[] indexValues, int numberAttributes) {
-    this.weight = weight;
-    this.instanceData = new SparseInstanceData(attributeValues,
-        indexValues, numberAttributes); // ???
-    this.classData = new SingleClassInstanceData();
-    // this.classValue = Double.NaN;
-    // this.instanceInformation = new InstancesHeader();
-
-  }
-
-  public SingleLabelInstance(double weight, InstanceData instanceData) {
-    this.weight = weight;
-    this.instanceData = instanceData; // ???
-    // this.classValue = Double.NaN;
-    this.classData = new SingleClassInstanceData();
-    // this.instanceInformation = new InstancesHeader();
-  }
-
-  public SingleLabelInstance(int numAttributes) {
-    this.instanceData = new DenseInstanceData(new double[numAttributes]);
-    // m_AttValues = new double[numAttributes];
-    /*
-     * for (int i = 0; i < m_AttValues.length; i++) { m_AttValues[i] =
-     * Utils.missingValue(); }
-     */
-    this.weight = 1;
-    this.classData = new SingleClassInstanceData();
-    this.instanceInformation = new InstancesHeader();
-  }
-
-  @Override
-  public double weight() {
-    return weight;
-  }
-
-  @Override
-  public void setWeight(double weight) {
-    this.weight = weight;
-  }
-
-  @Override
-  public Attribute attribute(int instAttIndex) {
-    return this.instanceInformation.attribute(instAttIndex);
-  }
-
-  @Override
-  public void deleteAttributeAt(int i) {
-    // throw new UnsupportedOperationException("Not yet implemented");
-  }
-
-  @Override
-  public void insertAttributeAt(int i) {
-    throw new UnsupportedOperationException("Not yet implemented");
-  }
-
-  @Override
-  public int numAttributes() {
-    return this.instanceInformation.numAttributes();
-  }
-
-  @Override
-  public double value(int instAttIndex) {
-    return // attributeValues[instAttIndex]; //
-    this.instanceData.value(instAttIndex);
-  }
-
-  @Override
-  public boolean isMissing(int instAttIndex) {
-    return // Double.isNaN(value(instAttIndex)); //
-    this.instanceData.isMissing(instAttIndex);
-  }
-
-  @Override
-  public int numValues() {
-    return // this.attributeValues.length; //
-    this.instanceData.numValues();
-  }
-
-  @Override
-  public int index(int i) {
-    return // i; //
-    this.instanceData.index(i);
-  }
-
-  @Override
-  public double valueSparse(int i) {
-    return this.instanceData.valueSparse(i);
-  }
-
-  @Override
-  public boolean isMissingSparse(int p) {
-    return this.instanceData.isMissingSparse(p);
-  }
-
-  @Override
-  public double value(Attribute attribute) {
-    // throw new UnsupportedOperationException("Not yet implemented");
-    // //Predicates.java
-    return value(attribute.index());
-
-  }
-
-  @Override
-  public String stringValue(int i) {
-    throw new UnsupportedOperationException("Not yet implemented");
-  }
-
-  @Override
-  public double[] toDoubleArray() {
-    return // this.attributeValues; //
-    this.instanceData.toDoubleArray();
-  }
-
-  @Override
-  public void setValue(int numAttribute, double d) {
-    this.instanceData.setValue(numAttribute, d);
-    // this.attributeValues[numAttribute] = d;
-  }
-
-  @Override
-  public double classValue() {
-    return this.classData.value(0);
-    // return classValue;
-  }
-
-  @Override
-  public int classIndex() {
-    return instanceInformation.classIndex();
-  }
-
-  @Override
-  public int numClasses() {
-    return this.instanceInformation.numClasses();
-  }
-
-  @Override
-  public boolean classIsMissing() {
-    return // Double.isNaN(this.classValue);//
-    this.classData.isMissing(0);
-  }
-
-  @Override
-  public Attribute classAttribute() {
-    //return the class attribute
-    return this.instanceInformation.attribute(classIndex());
-  }
-
-  @Override
-  public void setClassValue(double d) {
-    this.classData.setValue(0, d);
-  }
-
-  @Override
-  public Instance copy() {
-    SingleLabelInstance inst = new SingleLabelInstance(this);
-    return inst;
-  }
-
-  @Override
-  public Instances dataset() {
-    return this.instanceInformation;
-  }
-
-  @Override
-  public void setDataset(Instances dataset) {
-    this.instanceInformation = new InstancesHeader(dataset);
-  }
-
-  public void addSparseValues(int[] indexValues, double[] attributeValues,
-      int numberAttributes) {
-    this.instanceData = new SparseInstanceData(attributeValues,
-        indexValues, numberAttributes); // ???
-  }
-
-  @Override
-  public String toString() {
-    StringBuffer text = new StringBuffer();
-
-    for (int i = 0; i < this.numValues(); i++) {
-      if (i > 0)
-        text.append(",");
-      text.append(this.value(i));
-    }
-    text.append(",").append(this.weight());
-
-    return text.toString();
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstance.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstance.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstance.java
index 56dbc7f..a62013a 100644
--- 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstance.java
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstance.java
@@ -1,7 +1,3 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
 package org.apache.samoa.instances;
 
 /*
@@ -24,63 +20,46 @@ package org.apache.samoa.instances;
  * #L%
  */
 
-import java.text.SimpleDateFormat;
-
-/**
- * 
- * @author abifet
- */
-public class SparseInstance extends SingleLabelInstance {
+public class SparseInstance extends InstanceImpl {
 
+  /**
+   * Instantiates a new sparse instance.
+   *
+   * @param d the d
+   * @param res the res
+   */
   public SparseInstance(double d, double[] res) {
     super(d, res);
   }
 
-  public SparseInstance(SingleLabelInstance inst) {
+  /**
+   * Instantiates a new sparse instance.
+   *
+   * @param inst the inst
+   */
+  public SparseInstance(InstanceImpl inst) {
     super(inst);
   }
 
+  /**
+   * Instantiates a new sparse instance.
+   *
+   * @param numberAttributes the number attributes
+   */
   public SparseInstance(double numberAttributes) {
-    // super(1, new double[(int) numberAttributes-1]);
     super(1, null, null, (int) numberAttributes);
   }
 
+  /**
+   * Instantiates a new sparse instance.
+   *
+   * @param weight the weight
+   * @param attributeValues the attribute values
+   * @param indexValues the index values
+   * @param numberAttributes the number attributes
+   */
   public SparseInstance(double weight, double[] attributeValues, int[] 
indexValues, int numberAttributes) {
     super(weight, attributeValues, indexValues, numberAttributes);
   }
 
-  @Override
-  public String toString() {
-    StringBuffer str = new StringBuffer();
-
-    str.append("{");
-
-    for (int i=0; i<this.numAttributes()-1;i++){
-      if (!this.isMissing(i)) {
-
-        //if the attribute is Nominal we print the string value of the 
attribute.
-        if (this.attribute(i).isNominal()) {
-          int valueIndex = (int) this.value(i);
-          String stringValue = this.attribute(i).value(valueIndex);
-          str.append(i).append(" ").append(stringValue).append(",");
-        } else if (this.attribute(i).isNumeric()) {
-          //if the attribute is numeric we print the value of the attribute 
only if it is not equal 0
-          if (this.value(i) != 0) {
-            str.append(i).append(" ").append(this.value(i)).append(",");
-          }
-        } else if (this.attribute(i).isDate()) {
-          SimpleDateFormat dateFormatter = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-          str.append(i).append(" 
").append(dateFormatter.format(this.value(i))).append(",");
-        }
-      } else { //represent missing values
-        str.append(i).append(" ").append("?,");
-      }
-    }
-    //append the class value at the end of the instance.
-    str.append(classIndex()).append(" 
").append(this.classAttribute().value((int)classValue()));
-
-    str.append("}");
-
-    return str.toString();
-  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
index 9c14b8f..77b634b 100644
--- 
a/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
+++ 
b/samoa-instances/src/main/java/org/apache/samoa/instances/SparseInstanceData.java
@@ -1,7 +1,3 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
 package org.apache.samoa.instances;
 
 /*
@@ -24,62 +20,121 @@ package org.apache.samoa.instances;
  * #L%
  */
 
-/**
- * 
- * @author abifet
- */
 public class SparseInstanceData implements InstanceData {
 
+  /**
+   * Instantiates a new sparse instance data.
+   *
+   * @param attributeValues the attribute values
+   * @param indexValues the index values
+   * @param numberAttributes the number attributes
+   */
   public SparseInstanceData(double[] attributeValues, int[] indexValues, int 
numberAttributes) {
     this.attributeValues = attributeValues;
     this.indexValues = indexValues;
     this.numberAttributes = numberAttributes;
   }
 
+  /**
+   * Instantiates a new sparse instance data.
+   *
+   * @param length the length
+   */
   public SparseInstanceData(int length) {
     this.attributeValues = new double[length];
     this.indexValues = new int[length];
   }
 
+  /**
+   * The attribute values.
+   */
   protected double[] attributeValues;
 
+  /**
+   * Gets the attribute values.
+   *
+   * @return the attribute values
+   */
   public double[] getAttributeValues() {
     return attributeValues;
   }
 
+  /**
+   * Sets the attribute values.
+   *
+   * @param attributeValues the new attribute values
+   */
   public void setAttributeValues(double[] attributeValues) {
     this.attributeValues = attributeValues;
   }
 
+  /**
+   * Gets the index values.
+   *
+   * @return the index values
+   */
   public int[] getIndexValues() {
     return indexValues;
   }
 
+  /**
+   * Sets the index values.
+   *
+   * @param indexValues the new index values
+   */
   public void setIndexValues(int[] indexValues) {
     this.indexValues = indexValues;
   }
 
+  /**
+   * Gets the number attributes.
+   *
+   * @return the number attributes
+   */
   public int getNumberAttributes() {
     return numberAttributes;
   }
 
+  /**
+   * Sets the number of attributes.
+   *
+   * @param numberAttributes the new number attributes
+   */
   public void setNumberAttributes(int numberAttributes) {
     this.numberAttributes = numberAttributes;
   }
 
+  /**
+   * The index values.
+   */
   protected int[] indexValues;
+
+  /**
+   * The number of attributes.
+   */
   protected int numberAttributes;
 
+  /**
+   * Gets the number of attributes.
+   *
+   * @return the int
+   */
   @Override
   public int numAttributes() {
     return this.numberAttributes;
   }
 
+  /**
+   * Value.
+   *
+   * @param indexAttribute the index attribute
+   * @return the double
+   */
   @Override
   public double value(int indexAttribute) {
     int location = locateIndex(indexAttribute);
-    // return location == -1 ? 0 : this.attributeValues[location];
-    // int index = locateIndex(attIndex);
+    //return location == -1 ? 0 : this.attributeValues[location];
+    //      int index = locateIndex(attIndex);
     if ((location >= 0) && (indexValues[location] == indexAttribute)) {
       return attributeValues[location];
     } else {
@@ -87,36 +142,65 @@ public class SparseInstanceData implements InstanceData {
     }
   }
 
+  /**
+   * Checks if is missing.
+   *
+   * @param indexAttribute the index attribute
+   * @return true, if is missing
+   */
   @Override
   public boolean isMissing(int indexAttribute) {
     return Double.isNaN(this.value(indexAttribute));
   }
 
+  /**
+   * Num values.
+   *
+   * @return the int
+   */
   @Override
   public int numValues() {
     return this.attributeValues.length;
   }
 
+  /**
+   * Index.
+   *
+   * @param indexAttribute the index attribute
+   * @return the int
+   */
   @Override
   public int index(int indexAttribute) {
     return this.indexValues[indexAttribute];
   }
 
+  /**
+   * Value sparse.
+   *
+   * @param indexAttribute the index attribute
+   * @return the double
+   */
   @Override
   public double valueSparse(int indexAttribute) {
     return this.attributeValues[indexAttribute];
   }
 
+  /**
+   * Checks if is missing sparse.
+   *
+   * @param indexAttribute the index attribute
+   * @return true, if is missing sparse
+   */
   @Override
   public boolean isMissingSparse(int indexAttribute) {
     return Double.isNaN(this.valueSparse(indexAttribute));
   }
 
-  /*
-   * @Override public double value(Attribute attribute) { return
-   * value(attribute.index()); }
+  /**
+   * To double array.
+   *
+   * @return the double[]
    */
-
   @Override
   public double[] toDoubleArray() {
     double[] array = new double[numAttributes()];
@@ -126,6 +210,12 @@ public class SparseInstanceData implements InstanceData {
     return array;
   }
 
+  /**
+   * Sets the value.
+   *
+   * @param attributeIndex the attribute index
+   * @param d the d
+   */
   @Override
   public void setValue(int attributeIndex, double d) {
     int index = locateIndex(attributeIndex);
@@ -138,8 +228,9 @@ public class SparseInstanceData implements InstanceData {
 
   /**
    * Locates the greatest index that is not greater than the given index.
-   * 
-   * @return the internal index of the attribute index. Returns -1 if no index 
with this property could be found
+   *
+   * @return the internal index of the attribute index. Returns -1 if no index
+   * with this property could be found
    */
   public int locateIndex(int index) {
 
@@ -168,4 +259,46 @@ public class SparseInstanceData implements InstanceData {
     }
   }
 
+  /**
+   * Deletes an attribute at the given position (0 to numAttributes() - 1).
+   * 
+   * @param pos the attribute's position
+   */
+  @Override
+  public void deleteAttributeAt(int position) {
+
+    int index = locateIndex(position);
+
+    this.numberAttributes--;
+    if ((index >= 0) && (indexValues[index] == position)) {
+      int[] tempIndices = new int[indexValues.length - 1];
+      double[] tempValues = new double[attributeValues.length - 1];
+      System.arraycopy(indexValues, 0, tempIndices, 0, index);
+      System.arraycopy(attributeValues, 0, tempValues, 0, index);
+      for (int i = index; i < indexValues.length - 1; i++) {
+        tempIndices[i] = indexValues[i + 1] - 1;
+        tempValues[i] = attributeValues[i + 1];
+      }
+      indexValues = tempIndices;
+      attributeValues = tempValues;
+    } else {
+      int[] tempIndices = new int[indexValues.length];
+      double[] tempValues = new double[attributeValues.length];
+      System.arraycopy(indexValues, 0, tempIndices, 0, index + 1);
+      System.arraycopy(attributeValues, 0, tempValues, 0, index + 1);
+      for (int i = index + 1; i < indexValues.length; i++) {
+        tempIndices[i] = indexValues[i] - 1;
+        tempValues[i] = attributeValues[i];
+      }
+      indexValues = tempIndices;
+      attributeValues = tempValues;
+    }
+  }
+
+  @Override
+  public InstanceData copy() {
+    return new 
SparseInstanceData(this.attributeValues,this.indexValues,this.numberAttributes);
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-samoa/blob/26c21912/samoa-instances/src/main/java/org/apache/samoa/instances/Utils.java
----------------------------------------------------------------------
diff --git 
a/samoa-instances/src/main/java/org/apache/samoa/instances/Utils.java 
b/samoa-instances/src/main/java/org/apache/samoa/instances/Utils.java
index 73990bb..778f003 100644
--- a/samoa-instances/src/main/java/org/apache/samoa/instances/Utils.java
+++ b/samoa-instances/src/main/java/org/apache/samoa/instances/Utils.java
@@ -88,4 +88,4 @@ public class Utils {
 
     return string;
   }
-}
+}
\ No newline at end of file

Reply via email to