Beispiel #1
0
Expression Expression::operator-() const {
  // checkWellFormed();
  if (kindIs("constant")) {
    return -value;
  } else if (kindIs("*/") && name == "*" && arg1->kindIs("constant")) {
    return (-arg1->value) * *arg2;
  } else if (kindIs("*/") && name == "/" && arg1->kindIs("constant")) {
    return (-arg1->value) / *arg2;
  } else if (kindIs("*/") && name == "*" && arg2->kindIs("constant")) {
    return *arg1 * (-arg2->value);
  } else if (kindIs("*/") && name == "/" && arg2->kindIs("constant")) {
    return *arg1 / (-arg2->value);
  //} else if (kindIs("+-") && name == "+") {
  //  return (-*arg1) + (-*arg2);
  } else if (kindIs("unary") && name == "-") {
    return *arg1;
  }
  Expression out;
  out.name = "-";
  out.kind = "unary";
  out.type = type;
  out.arg1 = new Expression(*this);
  out.SetDepth();
  // out.checkWellFormed();
  return out;
}
Beispiel #2
0
Expression Expression::method(const std::string n) const {
  Expression out;
  out.kind = "method";
  out.name = "." + n + "(";
  out.arg1 = new Expression(*this);
  out.type = type; // default to methods not changing types
  out.SetDepth();
  return out;
}
Beispiel #3
0
Expression Expression::operator()(const Expression &e) const {
  Expression out;
  out.name = "(";
  out.kind = "method";
  out.arg1 = new Expression(*this);
  out.arg2 = new Expression(e);
  out.SetDepth();
  return out;
}
Beispiel #4
0
Expression linearfunexprgd(const char *n, const char *type, const Expression &arg) {
  if (arg.kindIs("constant") && arg.value == 0)
    return Expression(0); // Nice optimization!  :)
  Expression newarg(arg);
  Expression prefactor = newarg.ScalarFactor();

  Expression out = funexpr(n, newarg);
  out.kind = "linear function";
  out.name = std::string(n) + "(gd, ";
  out.unlazy = true;
  out.type = type;
  out.SetDepth();
  return prefactor*out;
}
Beispiel #5
0
Expression Expression::operator+(const Expression &e) const {
  if (kindIs("constant") && value == 0) {
    return e;
  } else if (e.kindIs("constant") && e.value == 0) {
    return *this;
  } else if (e.kindIs("constant") && kindIs("constant")) {
    return Expression(value+e.value);
  }
  Expression thispost(*this), epost(e);
  Expression thispre = thispost.ScalarFactor(), epre = epost.ScalarFactor();
  if (thispost.kindIs("linear function") && epost.kindIs("linear function") &&
      thispost.name == epost.name) {
    if (thispre == epre) {
      Expression out = linearfunexprgd("oops", thispost.type, *thispost.arg1 + *epost.arg1);
      out.name = thispost.name;
      return epre*out;
    }
    if (thispre == -epre && thispre != Expression(1)) {
      Expression out = linearfunexprgd("oops", thispost.type, *thispost.arg1 - *epost.arg1);
      out.name = thispost.name;
      return thispre*out;
    }
    Expression out = linearfunexprgd("oops", thispost.type,
                                     thispre * *thispost.arg1 + epre * *epost.arg1);
    out.name = thispost.name;
    return out;
  }
  Expression out;
  if (typeIs("ReciprocalGrid")) {
    assert(!e.typeIs("Grid"));
    out.type = "ReciprocalGrid";
  } else if (typeIs("Grid")) {
    assert(!e.typeIs("ReciprocalGrid"));
  } else if (e.typeIs("double")) {
    out.type = "double";
  } else if (e.typeIs("ReciprocalGrid")) {
    out.type = "ReciprocalGrid";
  }
  out.name = "+";
  out.kind = "+-";
  out.arg1 = new Expression(*this);
  out.arg2 = new Expression(e);
  out.SetDepth();
  return out;
}
Beispiel #6
0
Expression Expression::operator/(const Expression &e) const {
  // First, let's make a few optimizations...
  if (kindIs("constant") && value == 0) {
    return *this;
  } else if (e.kindIs("constant") && e.value == 1) {
    return *this;
  } else if (e.kindIs("constant") && e.value == -1) {
    return - *this;
  } else if (e.kindIs("constant") && kindIs("constant")) {
    return Expression(value/e.value);
  } else if (e.kindIs("*/") && e.name == "/") {
    return *this * *e.arg2 / *e.arg1; // inverse of inverse
  }
  //Expression postfactor = e;
  //Expression prefactor = postfactor.ScalarFactor();
  //if (postfactor.kindIs("*/") && postfactor.name == "/") {
  //  return (*this / prefactor) * *postfactor.arg2 / *postfactor.arg1;
  //}
  Expression out;
  if (typeIs("ReciprocalGrid")) {
    assert(!e.typeIs("Grid"));
    out.type = "ReciprocalGrid";
  } else if (typeIs("Grid")) {
    assert(!e.typeIs("ReciprocalGrid"));
  } else if (typeIs("ReciprocalGrid")) {
    out.type = "ReciprocalGrid";
  } else if (e.typeIs("double") && typeIs("double")) {
    out.type = "double";
  } else if (e.typeIs("ReciprocalGrid")) {
    out.type = "ReciprocalGrid";
  }
  out.name = "/";
  out.kind = "*/";
  out.arg1 = new Expression(*this);
  out.arg2 = new Expression(e);
  out.SetDepth();
  return out;
}
Beispiel #7
0
Expression Expression::operator*(const Expression &e) const {
  // checkWellFormed();
  // e.checkWellFormed();
  if (kindIs("constant") && e.kindIs("constant")) {
    return Expression(value*e.value);
  } else if (e.kindIs("constant")) {
    // prefer to have scalar on left.
    return e*(*this);
  }
  // First, let's make a few optimizations...
  if (kindIs("constant") && value == 1) {
    return e;
  } else if (kindIs("constant") && value == -1) {
    return -e;
  } else if (kindIs("constant") && value == 0) {
    return *this;
  } else if (e.kindIs("unary") && e.name == "-") {
    return - (*this * *e.arg1);
  }
  Expression out;
  if (e.typeIs("ReciprocalGrid")) {
    assert(!typeIs("Grid"));
    out.type = "ReciprocalGrid";
  } else if (typeIs("ReciprocalGrid")) {
    out.type = "ReciprocalGrid";
  } else if (e.typeIs("Grid")) {
    assert(!e.typeIs("ReciprocalGrid"));
  } else if (e.typeIs("double") && typeIs("double")) {
    out.type = "double";
  }
  out.name = "*";
  out.kind = "*/";
  out.arg1 = new Expression(*this);
  out.arg2 = new Expression(e);
  out.SetDepth();
  return out;
}
Beispiel #8
0
Expression Expression::method(const char *n, const Expression &a) const {
  Expression out = method(n);
  out.arg2 = new Expression(a);
  out.SetDepth();
  return out;
}
Beispiel #9
0
Expression funexpr(const char *n, const Expression &arg, const Expression &a2, const Expression &a3) {
  Expression out = funexpr(n, arg, a2);
  out.arg3 = new Expression(a3);
  out.SetDepth();
  return out;
}
Beispiel #10
0
Expression funexpr(const char *n, const Expression &arg) {
  Expression out = funexpr(n);
  out.arg1 = new Expression(arg);
  out.SetDepth();
  return out;
}
Beispiel #11
0
Expression Expression::method(const char *n, const Expression &a, const Expression &b) const {
  Expression out = method(n, a);
  out.arg3 = new Expression(b);
  out.SetDepth();
  return out;
}