Could you please point me to an algorithm that takes a (binary) parse tree for evaluating a polynomial expression in a single variable and returns an equivalent parse tree that evaluates the polynomial according to Horner’s rule.
The intended use case is in expression templates. The idea is that for a matrix x the parse tree obtained from
a + bx + c * x*x + d * x*x*x...
will get optimized into the corresponding parse tree of
a + x *( b + x( c + x*d))
You can get the monomial coefficients of the tree by a recursive function. Converting these coefficients and getting an expression according to Horner’s law would be simple.
I can give you a simple recursive function that computes these values, even though a more efficient one may exist.
Theoretical stuff
First, let’s formulate expressions. An expression
E:can be written as an (n+1)-ary tuple:
Then, we define two operations:
Addition: Given two expressions
E1 = (a0, ..., an)andE2 = (b0, ..., bm), the corresponding tuple ofE1 + E2is:that is, there are
max(n,m)+1elements, and theith element is computed by (with a C-ish syntax):Multiplication: Given two expressions
E1 = (a0, ..., an)andE2 = (b0, ..., bm), the corresponding tuple ofE1 * E2is:that is, there are
n+m+1elements, and theith element is computed byThe recursive function is therefore defined as follows:
where
Note: in the implementation of
mul,jshould iterate from0toi, while the following conditions must also hold:Therefore,
jcan go frommax(0,i-m)andmin(i,n)(which is equal tonsincen <= i)C++ implementation
Now that you have the pseudo-code, the implementation shouldn’t be hard. For the tuple type, a simple
std::vectorwould suffice. Therefore:Note: this code is untested. It may contain bugs or insufficient error checking. Make sure you understand it and implement it yourself, rather than copy-paste.
From here on, you just need to build an expression tree from the values this function gives you.