All Downloads are FREE. Search and download functionalities are using the official Maven repository.

water.rapids.ASTBinOp Maven / Gradle / Ivy

There is a newer version: 3.8.2.9
Show newest version
package water.rapids;

import water.H2O;
import water.MRTask;
import water.fvec.Chunk;
import water.fvec.Frame;
import water.fvec.NewChunk;
import water.fvec.Vec;
import water.parser.BufferedString;
import water.util.ArrayUtils;
import water.util.MathUtils;
import water.util.VecUtils;
import java.util.Arrays;

/**
 * Subclasses auto-widen between scalars and Frames, and have exactly two arguments
 */
abstract class ASTBinOp extends ASTPrim {
  @Override
  public String[] args() { return new String[]{"leftArg", "rightArg"}; }
  @Override int nargs() { return 1+2; }
  @Override
  public Val apply(Env env, Env.StackHelp stk, AST asts[]) {
    Val left = stk.track(asts[1].exec(env));
    Val rite = stk.track(asts[2].exec(env));
    return prim_apply(left,rite);
  }

  Val prim_apply( Val left, Val rite ) {
    switch( left.type() ) {
    case Val.NUM:
      final double dlf = left.getNum();
      switch( rite.type() ) {
      case Val.NUM:  return new ValNum( op (dlf,rite.getNum()));
      case Val.NUMS: return new ValNum(op(dlf,rite.getNums()[0]));
      case Val.FRM:  return scalar_op_frame(dlf,rite.getFrame());
      case Val.ROW:
        double[] lft = new double[rite.getRow().length];
        Arrays.fill(lft,dlf);
        return row_op_row(lft,rite.getRow(),((ValRow)rite).getNames());
      case Val.STR:  throw H2O.unimpl();
      case Val.STRS: throw H2O.unimpl();
      default: throw H2O.unimpl();
      }

    case Val.NUMS:
      final double ddlf = left.getNums()[0];
      switch( rite.type() ) {
        case Val.NUM:  return new ValNum( op (ddlf,rite.getNum()));
        case Val.NUMS: return new ValNum(op(ddlf,rite.getNums()[0]));
        case Val.FRM:  return scalar_op_frame(ddlf,rite.getFrame());
        case Val.ROW:
          double[] lft = new double[rite.getRow().length];
          Arrays.fill(lft,ddlf);
          return row_op_row(lft,rite.getRow(),((ValRow)rite).getNames());
        case Val.STR:  throw H2O.unimpl();
        case Val.STRS: throw H2O.unimpl();
        default: throw H2O.unimpl();
      }

    case Val.FRM:
      Frame flf = left.getFrame();
      switch( rite.type() ) {
      case Val.NUM:  return frame_op_scalar(flf,rite.getNum());
      case Val.NUMS: return frame_op_scalar(flf,rite.getNums()[0]);
      case Val.STR:  return frame_op_scalar(flf, rite.getStr());
      case Val.STRS: return frame_op_scalar(flf,rite.getStrs()[0]);
      case Val.FRM:  return frame_op_frame (flf,rite.getFrame());
      default: throw H2O.unimpl();
      }

    case Val.STR:
      String slf = left.getStr();
      switch( rite.type() ) {
      case Val.NUM:  throw H2O.unimpl();
      case Val.NUMS: throw H2O.unimpl();
      case Val.STR:  throw H2O.unimpl();
      case Val.STRS: throw H2O.unimpl();
      case Val.FRM:  return scalar_op_frame(slf, rite.getFrame());
      default: throw H2O.unimpl();
      }

    case Val.STRS:
      String sslf = left.getStrs()[0];
      switch( rite.type() ) {
        case Val.NUM:  throw H2O.unimpl();
        case Val.NUMS: throw H2O.unimpl();
        case Val.STR:  throw H2O.unimpl();
        case Val.STRS: throw H2O.unimpl();
        case Val.FRM:  return scalar_op_frame(sslf,rite.getFrame());
        default: throw H2O.unimpl();
      }

    case Val.ROW:
      double dslf[] = left.getRow();
      switch( rite.type() ) {
      case Val.NUM:
        double[] right = new double[dslf.length];
        Arrays.fill(right, rite.getNum());
        return row_op_row(dslf,right,((ValRow)left).getNames());
      case Val.ROW:  return row_op_row(dslf,rite.getRow(),((ValRow)rite).getNames());
      case Val.FRM:  return row_op_row(dslf,rite.getRow(),rite.getFrame().names());
      default: throw H2O.unimpl();
      }

    default: throw H2O.unimpl();
    }
  }

