Exemplo n.º 1
0
  /**
   * Tries to fix a structural problem leading to an evaluation error, e.g. x(x+1) is interpreted as
   * xcoord(x+1). This can be fixed by changing the structure to x*(x+1) for example.
   */
  private void fixStructure() {
    // get function variables for x, y, z
    FunctionVariable xVar = null, yVar = null, zVar = null;
    for (FunctionVariable fVar : fVars) {
      if ("x".equals(fVar.toString())) xVar = fVar;
      else if ("y".equals(fVar.toString())) yVar = fVar;
      else if ("z".equals(fVar.toString())) zVar = fVar;
    }

    // try to replace x(x+1) by x*(x+1)
    expression.replaceXYZnodes(xVar, yVar, zVar);
  }
Exemplo n.º 2
0
  /**
   * Call this function to resolve variables and init the function. May throw MyError
   * (InvalidFunction).
   */
  public void initFunction() {
    // replace function variables in tree
    for (int i = 0; i < fVars.length; i++) {
      FunctionVariable fVar = fVars[i];

      // look for Variable objects with name of function variable and
      // replace them
      int replacements = expression.replaceVariables(fVar.getSetVarString(), fVar);
      isConstantFunction = isConstantFunction && replacements == 0;

      if (replacements == 0) {
        // x, y got polynomials while parsing
        replacements = expression.replacePolynomials(fVar);
        isConstantFunction = isConstantFunction && replacements == 0;
      }
    }

    // replace variable names by objects
    expression.resolveVariables();

    // the idea here was to allow something like: Derivative[f] + 3x
    // but wrapping the GeoFunction objects as ExpressionNodes of type
    // FUNCTION
    // leads to Derivative[f](x) + 3x
    // expression.wrapGeoFunctionsAsExpressionNode();

    // replace all polynomials in expression (they are all equal to "1x" if
    // we got this far)
    // by an instance of MyDouble

    // simplify constant parts in expression
    expression.simplifyConstantIntegers();

    // evaluate expression to find out about the type of function
    ExpressionValue ev;
    try {
      ev = expression.evaluate();
    } catch (MyError err) {
      // Evaluation failed: DESPERATE MODE
      try {
        // try to fix structure of expression and then try evaluation again
        fixStructure();
        ev = expression.evaluate();
      } catch (Throwable th) {
        // throw original error when desperate mode failed
        throw err;
      }
    }

    // initialize type as boolean or numeric function
    initType(ev);
  }
Exemplo n.º 3
0
 // Map f to coefficients and arg
 public Algebraic map(LambdaAlgebraic f) throws JasymcaException {
   Algebraic x =
       var instanceof SimpleVariable
           ? new Polynomial(var)
           : FunctionVariable.create(
               ((FunctionVariable) var).fname, f.f_exakt(((FunctionVariable) var).arg));
   Algebraic r = Zahl.ZERO;
   for (int i = coef.length - 1; i > 0; i--) {
     r = r.add(f.f_exakt(coef[i])).mult(x);
   }
   if (coef.length > 0) r = r.add(f.f_exakt(coef[0]));
   return r;
 }
Exemplo n.º 4
0
 // return a vektor of all different solutions
 public Vektor solvepoly() throws JasymcaException {
   Vector s = new Vector();
   switch (degree()) {
     case 0:
       break;
     case 1:
       s.addElement(Zahl.MINUS.mult(coef[0].div(coef[1])));
       break;
     case 2:
       Algebraic p = coef[1].div(coef[2]);
       Algebraic q = coef[0].div(coef[2]);
       p = Zahl.MINUS.mult(p).div(Zahl.TWO);
       q = p.mult(p).sub(q);
       if (q.equals(Zahl.ZERO)) {
         s.addElement(p);
         break;
       }
       q = FunctionVariable.create("sqrt", q);
       s.addElement(p.add(q));
       s.addElement(p.sub(q));
       break;
       /*		case 3:
       Algebraic a = r.coef[2];
       Algebraic b = r.coef[1];
       Algebraic c = r.coef[0];
       Zahl drei = new Exakt(3.0);
       // p=(3b-a^2)/3
       p = drei.mult(b).sub(a.mult(a)).div(drei);
       // q = c + 2a^3/27 -ab/3
       q = c.add(Zahl.TWO.mult(a.pow_n(3)).div(new Exakt(27.))).
       	  					sub(a.mult(b).div(drei));
       // D^2 = (p/3)^3 + (q/2)^2
       Algebraic D = new Polynomial(new FunctionVariable("sqrt",
       	  					p.div(drei).pow_n(3).add(q.div(Zahl.TWO).pow_n(2))));
       Algebraic u = new Polynomial(new FunctionVariable("csqrt",
       	  					Zahl.MINUS.mult(q).div(Zahl.TWO).add(D)));
       Algebraic v = new Polynomial(new FunctionVariable("csqrt",
       	  					Zahl.MINUS.mult(q).div(Zahl.TWO).sub(D)));
       Algebraic r0   = Zahl.MINUS.mult(a).div(drei).add(u).add(v);
       Algebraic r1   = Zahl.MINUS.mult(a).div(drei).sub(u.add(v).div(Zahl.TWO));
       Algebraic w    = new Unexakt(Math.sqrt(3.)).mult(u.sub(v)).
       	  					div(Zahl.TWO).mult(Zahl.IONE);
       Algebraic r2	   = r1.sub(w);
       r1	   			   = r1.add(w);
       s.addElement(r0);
       s.addElement(r1);
       s.addElement(r2);
       break;*/
     default:
       // Maybe biquadratic/bicubic etc
       // Calculate gcd of exponents for nonzero coefficients
       int gcd = -1;
       for (int i = 1; i < coef.length; i++) {
         if (!coef[i].equals(Zahl.ZERO)) {
           if (gcd < 0) gcd = i;
           else gcd = gcd(i, gcd);
         }
       }
       int deg = degree() / gcd;
       if (deg < 3) { // Solveable
         Algebraic cn[] = new Algebraic[deg + 1];
         for (int i = 0; i < cn.length; i++) cn[i] = coef[i * gcd];
         Polynomial pr = new Polynomial(var, cn);
         Vektor sn = pr.solvepoly();
         if (gcd == 2) { // sol = +/-sqrt(sn)
           cn = new Algebraic[sn.coord.length * 2];
           for (int i = 0; i < sn.coord.length; i++) {
             cn[2 * i] = FunctionVariable.create("sqrt", sn.coord[i]);
             cn[2 * i + 1] = cn[2 * i].mult(Zahl.MINUS);
           }
         } else { // sol = sn^(1/gcd);
           cn = new Algebraic[sn.coord.length];
           Zahl wx = new Unexakt(1. / gcd);
           for (int i = 0; i < sn.coord.length; i++) {
             Algebraic exp = FunctionVariable.create("log", sn.coord[i]);
             cn[i] = FunctionVariable.create("exp", exp.mult(wx));
           }
         }
         return new Vektor(cn);
       }
       throw new JasymcaException("Can't solve expression " + this);
   }
   return Vektor.create(s);
 }
