use of water.rapids.ast.AstRoot in project h2o-3 by h2oai.
the class Rapids method parseFunctionDefinition.
/**
* Parse and return a user defined function of the form "{arg1 arg2 . (expr)}"
*/
private AstFunction parseFunctionDefinition() {
eatChar('{');
// Parse the list of ids
ArrayList<String> ids = new ArrayList<>();
// 1-based ID list
ids.add("");
while (skipWS() != '.') {
String id = token();
if (!Character.isJavaIdentifierStart(id.charAt(0)))
throw new IllegalASTException("variable must be a valid Java identifier: " + id);
for (char c : id.toCharArray()) if (!Character.isJavaIdentifierPart(c))
throw new IllegalASTException("variable must be a valid Java identifier: " + id);
ids.add(id);
}
// Single dot separates the list of ids from the body of the function
eatChar('.');
// Parse the body
AstRoot body = parseNext();
if (skipWS() != '}')
throw new IllegalASTException("Expected the end of the function, but found '" + peek(0) + "'");
eatChar('}');
return new AstFunction(ids, body);
}
use of water.rapids.ast.AstRoot in project h2o-3 by h2oai.
the class AstHist method apply.
@Override
public ValFrame apply(Env env, Env.StackHelp stk, AstRoot[] asts) {
// stack is [ ..., ary, breaks]
// handle the breaks
Frame fr2;
Frame f = stk.track(asts[1].exec(env)).getFrame();
if (f.numCols() != 1)
throw new IllegalArgumentException("Hist only applies to single numeric columns.");
Vec vec = f.anyVec();
if (!vec.isNumeric())
throw new IllegalArgumentException("Hist only applies to single numeric columns.");
//TODO Add case when vec is a constant numeric
if (vec.isConst())
throw new IllegalArgumentException("Hist does not apply to constant numeric columns.");
AstRoot a = asts[2];
String algo = null;
int numBreaks = -1;
double[] breaks = null;
if (a instanceof AstStr)
algo = a.str().toLowerCase();
else if (a instanceof AstNumList)
breaks = ((AstNumList) a).expand();
else if (a instanceof AstNum)
numBreaks = (int) a.exec(env).getNum();
AstHist.HistTask t;
double h;
double x1 = vec.max();
double x0 = vec.min();
if (breaks != null)
t = new AstHist.HistTask(breaks, -1, -1).doAll(vec);
else if (algo != null) {
switch(algo) {
case "sturges":
numBreaks = sturges(vec);
h = (x1 - x0) / numBreaks;
break;
case "rice":
numBreaks = rice(vec);
h = (x1 - x0) / numBreaks;
break;
case "sqrt":
numBreaks = sqrt(vec);
h = (x1 - x0) / numBreaks;
break;
case "doane":
numBreaks = doane(vec);
h = (x1 - x0) / numBreaks;
break;
case "scott":
h = scotts_h(vec);
numBreaks = scott(vec, h);
// special bin width computation
break;
case "fd":
h = fds_h(vec);
numBreaks = fd(vec, h);
// special bin width computation
break;
default:
numBreaks = sturges(vec);
// just do sturges even if junk passed in
h = (x1 - x0) / numBreaks;
}
t = new AstHist.HistTask(computeCuts(vec, numBreaks), h, x0).doAll(vec);
} else {
h = (x1 - x0) / numBreaks;
t = new AstHist.HistTask(computeCuts(vec, numBreaks), h, x0).doAll(vec);
}
// wanna make a new frame here [breaks,counts,mids]
final double[] brks = t._breaks;
final long[] cnts = t._counts;
final double[] mids_true = t._mids;
final double[] mids = new double[t._breaks.length - 1];
for (int i = 1; i < brks.length; ++i) mids[i - 1] = .5 * (t._breaks[i - 1] + t._breaks[i]);
Vec layoutVec = Vec.makeZero(brks.length);
fr2 = new MRTask() {
@Override
public void map(Chunk[] c, NewChunk[] nc) {
int start = (int) c[0].start();
for (int i = 0; i < c[0]._len; ++i) {
nc[0].addNum(brks[i + start]);
if (i == 0) {
nc[1].addNA();
nc[2].addNA();
nc[3].addNA();
} else {
nc[1].addNum(cnts[(i - 1) + start]);
nc[2].addNum(mids_true[(i - 1) + start]);
nc[3].addNum(mids[(i - 1) + start]);
}
}
}
}.doAll(4, Vec.T_NUM, new Frame(layoutVec)).outputFrame(null, new String[] { "breaks", "counts", "mids_true", "mids" }, null);
layoutVec.remove();
return new ValFrame(fr2);
}
use of water.rapids.ast.AstRoot in project h2o-3 by h2oai.
the class AstApply method rowwise.
// --------------------------------------------------------------------------
// Break each row into it's own Row, then execute the function passing the
// 1 argument. All rows are independent, and run in parallel
private ValFrame rowwise(Env env, Frame fr, final AstPrimitive fun) {
final String[] names = fr._names;
// Current execution scope; needed to lookup variables
final AstFunction scope = env._scope;
// do a single row of the frame to determine the size of the output.
double[] ds = new double[fr.numCols()];
for (int col = 0; col < fr.numCols(); ++col) ds[col] = fr.vec(col).at(0);
int noutputs = fun.apply(env, env.stk(), new AstRoot[] { fun, new AstRow(ds, fr.names()) }).getRow().length;
Frame res = new MRTask() {
@Override
public void map(Chunk[] chks, NewChunk[] nc) {
// Working row
double[] ds = new double[chks.length];
// Arguments to be called; they are reused endlessly
AstRoot[] asts = new AstRoot[] { fun, new AstRow(ds, names) };
// Session, again reused endlessly
Session ses = new Session();
Env env = new Env(ses);
// For proper namespace lookup
env._scope = scope;
for (int row = 0; row < chks[0]._len; row++) {
for (// Fill the row
int col = 0; // Fill the row
col < chks.length; // Fill the row
col++) ds[col] = chks[col].atd(row);
try (Env.StackHelp stk_inner = env.stk()) {
// Make the call per-row
double[] valRow = fun.apply(env, stk_inner, asts).getRow();
for (int newCol = 0; newCol < nc.length; ++newCol) nc[newCol].addNum(valRow[newCol]);
}
}
// Mostly for the sanity checks
ses.end(null);
}
}.doAll(noutputs, Vec.T_NUM, fr).outputFrame();
return new ValFrame(res);
}
use of water.rapids.ast.AstRoot in project h2o-3 by h2oai.
the class AstIsax method apply.
@Override
public Val apply(Env env, Env.StackHelp stk, AstRoot[] asts) {
Frame fr = stk.track(asts[1].exec(env)).getFrame();
AstRoot n = asts[2];
AstRoot mc = asts[3];
boolean optm_card = asts[4].exec(env).getNum() == 1;
//Check vecs are numeric
for (Vec v : fr.vecs()) {
if (!v.isNumeric()) {
throw new IllegalArgumentException("iSax only applies to numeric columns!");
}
}
int numWords = (int) n.exec(env).getNum();
int maxCardinality = (int) mc.exec(env).getNum();
//Check numWords and maxCardinality are >=0
if (numWords < 0) {
throw new IllegalArgumentException("numWords must be greater than 0!");
}
if (maxCardinality < 0) {
throw new IllegalArgumentException("maxCardinality must be greater than 0!");
}
ArrayList<String> columns = new ArrayList<>();
for (int i = 0; i < numWords; i++) {
columns.add("c" + i);
}
Frame fr2 = new AstIsax.IsaxTask(numWords, maxCardinality).doAll(numWords, Vec.T_NUM, fr).outputFrame(null, columns.toArray(new String[numWords]), null);
int[] maxCards = new int[numWords];
if (optm_card) {
_domain_hm = new double[numWords][maxCardinality];
for (double[] r : _domain_hm) Arrays.fill(r, Double.NaN);
// see if we can reduce the cardinality by checking all unique tokens in all series in a word
for (int i = 0; i < fr2.numCols(); i++) {
String[] domains = fr2.vec(i).toCategoricalVec().domain();
for (int j = 0; j < domains.length; j++) {
_domain_hm[i][j] = Double.valueOf(domains[j]);
}
}
// get the cardinalities of each word
for (int i = 0; i < numWords; i++) {
int cnt = 0;
for (double d : _domain_hm[i]) {
if (Double.isNaN(d))
break;
else
cnt++;
}
maxCards[i] = cnt;
}
Frame fr2_reduced = new AstIsax.IsaxReduceCard(_domain_hm, maxCardinality).doAll(numWords, Vec.T_NUM, fr2).outputFrame(null, columns.toArray(new String[numWords]), null);
Frame fr3 = new AstIsax.IsaxStringTask(maxCards).doAll(1, Vec.T_STR, fr2_reduced).outputFrame(null, new String[] { "iSax_index" }, null);
//Not needed anymore
fr2.delete();
fr3.add(fr2_reduced);
return new ValFrame(fr3);
}
for (int i = 0; i < numWords; ++i) {
maxCards[i] = maxCardinality;
}
Frame fr3 = new AstIsax.IsaxStringTask(maxCards).doAll(1, Vec.T_STR, fr2).outputFrame(null, new String[] { "iSax_index" }, null);
fr3.add(fr2);
return new ValFrame(fr3);
}
use of water.rapids.ast.AstRoot in project h2o-3 by h2oai.
the class RapidsHandler method processAstClass.
private RapidsExpressionV3 processAstClass(Class<? extends AstRoot> clz, Reflections refl) {
ArrayList<RapidsExpressionV3> subs = new ArrayList<>();
for (Class<? extends AstRoot> subclass : refl.getSubTypesOf(clz)) if (subclass.getSuperclass() == clz)
subs.add(processAstClass(subclass, refl));
RapidsExpressionV3 target = new RapidsExpressionV3();
target.name = clz.getSimpleName();
target.is_abstract = Modifier.isAbstract(clz.getModifiers());
if (!target.is_abstract) {
try {
AstRoot m = clz.newInstance();
target.pattern = m.example();
target.description = m.description();
} catch (IllegalAccessException e) {
throw H2O.fail("A");
} catch (InstantiationException e) {
throw H2O.fail("B");
}
}
target.sub = subs.toArray(new RapidsExpressionV3[subs.size()]);
return target;
}
Aggregations