* @return the modified data
* @throws Exception in case the processing goes wrong
* @see #batchFinished()
*/
protected Instances process(Instances instances) throws Exception {
Instances result;
int i;
int n;
int m;
int index;
Instances[] processed;
Instance inst;
Instance newInst;
double[] values;
Vector errors;
if (!isFirstBatchDone()) {
checkDimensions();
// set upper limits
for (i = 0; i < m_Ranges.length; i++)
m_Ranges[i].setUpper(instances.numAttributes() - 1);
// determine unused indices
determineUnusedIndices(instances);
}
// pass data through all filters
processed = new Instances[getFilters().length];
for (i = 0; i < getFilters().length; i++) {
processed[i] = generateSubset(instances, getRange(i));
if (!isFirstBatchDone())
getFilter(i).setInputFormat(processed[i]);
processed[i] = Filter.useFilter(processed[i], getFilter(i));
}
// set output format (can only be determined with full dataset, hence here)
if (!isFirstBatchDone()) {
result = determineOutputFormat(instances);
setOutputFormat(result);
}
else {
result = getOutputFormat();
}
// check whether all filters didn't change the number of instances
errors = new Vector();
for (i = 0; i < processed.length; i++) {
if (processed[i].numInstances() != instances.numInstances())
errors.add(new Integer(i));
}
if (errors.size() > 0)
throw new IllegalStateException(
"The following filter(s) changed the number of instances: " + errors);
// assemble data
for (i = 0; i < instances.numInstances(); i++) {
inst = instances.instance(i);
values = new double[result.numAttributes()];
// filtered data
index = 0;
for (n = 0; n < processed.length; n++) {
for (m = 0; m < processed[n].numAttributes(); m++) {
if (m == processed[n].classIndex())
continue;
values[index] = processed[n].instance(i).value(m);
index++;
}
}
// unused attributes
if (!getRemoveUnused()) {
for (n = 0; n < m_IndicesUnused.length; n++) {
values[index] = inst.value(m_IndicesUnused[n]);
index++;
}
}
// class
if (instances.classIndex() > -1)
values[values.length - 1] = inst.value(instances.classIndex());
// generate and add instance
if (inst instanceof SparseInstance)
newInst = new SparseInstance(instances.instance(i).weight(), values);
else
newInst = new DenseInstance(instances.instance(i).weight(), values);
result.add(newInst);
}
return result;
}