views:

173

answers:

6

I was working on my advanced calculus homework today and we're doing some iteration methods along the lines of newton's method to find solutions to things like x^2=2. It got me thinking that I could write a function that would take two function pointers, one to the function itself and one to the derivative and automate the process. This wouldn't be too challenging, then I started thinking could I have the user input a function and parse that input (yes I can do that). But can I then dynamically create a pointer to a one-variable function in c++. For instance if x^2+x, can I make a function double function(double x){ return x*x+x;} during run-time. Is this remotely feasible, or is it along the lines of self-modifying code?

Edit:

So I suppose how this could be done if you stored the information in an array and that had a function that evaluated the information stored in this array with a given input. Then you could create a class and initialize the array inside of that class and then use the function from there. Is there a better way?

+3  A: 
Roger Pate
That only works for polynomials... what if the expression is `x^x`?
Peter Alexander
@Peter: That's true.
Roger Pate
+3  A: 

You can't dynamically create a function in the sense that you can generate raw machine code for it, but you can quite easily create mathematical expressions using polymorphism:

struct Expr
{
  virtual double eval(double x) = 0;
};

struct Sum : Expr
{
  Sum(Expr* a, Expr* b):a(a), b(b) {}
  virtual double eval(double x) {return a->eval(x) + b->eval(x);}
private:
  Expr *a, *b;
};

struct Product : Expr
{
  Product(Expr* a, Expr* b):a(a), b(b) {}
  virtual double eval(double x) {return a->eval(x) * b->eval(x);}
private:
  Expr *a, *b;
};

struct VarX : Expr
{
  virtual double eval(double x) {return x;}
};

struct Constant : Expr
{
  Constant(double c):c(c) {}
  virtual double eval(double x) {return c;}
private:
  double c;
};

You can then parse your expression into an Expr object at runtime. For example, x^2+x would be Expr* e = new Sum(new Product(new VarX(), new VarX()), new VarX()). You can then evaluate that for a given value of x by using e->eval(x).

Note: in the above code, I have ignored const-correctness for clarity -- you should not :)

Peter Alexander
+1  A: 

You don't really need self modifiying code for that. But you will be writing what comes down to an expression parser and interpreter. You write the code to parse your function into suitable data structures (e.g. trees). For a given input you now traverse the tree and calculate the result of the function. Calculation can be done through a visitor.

Harald Scheirich
+4  A: 

As others have said, you cannot create new C++ functions at runtime in any portable way. You can however create an expression evaluator that can evaluate things like:

 (1 + 2) * 3

contained in a string, at run time. It's not difficult to expand such an evaluator to have variables and functions.

anon
A: 

You don't need to know assembly. Write c++ code for the possible expressions, and then write a compiler which examines the expression and choose the appropriate code snippets. That could be done at runtime like an interpreter usually does, or it could be a compile phase which creates code to execute by copying the instructions from each expression evaluation into allocated memory and then sets it up as a function. The latter is harder to understand and code, but will perform better. But for the development time plus execution time to be less than an interpreted implementation, the compiled code would have to be used lots (billions) of times.

wallyk
A: 

As others have mentioned. Writing self-modifying code isn't necessary at all and is painfull in a compiled language if you want it to be portable. The hardest part of your work is parsing the input. I recommend muParser to evaluate your expressions. It should take away a lot of pain and you would be able to focus on the important part of your project.

pmr