  /** Override to express a basic math primitive */
  abstract double op( double l, double r );
  double str_op( BufferedString l, BufferedString r ) { throw H2O.fail(); }

  /** Auto-widen the scalar to every element of the frame */
  private ValFrame scalar_op_frame( final double d, Frame fr ) {
    Frame res = new MRTask() {
        @Override public void map( Chunk[] chks, NewChunk[] cress ) {
          for( int c=0; c 1 ) return vec_op_frame(lf.vecs()[0],rt);
    if( rt.numCols() == 1 && lf.numCols() > 1 ) return frame_op_vec(lf,rt.vecs()[0]);
    if( lf.numCols() != rt.numCols() )
      throw new IllegalArgumentException("Frames must have same columns, found "+lf.numCols()+" columns and "+rt.numCols()+" columns.");

    Frame res = new MRTask() {
        @Override public void map( Chunk[] chks, NewChunk[] cress ) {
          BufferedString lfstr = new BufferedString();
          BufferedString rtstr = new BufferedString();
          assert (cress.length<<1) == chks.length;
          for( int c=0; c 2.68
    if(Double.isNaN(x)) return x;
    double sgn = x < 0 ? -1 : 1;
    x = Math.abs(x);
    if( (int) digits != digits) digits = Math.round(digits);
    double power_of_10 = (int)Math.pow(10, (int)digits);
    return sgn*(digits == 0
                // go to the even digit
                ?( x % 1 > 0.5 || (x % 1 == 0.5 && !(Math.floor(x)%2==0)))
                ? Math.ceil(x)
                : Math.floor(x)
                : Math.floor(x * power_of_10 + 0.5) / power_of_10);
  }
}

class ASTSignif extends ASTBinOp {
  public String str() { return "signif"; }
  double op(double x, double digits) {
    if(Double.isNaN(x)) return x;
    if(digits < 1) digits = 1; //mimic R's base::signif
    if( (int) digits != digits) digits = Math.round(digits);
    java.math.BigDecimal bd = new java.math.BigDecimal(x);
    bd = bd.round(new java.math.MathContext((int)digits, java.math.RoundingMode.HALF_EVEN));
    return bd.doubleValue();
  }
}


class ASTGE   extends ASTBinOp { public String str() { return ">="; } double op( double l, double r ) { return l>=r?1:0; } }
class ASTGT   extends ASTBinOp { public String str() { return ">" ; } double op( double l, double r ) { return l> r?1:0; } }
class ASTLE   extends ASTBinOp { public String str() { return "<="; } double op( double l, double r ) { return l<=r?1:0; } }
class ASTLT   extends ASTBinOp { public String str() { return "<" ; } double op( double l, double r ) { return l< r?1:0; } }

class ASTEQ   extends ASTBinOp { public String str() { return "=="; } double op( double l, double r ) { return MathUtils.equalsWithinOneSmallUlp(l,r)?1:0; }
  double str_op( BufferedString l, BufferedString r ) { return (l==null||l.equals("")) ? (r==null||(r.equals(""))?1:0) : (l.equals(r) ? 1 : 0); }
  @Override ValFrame frame_op_scalar( Frame fr, final double d ) {
    return new ValFrame(new MRTask() {
        @Override public void map( Chunk[] chks, NewChunk[] cress ) {
          for( int c=0; c 0; truth => 1
          fsIntMap[i] = 0;
          tsIntMap[i]  = 1;
        }
      } else if( ts!=null ) {
        for(int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy