Re: [Boost-users] [proto] generation of adaptive precision floating-point geometric predicates

Hi Andrew, just my thoughts on this chat. Andrew Durward schrieb:
The central concept is that for any expression (a # b) where # is {+, -, *}, the result can be expressed as (x + y) where x is the floating-point
How about transform the expression a+b to sum_approx(a,b)+sum_diff(a,b)
instead to fusion::cons
approximation of (a # b), and y is an error term whose value can also be computed as a floating-point value.
In toying with proto, I've been able to transform simple expressions successfully but I can't seem to figure out how to define a grammar that will handle arbitrary combinations of {+, -, *} recursively. Here's what I've got so far:
struct sum_approx{/* */}; struct sum_error{/* */};
struct diff_approx{/* */}; struct diff_error{/* */};
struct prod_approx{/* */}; struct prod_error{/* */};
struct Transform : proto::or_< proto::when< proto::plus< proto::terminal< _ >, proto::terminal< _ > > , fusion::cons< proto::_make_function( sum_approx() , proto::_left , proto::_right )
I dont see the meaning behind this step. If you use proto::_make_function you create a child in the ast, but you put this child in a fusion::cons.
, fusion::cons< proto::_make_function( sum_error() , proto::_left , proto::_right ) > >() > // ... similar substitutions for minus and multiplies > {};
So the expression (a + b) yields the sequence: sum_approx(a,b) sum_error(a,b)
Here's where I'm stuck. In the case of the expression (a + b)*(c - d), the addition and subtraction should be replaced by the appropriate sequences before the multiplication gets expanded to yield the final sequence: prod_approx( sum_approx(a,b), diff_approx(c,d) ) prod_error( sum_approx(a,b), diff_approx(c,d) ) prod_approx( sum_approx(a,b), diff_error(c,d) ) prod_error( sum_approx(a,b), diff_error(c,d) ) prod_approx( sum_error(a,b), diff_approx(c,d) ) prod_error( sum_error(a,b), diff_approx(c,d) ) prod_approx( sum_error(a,b), diff_error(c,d) ) prod_error( sum_error(a,b), diff_error(c,d) )
Are you sure that you want to get a sequence of expression instead an ast. In case you really want to get a sequence you can use proto::tag::comma to separate your child.
Obviously I need a recursive transform here but I'm not sure how to pass it the sequences generated by both the left and right subtrees.
Cheers,
Kim
Here is a toy project.
Hth.
# include

Hi Kim, Thanks very much for your response and the sample code.
How about transform the expression a+b to sum_approx(a,b)+sum_diff(a,b) instead to fusion::cons
> ? The advantage of this approach is that you still get an ast where childs are held in terminal (instead in cons).
You are correct that the elements being generated will represent terms to be summed together. My rationale for choosing to represent them as a sequence rather than a tree was to make it easier to modify the order in which the summation is performed. Namely, I plan to sort the terms according to their expected magnitude so that I can add them up until the magnitude of the result exceeds the maximum possible magnitude of the error (hence guaranteeing that the sign is correct). The value of any remaining terms should never actually be computed. Having said that, if it makes life easier to generate an AST with an n-ary "sum" function rather than a sequence or a deep tree of binary "plus" nodes, then that would be fine too. The final tree should then consist of a single "sum" node with a long list of terms.
I dont see the meaning behind this step. If you use proto::_make_function you create a child in the ast, but you put this child in a fusion::cons.
Yes, exactly. The resulting sequence should consist of AST nodes that can be evaluated one by one until the stop condition is reached.
Are you sure that you want to get a sequence of expression instead an ast. In case you really want to get a sequence you can use proto::tag::comma to separate your child.
Yes, I think so -- but that doesn't exclude the possibility that I'm going about this in completely the wrong way :)
Here is a toy project. Hth.
Thanks again for taking the time to respond. andrew
participants (2)
-
Andrew Durward
-
Kim Kuen Tang