Exemplo n.º 5
0
  public Algebraic integrate(Variable var) throws JasymcaException {
    Algebraic in = Zahl.ZERO;
    for (int i = 1; i < coef.length; i++) {
      if (!coef[i].depends(var))
        if (var.equals(this.var))
          // c*x^n -->1/(n+1)*x^(n+1)
          in = in.add(coef[i].mult(new Polynomial(var).pow_n(i + 1).div(new Unexakt(i + 1))));
        else if (this.var instanceof FunctionVariable
            && ((FunctionVariable) this.var).arg.depends(var))
          // f(x)
          if (i == 1) in = in.add(((FunctionVariable) this.var).integrate(var).mult(coef[1]));
          // (f(x))^2, (f(x))^3 etc
          // give up here but try again after exponential normalization
          else throw new JasymcaException("Integral not supported.");
        else
          // Constant:  c --> c*x
          in = in.add(coef[i].mult(new Polynomial(var).mult(new Polynomial(this.var).pow_n(i))));
      else if (var.equals(this.var))
        // c(x)*x^n , should not happen if this is canonical
        throw new JasymcaException("Integral not supported.");
      else if (this.var instanceof FunctionVariable
          && ((FunctionVariable) this.var).arg.depends(var)) {
        if (i == 1 && coef[i] instanceof Polynomial && ((Polynomial) coef[i]).var.equals(var)) {
          // poly(x)*f(x)
          // First attempt: try to isolate inner derivative
          // poly(x)*f(w(x)) --> check poly(x)/w' == q : const?
          //           yes   --> Int f dw * q
          p("Trying to isolate inner derivative " + this);
          try {
            FunctionVariable f = (FunctionVariable) this.var;
            Algebraic w = f.arg; // Innere Funktion
            Algebraic q = coef[i].div(w.deriv(var));
            if (q.deriv(var).equals(Zahl.ZERO)) { // q - constant
              SimpleVariable v = new SimpleVariable("v");
              Algebraic p = FunctionVariable.create(f.fname, new Polynomial(v));
              Algebraic r = p.integrate(v).value(v, w).mult(q);
              in = in.add(r);
              continue;
            }
          } catch (JasymcaException je) {
            // Didn't work, try more methods
          }
          p("Failed.");

          // Some partial integrations follow. To
          // avoid endless loops, we flag this section

          // Coefficients of coef[i] must not depend on var
          for (int k = 0; k < ((Polynomial) coef[i]).coef.length; k++)
            if (((Polynomial) coef[i]).coef[k].depends(var))
              throw new JasymcaException("Function not supported by this method");

          if (loopPartial) {
            loopPartial = false;
            p("Partial Integration Loop detected.");
            throw new JasymcaException("Partial Integration Loop: " + this);
          }

          // First attempt: x^n*f(x) , n-times diff!
          // works for exp,sin,cos
          p("Trying partial integration: x^n*f(x) , n-times diff " + this);
          try {
            loopPartial = true;
            Algebraic p = coef[i];
            Algebraic f = ((FunctionVariable) this.var).integrate(var);
            Algebraic r = f.mult(p);
            while (!(p = p.deriv(var)).equals(Zahl.ZERO)) {
              f = f.integrate(var).mult(Zahl.MINUS);
              r = r.add(f.mult(p));
            }
            loopPartial = false;
            in = in.add(r);
            continue;
          } catch (JasymcaException je) {
            loopPartial = false;
          }
          p("Failed.");
          // Second attempt: x^n*f(x) , 1-times int!
          // works for log, atan
          p("Trying partial integration: x^n*f(x) , 1-times int " + this);
          try {
            loopPartial = true;
            Algebraic p = coef[i].integrate(var);
            Algebraic f = new Polynomial((FunctionVariable) this.var);
            Algebraic r = p.mult(f).sub(p.mult(f.deriv(var)).integrate(var));
            loopPartial = false;
            in = in.add(r);
            continue;
          } catch (JasymcaException je3) {
            loopPartial = false;
          }
          p("Failed");
          // Add more attempts....
          throw new JasymcaException("Function not supported by this method");
        } else throw new JasymcaException("Integral not supported.");
      } else // mainvar independend of var, treat as constant and integrate coef
      in = in.add(coef[i].integrate(var).mult(new Polynomial(this.var).pow_n(i)));
    }
    if (coef.length > 0) in = in.add(coef[0].integrate(var));
    return in;
  }