Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
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) 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{
40 template<typename Iterator, typename Skipper = ascii::space_type>
41 struct MpfrFloatParser : qi::grammar<Iterator, real_mp(), boost::spirit::ascii::space_type>
42 {
44 MpfrFloatParser() : MpfrFloatParser::base_type(root_rule_,"MpfrFloatParser")
45 {
46 using std::max;
47 namespace phx = boost::phoenix;
48 using qi::_1;
49 using qi::_2;
50 using qi::_3;
51 using qi::_4;
52 using qi::_val;
53
54 root_rule_.name("real_mp");
55 root_rule_ = mpfr_rules_.number_string_
56 [ phx::bind(
57 []
58 (real_mp & B, std::string const& P)
59 {
60 using std::max;
61 auto prev_prec = DefaultPrecision();
62 auto asdf = max(prev_prec,LowestMultiplePrecision());
63 auto digits = max(P.size(),static_cast<decltype(P.size())>(asdf));
64
65 B.precision(static_cast<unsigned>(digits));
66 B = real_mp(P,static_cast<unsigned>(digits));
67 },
68 _val,_1
69 )
70 ];
71
72 qi::on_error<qi::fail>(
74 phx::bind(&ReportParseError, _1, _2, _3, _4, std::string("MpfrFloatParser"))
75 );
76 }
77
78 qi::rule<Iterator, real_mp(), Skipper > root_rule_;
79 rules::LongNum<Iterator> mpfr_rules_;
80 };
81
82
84 template<typename Iterator, typename Skipper = ascii::space_type>
85 struct MpfrComplexParser : qi::grammar<Iterator, complex_mp(), boost::spirit::ascii::space_type>
86 {
88 MpfrComplexParser() : MpfrComplexParser::base_type(root_rule_,"MpfrComplexParser")
89 {
90 using std::max;
91 namespace phx = boost::phoenix;
92 using qi::_1;
93 using qi::_2;
94 using qi::_val;
95
98 [ phx::bind(
99 []
100 (complex_mp & B, real_mp const& P, real_mp const& Q)
101 {
102 auto digits = max(P.precision(),Q.precision());
103
104 B.precision(digits);
105
106 B.real(P);
107 B.imag(Q);
108 },
109 _val,_1,_2
110 )
111 ];
112 }
113
114 qi::rule<Iterator, complex_mp(), Skipper > root_rule_;
116 };
117
119 template <typename Iterator>
120 static bool parse(Iterator first, Iterator last, double& c)
121 {
122 using boost::spirit::qi::double_;
123 using boost::spirit::qi::_1;
124 using boost::spirit::qi::phrase_parse;
125 using boost::spirit::ascii::space;
126 using boost::phoenix::ref;
127
128 double rN = 0.0;
129 bool r = phrase_parse(first, last,
130 (
131 double_[ref(rN) = _1]
132 ),
133 space);
134
135 if (!r || first != last) // fail if we did not get a full match
136 return false;
137
138 c = rN;
139 return r;
140 }
141
143 template <typename Iterator>
144 static bool parse(Iterator first, Iterator last, std::complex<double>& c)
145 {
146 using boost::spirit::qi::double_;
147 using boost::spirit::qi::_1;
148 using boost::spirit::qi::phrase_parse;
149 using boost::spirit::ascii::space;
150 using boost::phoenix::ref;
151
152 double rN = 0.0;
153 double iN = 0.0;
154 bool r = phrase_parse(first, last,
155 (
156 double_[ref(rN) = _1]
157 >> -(double_[ref(iN) = _1])
158 | double_[ref(rN) = _1]
159 ),
160 space);
161
162 if (!r || first != last) // fail if we did not get a full match
163 return false;
164 c = std::complex<double>(rN, iN);
165 return r;
166 }
167
168
169
170
171
173 template <typename Iterator>
174 static bool parse(Iterator first, Iterator last, real_mp& c)
175 {
176 using boost::spirit::qi::double_;
177 using boost::spirit::qi::_1;
178 using boost::spirit::qi::phrase_parse;
179 using boost::spirit::ascii::space;
180 using boost::phoenix::ref;
181
183
184 real_mp rN {0};
185 bool r = phrase_parse(first, last,
186 S,
187 space,
188 rN
189 );
190
191 if (!r || first != last) // fail if we did not get a full match
192 return false;
193 c.precision(rN.precision());
194 c = rN;
195 return r;
196 }
197
198
199
200
201
203 template <typename Iterator>
204 static bool parse(Iterator first, Iterator last, complex_mp& c)
205 {
206 using boost::spirit::qi::double_;
207 using boost::spirit::qi::_1;
208 using boost::spirit::qi::phrase_parse;
209 using boost::spirit::ascii::space;
210 using boost::phoenix::ref;
211
213
214 complex_mp rN {};
215 bool r = phrase_parse(first, last,
216 S,
217 space,
218 rN);
219
220 if (!r || first != last) // fail if we did not get a full match
221 return false;
222 c.precision(rN.precision());
223 c = rN;
224 return r;
225 }
226
227 } // re: namespace classic
228
229
230
231 namespace cplusplus{
232
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
259 template <typename Iterator>
260 static bool parse(Iterator first, Iterator last, std::complex<double>& c)
261 {
262 using boost::spirit::qi::double_;
263 using boost::spirit::qi::_1;
264 using boost::spirit::qi::phrase_parse;
265 using boost::spirit::ascii::space;
266 using boost::phoenix::ref;
267
268 double rN = 0.0;
269 double iN = 0.0;
270 bool r = phrase_parse(first, last,
271 (
272 '(' >> double_[ref(rN) = _1]
273 >> -(',' >> double_[ref(iN) = _1]) >> ')'
274 | double_[ref(rN) = _1]
275 ),
276 space);
277
278 if (!r || first != last) // fail if we did not get a full match
279 return false;
280 c = std::complex<double>(rN, iN);
281 return r;
282 }
283 } // re: namespace cplusplus
284 } //re: namespace parsing
285} //re: namespace bertini
Definition classic_utilities.hpp:41
void ReportParseError(std::string::const_iterator begin, std::string::const_iterator end, std::string::const_iterator err_pos, boost::spirit::info const &what, std::string const &parser_name)
Report a parse error (via FormatParseError) to the log, for use in a Spirit on_error handler.
Definition qi_files.hpp:199
bool parse(Iterator first, Iterator last, std::shared_ptr< bertini::node::Node > &func)
Parse a function expression from the iterator range into a node tree.
Definition function_parsers.hpp:46
Definition number_parsers.hpp:231
static bool parse(Iterator first, Iterator last, double &c)
Parse a double from the iterator range.
Definition number_parsers.hpp:235
Definition classic_utilities.hpp:40
T max(T const &a, T const &b, T const &c)
Three-argument form of max.
Definition mpfr_extensions.hpp:96
Definition algorithm_builder.hpp:36
bmp::number< mpc_complex_backend< 0 >, bmp::et_on > complex_mp
The arbitrary-precision complex number type.
Definition mpfr_complex.hpp:58
auto DefaultPrecision()
Get the global default precision (digits) for multiprecision numbers.
Definition mpfr_complex.hpp:135
boost::multiprecision::number< boost::multiprecision::mpfr_float_backend< 0 >, boost::multiprecision::et_on > real_mp
The arbitrary-precision real number type.
Definition mpfr_extensions.hpp:53
constexpr unsigned LowestMultiplePrecision()
The lowest multiple-precision digit count used (20).
Definition num_traits.hpp:159
Provides the parsersing rules for numbers in bertini2.
A Qi grammar parsing a complex multiprecision number (real then imaginary part).
Definition number_parsers.hpp:86
MpfrFloatParser< Iterator > mpfr_float_
The real-part parser, used for both components.
Definition number_parsers.hpp:115
MpfrComplexParser()
Construct the complex-multiprecision parser.
Definition number_parsers.hpp:88
qi::rule< Iterator, complex_mp(), Skipper > root_rule_
The grammar's root rule.
Definition number_parsers.hpp:114
A Qi grammar parsing a real multiprecision number, at a precision matching the input's digits.
Definition number_parsers.hpp:42
MpfrFloatParser()
Construct the real-multiprecision parser.
Definition number_parsers.hpp:44
rules::LongNum< Iterator > mpfr_rules_
Sub-rules matching arbitrary-length number strings.
Definition number_parsers.hpp:79
qi::rule< Iterator, real_mp(), Skipper > root_rule_
The grammar's root rule.
Definition number_parsers.hpp:78