@Override
 public void compute() {
   // cover undefined cases
   if (!degree.isDefined() || !min.isDefined() || !max.isDefined() || degree.getDouble() < 0) {
     polynomial.setUndefined();
     return;
   }
   int lower = (int) Math.ceil(min.getDouble());
   int upper = (int) Math.floor(max.getDouble());
   if (lower > upper || (lower == 0 && upper == 0)) {
     polynomial.setUndefined();
     return;
   }
   // input is sane, we can do the computation
   int deg = (int) Math.floor(degree.getDouble());
   ExpressionNode varExpr = new ExpressionNode(kernel, fv);
   ExpressionNode newExpr = randomCoef(deg != 0);
   for (int i = 1; i <= deg; i++) {
     newExpr = varExpr.power(new MyDouble(kernel, i)).multiply(randomCoef(i != deg)).plus(newExpr);
   }
   f.setExpression(newExpr, fv);
   polynomial.setFunction(f);
 }
Ejemplo n.º 2
0
  @Override
  public void compute() {
    int degInt;
    GeoList coefs = null;
    fv.setVarString(f.getVarString(StringTemplate.defaultTemplate));
    // px^2+qx+r; p+q+r=s;
    double r = f.evaluate(0);
    double s = f.evaluate(1);
    double p = 0.5 * (s + f.evaluate(-1)) - r;
    double q = s - p - r;
    boolean isQuadratic = !f.isGeoFunctionConditional();
    double[] checkpoints = {1000, -1000, Math.PI, Math.E};
    for (int i = 0; i < checkpoints.length; i++) {
      double x = checkpoints[i];
      if (!Kernel.isZero(p * x * x + q * x + r - f.evaluate(x))) {
        // App.debug(p + "," + q + "," + r + ","
        // + (p * x * x + q * x + r - f.evaluate(x)));
        isQuadratic = false;
      }
    }
    if (!isQuadratic) {
      if (algoCoef == null) {
        algoCoef = new AlgoCoefficients(cons, f);
        algoCoef.setProtectedInput(true);
        algoCoef.remove();
      } else {
        algoCoef.compute();
      }
      coefs = algoCoef.getResult();

      degInt = coefs.size() - 1;
      isQuadratic = coefs.isDefined() && coefs.get(0).isDefined();
      for (int i = 1; i < degInt; i++) {
        if (2 * i != degInt && !Kernel.isZero(((GeoNumeric) coefs.get(i)).getDouble())) {
          isQuadratic = false;
        }
        p = ((GeoNumeric) coefs.get(0)).getDouble();
        q = ((GeoNumeric) coefs.get(degInt / 2)).getDouble();
        r = ((GeoNumeric) coefs.get(degInt)).getDouble();
      }
    } else {
      degInt = 2;
    }

    if (degInt % 2 == 1 || degInt < 2 || !isQuadratic || Kernel.isZero(p)) {
      square.setUndefined();
      return;
    }

    if (lastDeg != degInt) {
      ExpressionNode squareE;
      ExpressionValue fvPower;
      if (degInt == 2) fvPower = fv;
      else
        fvPower = new ExpressionNode(kernel, fv, Operation.POWER, new MyDouble(kernel, degInt / 2));
      squareE =
          new ExpressionNode(
              kernel,
              new ExpressionNode(
                  kernel,
                  a,
                  Operation.MULTIPLY,
                  new ExpressionNode(kernel, fvPower, Operation.MINUS, h)
                      .power(new MyDouble(kernel, 2))),
              Operation.PLUS,
              k);

      square.getFunction().setExpression(squareE);
    }
    lastDeg = degInt;
    fv.setVarString(f.getVarString(StringTemplate.defaultTemplate));

    // if one is undefined, others are as well
    square.setDefined(!Double.isNaN(r));
    a.set(p);
    h.set(-q / (2 * p));
    k.set(r - q * q / (p * 4));
  }