31#if defined(MPolynomialReader_RECURSES)
32#error Recursive header files inclusion detected in MPolynomialReader.h
35#define MPolynomialReader_RECURSES
37#if !defined MPolynomialReader_h
39#define MPolynomialReader_h
44#include "DGtal/base/Common.h"
45#include "DGtal/math/MPolynomial.h"
46#include <boost/spirit/include/qi.hpp>
47#include <boost/spirit/include/phoenix_core.hpp>
48#include <boost/spirit/include/phoenix_operator.hpp>
49#include <boost/spirit/include/phoenix_fusion.hpp>
50#include <boost/spirit/include/phoenix_stl.hpp>
51#include <boost/fusion/include/adapt_struct.hpp>
52#include <boost/variant/recursive_variant.hpp>
86 boost::variant< boost::recursive_wrapper<top_node>,
monomial_node >
94 std::vector<char>
ops;
107BOOST_FUSION_ADAPT_STRUCT(
117BOOST_FUSION_ADAPT_STRUCT(
120 (std::vector<DGtal::detail::power_node>, powers)
127BOOST_FUSION_ADAPT_STRUCT(
129 (std::vector<char>, ops)
130 (std::vector<DGtal::detail::expr_node>, expressions)
136 namespace qi = boost::spirit::qi;
137 namespace ascii = boost::spirit::ascii;
138 namespace phoenix = boost::phoenix;
147 template <
typename Iterator>
149 : qi::grammar<Iterator, detail::top_node(), ascii::space_type>
161 using phoenix::push_back;
164 mulexpr [push_back(at_c<1>(_val), _1)]
165 >> *( ( lit(
'+') [ push_back(at_c<0>(_val),
'+') ]
166 >>
mulexpr [push_back(at_c<1>(_val), _1)] )
167 | ( ( lit(
'-') [ push_back(at_c<0>(_val),
'-') ]
168 >>
mulexpr [push_back(at_c<1>(_val), _1)] ) ) );
171 subexpr [push_back(at_c<1>(_val), _1)]
172 >> *( ( lit(
'*') [ push_back(at_c<0>(_val),
'*') ]
173 >>
mulexpr [push_back(at_c<1>(_val), _1)] ) );
180 lit(
'(') [ push_back(at_c<0>(_val),
'^') ]
181 >> top [ push_back(at_c<1>(_val), _1) ]
183 >> ( ( lit(
'^') >> int_ [ at_c<2>(_val) = _1 ] )
184 | eps [ at_c<2>(_val) = 1 ] ) ;
187 ( double_ [at_c<0>(_val) = _1]
188 >> *(
genvariable [push_back(at_c<1>(_val), _1)] ) )
190 >> eps [at_c<0>(_val) = 1] );
196 >> int_ [at_c<0>(_val) = _1]
197 >> ( ( lit(
'^') >> int_ [at_c<1>(_val) = _1] )
198 | eps [at_c<1>(_val) = 1]
201 ( lit(
'x') [at_c<0>(_val) = 0]
202 | lit(
'y') [at_c<0>(_val) = 1]
203 | lit(
'z') [at_c<0>(_val) = 2]
204 | lit(
't') [at_c<0>(_val) = 3] )
205 >> ( ( lit(
'^') >> int_ [at_c<1>(_val) = _1] )
206 | eps [at_c<1>(_val) = 1]
255 template <
int n,
typename TRing,
256 typename TAlloc = std::allocator<TRing>,
257 typename TIterator = std::string::const_iterator>
286 using qi::phrase_parse;
289 bool r = phrase_parse( begin, end,
gpolynomial, space, m );
290 if (r) p =
make( m );
291 return r ? begin : end;
330 if ( mnode.
powers.size() != 0 )
333 for (
unsigned int i = 1; i < mnode.
powers.size(); ++i )
371 if ( topnode.
ops.empty() )
374 boost::apply_visitor( emaker, topnode.
expressions[ 0 ] );
377 else if ( topnode.
ops[ 0 ] ==
'^' )
380 boost::apply_visitor( emaker, topnode.
expressions[ 0 ] );
382 for (
unsigned int i = 1; i <= (
unsigned int)topnode.
exp; ++i )
389 boost::apply_visitor( emaker, topnode.
expressions[ 0 ] );
391 for (
unsigned int i = 0; i < (
unsigned int)topnode.
ops.size(); ++i )
393 boost::apply_visitor( emaker, topnode.
expressions[ i+1 ] );
394 switch ( topnode.
ops[ i ] ) {
395 case '+': p += emaker.
myP;
break;
396 case '-': p -= emaker.
myP;
break;
397 case '*': p *= emaker.
myP;
break;
398 default: std::cerr <<
"[UNKNOWN-node]" << topnode.
ops[ i ] << std::endl;
422 template <
int n,
typename TRing,
typename TAlloc,
typename TIterator>
454 template <
int n,
typename TRing,
class TAlloc >
464#include "DGtal/io/readers/MPolynomialReader.ih"
471#undef MPolynomialReader_RECURSES
Aim: This class converts a string polynomial expression in a multivariate polynomial.
Grammar gpolynomial
Polynomial grammar.
MPolynomial< n, Ring, Alloc > Polynomial
Polynomial make(const detail::power_node &pnode)
void selfDisplay(std::ostream &out) const
Polynomial make(const detail::top_node &topnode)
Iterator read(Polynomial &p, Iterator begin, Iterator end)
MPolynomialGrammar< Iterator > Grammar
Polynomial make(const detail::monomial_node &mnode)
Aim: Represents a multivariate polynomial, i.e. an element of , where K is some ring or field.
boost::variant< boost::recursive_wrapper< top_node >, monomial_node > expr_node
DGtal is the top-level namespace which contains all DGtal functions and types.
MPolynomial< n, Ring, Alloc > Xe_k(unsigned int k, unsigned int e)
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)
void operator>>(const Display3D< Space, KSpace > &aDisplay3D, DGtal::Mesh< typename Display3D< Space, KSpace >::RealPoint > &aMesh)
qi::rule< Iterator, detail::power_node(), ascii::space_type > genvariable
qi::rule< Iterator, detail::top_node(), ascii::space_type > expexpr
qi::rule< Iterator, detail::expr_node(), ascii::space_type > subexpr
qi::rule< Iterator, detail::top_node(), ascii::space_type > top
qi::rule< Iterator, detail::top_node(), ascii::space_type > mulexpr
qi::rule< Iterator, detail::monomial_node(), ascii::space_type > monomial
qi::rule< Iterator, detail::power_node(), ascii::space_type > variable
qi::rule< Iterator, detail::power_node(), ascii::space_type > litvariable
void operator()(const detail::monomial_node &mnode)
void operator()(const detail::top_node &topnode)
ExprNodeMaker(MPolynomialReader &reader)
std::vector< power_node > powers
std::vector< expr_node > expressions
the sub-expressions (one more than ops).
std::vector< char > ops
the operation(s), or '^' to designate (expr) or ( expr )^k