2

I found these two libraries: - muparser - symbolicc++

The first one is capable of efficient parsing of mathematical expression, so that with minimal wrapping I could make a parser object so that

parser my_parser("1/2 * x^2");
cout<<myparser(2)<<endl;

Would result in it printing 2.0. This is wonderful, but it only works with doubles, right?

The second one implements the Symbolic object so that on example I can do something like:

Symbolic x("x");
Symbolic x2 = x^2;
cout<<df(x2, x)<<endl;

Resulting in 2.0*x. So it is capable of differentiating expressions, which is fine.

What I would need to do is a mix of the two! I need a function to be parsed and then differentiated, so that I could do something like:

 cout<<df("1/2 * x^2", "x")<<endl;

And I would like it to print out 2.0*x as well.

Is it possible to do something like this? In principle, if muparser could work on any object, I could simply run an expression on Symbolic objects, and then differentiate them. But I couldn't make something like this work.

So is there any other workaround? I need something that takes an input string with an expression and returns an output string with the derivative of that expression.

Thank you!

Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • I don't think that you can use muparser for that - I believe it hasn't the appropriate callbacks, it only constructs the expression internally. You should look at something like http://stackoverflow.com/questions/11703082/parsing-math-expression-in-c-c – LSerni Oct 17 '14 at 18:20
  • Well... I am not familiar with parsing trees and grammars.. is there any easier way to do it? Doing that wasn't my specific aim, so if there is something that could simply work that would be awesome.. – Matteo Monti Oct 17 '14 at 19:06

1 Answers1

2

This isn't a complete answer since, as they say, TMTOWTDI. However, to be able to use Symbolic++ you need to have program-level access... that is, you can't really write and compile

Symbolic x("x");
Symbolic x2 = x^2;

but you need something on the order of (but waaaaay more flexible than)

if (there_is_x_symbol) {
    expr = Symbolic x("x");
}
if (raise_to_the_2nd_power) {
    expr = expr^2;
}

To do this in a organic way you need a parser, and a parser that will not simply export an evaluate() method but something that will allow you access to the expression tree, for example

     ( multiply )
      /        \
  ( 2 )       ( square )
                 \
                ( x )

This you could evaluate recursively:

left = myEvaluate(node.left)
right = myEvaluate(node.right)
if (node.op == multiply) {
    return left * right;
}
if (node.op == square ) {
    return right ^ 2;
}
...

The muparser (and muparserX) libraries do not seem to allow this.

There are several other algebraic parsers out there, for example this looks promising. You can use the supplier Parser algorithm, and write an Evaluator of your own that uses Symbolic++ and outputs a Symbolic++ expression.

You do not need a deep knowledge of grammars to hack at such a parser - most will just generate a Reverse Polish Notation stack, and that's all you really need to know about.

In bocca al lupo :-)

LSerni
  • 55,617
  • 10
  • 65
  • 107