* It returns a <b>two element array</b> containing an adapted frame and a
* frame which contains only vectors which where adapted (the purpose of the
* second frame is to delete all adapted vectors with deletion of the
* frame). */
public Frame[] adapt( final Frame fr, boolean exact) {
Frame vfr = new Frame(fr); // To avoid modification of original frame fr
int ridx = vfr.find(_output._names[_output._names.length-1]);
if(ridx != -1 && ridx != vfr._names.length-1){ // Unify frame - put response to the end
String n = vfr._names[ridx];
vfr.add(n,vfr.remove(ridx));
}
int n = ridx == -1?_output._names.length-1:_output._names.length;
String [] names = Arrays.copyOf(_output._names, n);
Frame [] subVfr;
// replace missing columns with NaNs (or 0s for DeepLearning with sparse data)
// subVfr = vfr.subframe(names, (this instanceof DeepLearningModel && ((DeepLearningModel)this).get_params().sparse) ? 0 : Double.NaN);
subVfr = vfr.subframe(names, Double.NaN);
vfr = subVfr[0]; // extract only subframe but keep the rest for delete later
Vec[] frvecs = vfr.vecs();
boolean[] toEnum = new boolean[frvecs.length];
if(!exact) for(int i = 0; i < n;++i)
if(_output._domains[i] != null && !frvecs[i].isEnum()) {// if model expects domain but input frame does not have domain => switch vector to enum
frvecs[i] = frvecs[i].toEnum();
toEnum[i] = true;
}
int[][][] map = adapt(names,vfr.domains(),exact);
assert map.length == names.length; // Be sure that adapt call above do not skip any column
ArrayList<Vec> avecs = new ArrayList<>(); // adapted vectors
ArrayList<String> anames = new ArrayList<>(); // names for adapted vector
for( int c=0; c<map.length; c++ ) // Iterate over columns
if(map[c] != null) { // Column needs adaptation
Vec adaptedVec;
if (toEnum[c]) { // Vector was flipped to column already, compose transformation
adaptedVec = TransfVec.compose((TransfVec) frvecs[c], map[c], vfr.domains()[c], false);
} else adaptedVec = frvecs[c].makeTransf(map[c], vfr.domains()[c]);
avecs.add(frvecs[c] = adaptedVec);
anames.add(names[c]); // Collect right names
} else if (toEnum[c]) { // Vector was transformed to enum domain, but does not need adaptation we need to record it
avecs.add(frvecs[c]);
anames.add(names[c]);
}
// Fill trash bin by vectors which need to be deleted later by the caller.
Frame vecTrash = new Frame(anames.toArray(new String[anames.size()]), avecs.toArray(new Vec[avecs.size()]));
// if (subVfr[1]!=null) vecTrash.add(subVfr[1], true);
return new Frame[] { new Frame(names,frvecs), vecTrash };
}