public double execute(double in) throws DMLRuntimeException {
    switch (bFunc) {
      case SIN:
        return FASTMATH ? FastMath.sin(in) : Math.sin(in);
      case COS:
        return FASTMATH ? FastMath.cos(in) : Math.cos(in);
      case TAN:
        return FASTMATH ? FastMath.tan(in) : Math.tan(in);
      case ASIN:
        return FASTMATH ? FastMath.asin(in) : Math.asin(in);
      case ACOS:
        return FASTMATH ? FastMath.acos(in) : Math.acos(in);
      case ATAN:
        return Math.atan(in); // faster in Math
      case CEIL:
        return FASTMATH ? FastMath.ceil(in) : Math.ceil(in);
      case FLOOR:
        return FASTMATH ? FastMath.floor(in) : Math.floor(in);
      case LOG:
        return FASTMATH ? FastMath.log(in) : Math.log(in);
      case LOG_NZ:
        return (in == 0) ? 0 : FASTMATH ? FastMath.log(in) : Math.log(in);
      case ABS:
        return Math.abs(in); // no need for FastMath	
      case SIGN:
        return FASTMATH ? FastMath.signum(in) : Math.signum(in);
      case SQRT:
        return Math.sqrt(in); // faster in Math
      case EXP:
        return FASTMATH ? FastMath.exp(in) : Math.exp(in);
      case ROUND:
        return Math.round(in); // no need for FastMath

      case PLOGP:
        if (in == 0.0) return 0.0;
        else if (in < 0) return Double.NaN;
        else return (in * (FASTMATH ? FastMath.log(in) : Math.log(in)));

      case SPROP:
        // sample proportion: P*(1-P)
        return in * (1 - in);

      case SIGMOID:
        // sigmoid: 1/(1+exp(-x))
        return FASTMATH ? 1 / (1 + FastMath.exp(-in)) : 1 / (1 + Math.exp(-in));

      case SELP:
        // select positive: x*(x>0)
        return (in > 0) ? in : 0;

      default:
        throw new DMLRuntimeException("Builtin.execute(): Unknown operation: " + bFunc);
    }
  }
  /**
   * Returns an estimate of the <code>p</code>th percentile of the values in the <code>values</code>
   * array, starting with the element in (0-based) position <code>begin</code> in the array and
   * including <code>length</code> values.
   *
   * <p>Calls to this method do not modify the internal <code>quantile</code> state of this
   * statistic.
   *
   * <p>
   *
   * <ul>
   *   <li>Returns <code>Double.NaN</code> if <code>length = 0</code>
   *   <li>Returns (for any value of <code>p</code>) <code>values[begin]</code> if <code>length = 1
   *       </code>
   *   <li>Throws <code>IllegalArgumentException</code> if <code>values</code> is null , <code>begin
   *       </code> or <code>length</code> is invalid, or <code>p</code> is not a valid quantile
   *       value (p must be greater than 0 and less than or equal to 100)
   * </ul>
   *
   * <p>See {@link Percentile} for a description of the percentile estimation algorithm used.
   *
   * @param values array of input values
   * @param p the percentile to compute
   * @param begin the first (0-based) element to include in the computation
   * @param length the number of array elements to include
   * @return the percentile value
   * @throws IllegalArgumentException if the parameters are not valid or the input array is null
   */
  public double evaluate(final double[] values, final int begin, final int length, final double p) {

    test(values, begin, length);

    if ((p > 100) || (p <= 0)) {
      throw new OutOfRangeException(LocalizedFormats.OUT_OF_BOUNDS_QUANTILE_VALUE, p, 0, 100);
    }
    if (length == 0) {
      return Double.NaN;
    }
    if (length == 1) {
      return values[begin]; // always return single value for n = 1
    }
    double n = length;
    double pos = p * (n + 1) / 100;
    double fpos = FastMath.floor(pos);
    int intPos = (int) fpos;
    double dif = pos - fpos;
    double[] work;
    int[] pivotsHeap;
    if (values == getDataRef()) {
      work = getDataRef();
      pivotsHeap = cachedPivots;
    } else {
      work = new double[length];
      System.arraycopy(values, begin, work, 0, length);
      pivotsHeap = new int[(0x1 << MAX_CACHED_LEVELS) - 1];
      Arrays.fill(pivotsHeap, -1);
    }

    if (pos < 1) {
      return select(work, pivotsHeap, 0);
    }
    if (pos >= n) {
      return select(work, pivotsHeap, length - 1);
    }
    double lower = select(work, pivotsHeap, intPos - 1);
    double upper = select(work, pivotsHeap, intPos);
    return lower + dif * (upper - lower);
  }
 /**
  * Compute the error of Stirling's series at the given value.
  *
  * <p>References:
  *
  * <ol>
  *   <li>Eric W. Weisstein. "Stirling's Series." From MathWorld--A Wolfram Web Resource. <a
  *       target="_blank" href="http://mathworld.wolfram.com/StirlingsSeries.html">
  *       http://mathworld.wolfram.com/StirlingsSeries.html</a>
  * </ol>
  *
  * @param z the value.
  * @return the Striling's series error.
  */
 static double getStirlingError(double z) {
   double ret;
   if (z < 15.0) {
     double z2 = 2.0 * z;
     if (FastMath.floor(z2) == z2) {
       ret = EXACT_STIRLING_ERRORS[(int) z2];
     } else {
       ret = Gamma.logGamma(z + 1.0) - (z + 0.5) * FastMath.log(z) + z - HALF_LOG_2_PI;
     }
   } else {
     double z2 = z * z;
     ret =
         (0.083333333333333333333
                 - (0.00277777777777777777778
                         - (0.00079365079365079365079365
                                 - (0.000595238095238095238095238
                                         - 0.0008417508417508417508417508 / z2)
                                     / z2)
                             / z2)
                     / z2)
             / z;
   }
   return ret;
 }
Beispiel #4
0
  /**
   * Create a fraction given the double value and either the maximum error allowed or the maximum
   * number of denominator digits.
   *
   * <p>NOTE: This constructor is called with EITHER - a valid epsilon value and the maxDenominator
   * set to Integer.MAX_VALUE (that way the maxDenominator has no effect). OR - a valid
   * maxDenominator value and the epsilon value set to zero (that way epsilon only has effect if
   * there is an exact match before the maxDenominator value is reached).
   *
   * <p>It has been done this way so that the same code can be (re)used for both scenarios. However
   * this could be confusing to users if it were part of the public API and this constructor should
   * therefore remain PRIVATE. See JIRA issue ticket MATH-181 for more details:
   *
   * <p>https://issues.apache.org/jira/browse/MATH-181
   *
   * @param value the double value to convert to a fraction.
   * @param epsilon maximum error allowed. The resulting fraction is within {@code epsilon} of
   *     {@code value}, in absolute terms.
   * @param maxDenominator maximum denominator value allowed.
   * @param maxIterations maximum number of convergents
   * @throws FractionConversionException if the continued fraction failed to converge.
   */
  private Fraction(double value, double epsilon, int maxDenominator, int maxIterations)
      throws FractionConversionException {
    long overflow = Integer.MAX_VALUE;
    double r0 = value;
    long a0 = (long) FastMath.floor(r0);
    if (FastMath.abs(a0) > overflow) {
      throw new FractionConversionException(value, a0, 1l);
    }

    // check for (almost) integer arguments, which should not go
    // to iterations.
    if (FastMath.abs(a0 - value) < epsilon) {
      this.numerator = (int) a0;
      this.denominator = 1;
      return;
    }

    long p0 = 1;
    long q0 = 0;
    long p1 = a0;
    long q1 = 1;

    long p2 = 0;
    long q2 = 1;

    int n = 0;
    boolean stop = false;
    do {
      ++n;
      double r1 = 1.0 / (r0 - a0);
      long a1 = (long) FastMath.floor(r1);
      p2 = (a1 * p1) + p0;
      q2 = (a1 * q1) + q0;
      if ((FastMath.abs(p2) > overflow) || (FastMath.abs(q2) > overflow)) {
        // in maxDenominator mode, if the last fraction was very close to the actual value
        // q2 may overflow in the next iteration; in this case return the last one.
        if (epsilon == 0.0 && FastMath.abs(q1) < maxDenominator) {
          break;
        }

        throw new FractionConversionException(value, p2, q2);
      }

      double convergent = (double) p2 / (double) q2;
      if (n < maxIterations && FastMath.abs(convergent - value) > epsilon && q2 < maxDenominator) {
        p0 = p1;
        p1 = p2;
        q0 = q1;
        q1 = q2;
        a0 = a1;
        r0 = r1;
      } else {
        stop = true;
      }
    } while (!stop);

    if (n >= maxIterations) {
      throw new FractionConversionException(value, maxIterations);
    }

    if (q2 < maxDenominator) {
      this.numerator = (int) p2;
      this.denominator = (int) q2;
    } else {
      this.numerator = (int) p1;
      this.denominator = (int) q1;
    }
  }
