Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
number_parsers.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//bertini2/io/parsers.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//bertini2/io/parsing/number_parsers.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with bertini2/io/parsing/number_parsers.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2017 by Bertini2 Development Team
17//
18// See <http://www.gnu.org/licenses/> for a copy of the license,
19// as well as COPYING. Bertini2 is provided with permitted
20// additional terms in the b2/licenses/ directory.
21
22
28
29#pragma once
30
32
33
34
35namespace bertini{
36 namespace parsing{
37
38 namespace classic{
39 template<typename Iterator, typename Skipper = ascii::space_type>
40 struct MpfrFloatParser : qi::grammar<Iterator, mpfr_float(), boost::spirit::ascii::space_type>
41 {
42 MpfrFloatParser() : MpfrFloatParser::base_type(root_rule_,"MpfrFloatParser")
43 {
44 using std::max;
45 namespace phx = boost::phoenix;
46 using qi::_1;
47 using qi::_2;
48 using qi::_3;
49 using qi::_4;
50 using qi::_val;
51
52 root_rule_.name("mpfr_float");
53 root_rule_ = mpfr_rules_.number_string_
54 [ phx::bind(
55 []
56 (mpfr_float & B, std::string const& P)
57 {
58 using std::max;
59 auto prev_prec = DefaultPrecision();
60 auto asdf = max(prev_prec,LowestMultiplePrecision());
61 auto digits = max(P.size(),static_cast<decltype(P.size())>(asdf));
62
63 B.precision(digits);
64 B = mpfr_float(P,digits);
65 },
66 _val,_1
67 )
68 ];
69
70 using phx::val;
71 using phx::construct;
72 using namespace qi::labels;
73 qi::on_error<qi::fail>
74 ( root_rule_ ,
75 std::cout<<
76 val("mpfr_float parser could not complete parsing. Expecting ")<<
77 _4<<
78 val(" here: ")<<
79 construct<std::string>(_3,_2)<<
80 std::endl
81 );
82 }
83
84 qi::rule<Iterator, mpfr_float(), Skipper > root_rule_;
85 rules::LongNum<Iterator> mpfr_rules_;
86 };
87
88
89 template<typename Iterator, typename Skipper = ascii::space_type>
90 struct MpfrComplexParser : qi::grammar<Iterator, mpfr_complex(), boost::spirit::ascii::space_type>
91 {
92 MpfrComplexParser() : MpfrComplexParser::base_type(root_rule_,"MpfrComplexParser")
93 {
94 using std::max;
95 namespace phx = boost::phoenix;
96 using qi::_1;
97 using qi::_2;
98 using qi::_val;
99
100 root_rule_ =
101 (mpfr_float_ >> mpfr_float_)
102 [ phx::bind(
103 []
104 (mpfr_complex & B, mpfr_float const& P, mpfr_float const& Q)
105 {
106 auto prev_prec = DefaultPrecision();
107 auto digits = max(P.precision(),Q.precision());
108
109 B.precision(digits);
110
111 B.real(P);
112 B.imag(Q);
113 },
114 _val,_1,_2
115 )
116 ];
117 }
118
119 qi::rule<Iterator, mpfr_complex(), Skipper > root_rule_;
120 MpfrFloatParser<Iterator> mpfr_float_;
121 };
122
123 template <typename Iterator>
124 static bool parse(Iterator first, Iterator last, double& c)
125 {
126 using boost::spirit::qi::double_;
127 using boost::spirit::qi::_1;
128 using boost::spirit::qi::phrase_parse;
129 using boost::spirit::ascii::space;
130 using boost::phoenix::ref;
131
132 double rN = 0.0;
133 bool r = phrase_parse(first, last,
134 (
135 double_[ref(rN) = _1]
136 ),
137 space);
138
139 if (!r || first != last) // fail if we did not get a full match
140 return false;
141
142 c = rN;
143 return r;
144 }
145
146 template <typename Iterator>
147 static bool parse(Iterator first, Iterator last, std::complex<double>& c)
148 {
149 using boost::spirit::qi::double_;
150 using boost::spirit::qi::_1;
151 using boost::spirit::qi::phrase_parse;
152 using boost::spirit::ascii::space;
153 using boost::phoenix::ref;
154
155 double rN = 0.0;
156 double iN = 0.0;
157 bool r = phrase_parse(first, last,
158 (
159 double_[ref(rN) = _1]
160 >> -(double_[ref(iN) = _1])
161 | double_[ref(rN) = _1]
162 ),
163 space);
164
165 if (!r || first != last) // fail if we did not get a full match
166 return false;
167 c = std::complex<double>(rN, iN);
168 return r;
169 }
170
171
172
173
174
175 template <typename Iterator>
176 static bool parse(Iterator first, Iterator last, mpfr_float& c)
177 {
178 using boost::spirit::qi::double_;
179 using boost::spirit::qi::_1;
180 using boost::spirit::qi::phrase_parse;
181 using boost::spirit::ascii::space;
182 using boost::phoenix::ref;
183
184 MpfrFloatParser<Iterator> S;
185
186 mpfr_float rN {0};
187 bool r = phrase_parse(first, last,
188 S,
189 space,
190 rN
191 );
192
193 if (!r || first != last) // fail if we did not get a full match
194 return false;
195 c.precision(rN.precision());
196 c = rN;
197 return r;
198 }
199
200
201
202
203
204 template <typename Iterator>
205 static bool parse(Iterator first, Iterator last, mpfr_complex& c)
206 {
207 using boost::spirit::qi::double_;
208 using boost::spirit::qi::_1;
209 using boost::spirit::qi::phrase_parse;
210 using boost::spirit::ascii::space;
211 using boost::phoenix::ref;
212
213 MpfrComplexParser<Iterator> S;
214
215 mpfr_complex rN {};
216 bool r = phrase_parse(first, last,
217 S,
218 space,
219 rN);
220
221 if (!r || first != last) // fail if we did not get a full match
222 return false;
223 c.precision(rN.precision());
224 c = rN;
225 return r;
226 }
227
228 } // re: namespace classic
229
230
231
232 namespace cplusplus{
233
234 template <typename Iterator>
235 static bool parse(Iterator first, Iterator last, double& c)
236 {
237 using boost::spirit::qi::double_;
238 using boost::spirit::qi::_1;
239 using boost::spirit::qi::phrase_parse;
240 using boost::spirit::ascii::space;
241 using boost::phoenix::ref;
242
243 double rN = 0.0;
244 bool r = phrase_parse(first, last,
245 (
246 double_[ref(rN) = _1]
247 ),
248 space);
249
250 if (!r || first != last) // fail if we did not get a full match
251 return false;
252
253 c = rN;
254 return r;
255 }
256
257
258 template <typename Iterator>
259 static bool parse(Iterator first, Iterator last, std::complex<double>& c)
260 {
261 using boost::spirit::qi::double_;
262 using boost::spirit::qi::_1;
263 using boost::spirit::qi::phrase_parse;
264 using boost::spirit::ascii::space;
265 using boost::phoenix::ref;
266
267 double rN = 0.0;
268 double iN = 0.0;
269 bool r = phrase_parse(first, last,
270 (
271 '(' >> double_[ref(rN) = _1]
272 >> -(',' >> double_[ref(iN) = _1]) >> ')'
273 | double_[ref(rN) = _1]
274 ),
275 space);
276
277 if (!r || first != last) // fail if we did not get a full match
278 return false;
279 c = std::complex<double>(rN, iN);
280 return r;
281 }
282 } // re: namespace cplusplus
283 } //re: namespace parsing
284} //re: namespace bertini
T max(T const &a, T const &b, T const &c)
Three-argument form of max.
Definition mpfr_extensions.hpp:98
Provides the parsersing rules for numbers in bertini2.