Beispiel #5
0
  /**
   * Returns the value of log B(p, q) for 0 ≤ x ≤ 1 and p, q > 0. Based on the <em>NSWC Library of
   * Mathematics Subroutines</em> implementation, {@code DBETLN}.
   *
   * @param p First argument.
   * @param q Second argument.
   * @return the value of {@code log(Beta(p, q))}, {@code NaN} if {@code p <= 0} or {@code q <= 0}.
   */
  public static double logBeta(final double p, final double q) {
    if (Double.isNaN(p) || Double.isNaN(q) || (p <= 0.0) || (q <= 0.0)) {
      return Double.NaN;
    }

    final double a = FastMath.min(p, q);
    final double b = FastMath.max(p, q);
    if (a >= 10.0) {
      final double w = sumDeltaMinusDeltaSum(a, b);
      final double h = a / b;
      final double c = h / (1.0 + h);
      final double u = -(a - 0.5) * FastMath.log(c);
      final double v = b * FastMath.log1p(h);
      if (u <= v) {
        return (((-0.5 * FastMath.log(b) + HALF_LOG_TWO_PI) + w) - u) - v;
      } else {
        return (((-0.5 * FastMath.log(b) + HALF_LOG_TWO_PI) + w) - v) - u;
      }
    } else if (a > 2.0) {
      if (b > 1000.0) {
        final int n = (int) FastMath.floor(a - 1.0);
        double prod = 1.0;
        double ared = a;
        for (int i = 0; i < n; i++) {
          ared -= 1.0;
          prod *= ared / (1.0 + ared / b);
        }
        return (FastMath.log(prod) - n * FastMath.log(b))
            + (Gamma.logGamma(ared) + logGammaMinusLogGammaSum(ared, b));
      } else {
        double prod1 = 1.0;
        double ared = a;
        while (ared > 2.0) {
          ared -= 1.0;
          final double h = ared / b;
          prod1 *= h / (1.0 + h);
        }
        if (b < 10.0) {
          double prod2 = 1.0;
          double bred = b;
          while (bred > 2.0) {
            bred -= 1.0;
            prod2 *= bred / (ared + bred);
          }
          return FastMath.log(prod1)
              + FastMath.log(prod2)
              + (Gamma.logGamma(ared) + (Gamma.logGamma(bred) - logGammaSum(ared, bred)));
        } else {
          return FastMath.log(prod1) + Gamma.logGamma(ared) + logGammaMinusLogGammaSum(ared, b);
        }
      }
    } else if (a >= 1.0) {
      if (b > 2.0) {
        if (b < 10.0) {
          double prod = 1.0;
          double bred = b;
          while (bred > 2.0) {
            bred -= 1.0;
            prod *= bred / (a + bred);
          }
          return FastMath.log(prod)
              + (Gamma.logGamma(a) + (Gamma.logGamma(bred) - logGammaSum(a, bred)));
        } else {
          return Gamma.logGamma(a) + logGammaMinusLogGammaSum(a, b);
        }
      } else {
        return Gamma.logGamma(a) + Gamma.logGamma(b) - logGammaSum(a, b);
      }
    } else {
      if (b >= 10.0) {
        return Gamma.logGamma(a) + logGammaMinusLogGammaSum(a, b);
      } else {
        // The following command is the original NSWC implementation.
        // return Gamma.logGamma(a) +
        // (Gamma.logGamma(b) - Gamma.logGamma(a + b));
        // The following command turns out to be more accurate.
        return FastMath.log(Gamma.gamma(a) * Gamma.gamma(b) / Gamma.gamma(a + b));
      }
    }
  }