Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
generators.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//bertini2/io/generators.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/generators.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/generators.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
27
28#pragma once
29
30
33
34#include <boost/math/special_functions/modf.hpp>
35
36BOOST_MATH_STD_USING
37
38#include <boost/fusion/adapted.hpp>
39#include <boost/fusion/include/adapted.hpp>
40
42#define BOOST_SPIRIT_USE_PHOENIX_V3 1
43
44#include <boost/spirit/include/qi.hpp>
45#include <boost/spirit/include/karma.hpp>
46#include <boost/phoenix/core.hpp>
47#include <boost/phoenix/operator.hpp>
48#include <boost/fusion/include/std_pair.hpp>
49
50
51#include <boost/spirit/include/support_istream_iterator.hpp>
52
53
54
55// BOOST_FUSION_ADAPT_ADT(
56// std::complex<double>,
57// (bool, bool, obj.imag() != 0, /**/)
58// (double, double, obj.real(), /**/)
59// (double, double, obj.imag(), /**/)
60// )
61
62
63// BOOST_FUSION_ADAPT_ADT(
64// bertini::complex_mp,
65// (bool, bool, obj.imag() != 0, /**/)
66// (bertini::real_mp, bertini::real_mp, obj.real(), /**/)
67// (bertini::real_mp, bertini::real_mp, obj.imag(), /**/)
68// )
69
70
71namespace bertini{
72 namespace generators{
73
74 namespace karma = boost::spirit::karma;
75
77 template <typename Num>
78 struct BertiniNumPolicy : public karma::real_policies<Num>
79 {
81 static int floatfield(Num /*n*/) { return std::ios_base::scientific; }
82
84 static unsigned int precision(Num) {
85 return std::numeric_limits<Num>::max_digits10;
86 }
87 };
88
90 template<>
91 struct BertiniNumPolicy<real_mp> : public karma::real_policies<real_mp>
92 {
94 static int floatfield(real_mp /*n*/) { return std::ios_base::scientific; }
95
97 static unsigned int precision(real_mp const& x) {
98 return x.precision();
99 }
100 };
101
102
103
105 template<typename Num>
106 using FullPrec = boost::spirit::karma::real_generator<Num, BertiniNumPolicy<Num> >;
107
110
111
113 struct Classic{
114
116 template <typename OutputIterator>
117 static bool generate(OutputIterator sink, double const& c)
118 {
119 using boost::spirit::karma::omit;
120 using boost::spirit::karma::generate;
121
122 return generate(sink,
123
124 // Begin grammar
125 (
126 full_prec_d << " " << full_prec_d
127 ),
128 // End grammar
129
130 c, 0 // Data to output
131 );
132 }
133
134
136 template <typename OutputIterator>
137 static bool generate(OutputIterator sink, std::complex<double> const& c)
138 {
139 using boost::spirit::karma::omit;
140 using boost::spirit::karma::generate;
141
142 return generate(sink,
143
144 // Begin grammar
145 (
146 full_prec_d << " " << full_prec_d
147 ),
148 // End grammar
149
150 c.real(), c.imag() // Data to output
151 );
152 }
153
154
155
157 template <typename OutputIterator>
158 static bool generate(OutputIterator sink, real_mp const& c)
159 {
160 using boost::spirit::karma::omit;
161 using boost::spirit::karma::generate;
162
163 return generate(sink,
164
165 // Begin grammar
166 (
167 boost::spirit::karma::string
168 ),
169 // End grammar
170
171 c.str() // Data to output
172 );
173 }
174
175
177 template <typename OutputIterator>
178 static bool generate(OutputIterator sink, complex_mp const& c)
179 {
180 using boost::spirit::karma::omit;
181 using boost::spirit::karma::generate;
182
183 return generate(sink,
184
185 // Begin grammar
186 (
187 boost::spirit::karma::string << " " << boost::spirit::karma::string
188 ),
189 // End grammar
190
191 c.real().str(), c.imag().str() // Data to output
192 );
193 }
194
195
197 template <typename OutputIterator, typename T>
198 static bool generate(OutputIterator sink, Vec<T> const& c)
199 {
200 auto s = c.size();
201 for (decltype(s) ii=0; ii<s; ++ii)
202 {
203 bool b = generate(sink, c(ii));
204 if (!b)
205 return b;
206 boost::spirit::karma::generate(sink, (boost::spirit::karma::char_), '\n');
207 }
208 return true;
209 }
210
211 };
212
213
214
216 struct CPlusPlus{
217
219 template <typename OutputIterator>
220 static bool generate(OutputIterator sink, std::complex<double> const& c)
221 {
222 using boost::spirit::karma::omit;
223 using boost::spirit::karma::generate;
224
225 return generate(sink,
226
227 // Begin grammar
228 (
229 !full_prec_d(0.0) << '(' << full_prec_d << ", " << full_prec_d << ')'
230 | omit[full_prec_d] << full_prec_d
231 ),
232 // End grammar
233
234 c.imag(), c.real(), c.imag() // Data to output
235 );
236 }
237 };
238
239
240
241 }
242}
Bertini extensions of the Eigen linear algebra library.
The main multiprecision complex number type.
Definition generators.hpp:72
FullPrec< real_mp > const full_prec_mp
Full-precision generator for real_mp.
Definition generators.hpp:109
FullPrec< double > const full_prec_d
Full-precision generator for double.
Definition generators.hpp:108
boost::spirit::karma::real_generator< Num, BertiniNumPolicy< Num > > FullPrec
A Karma real generator that emits at full precision using BertiniNumPolicy.
Definition generators.hpp:106
Definition algorithm_builder.hpp:36
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
bmp::number< mpc_complex_backend< 0 >, bmp::et_on > complex_mp
The arbitrary-precision complex number type.
Definition mpfr_complex.hpp:58
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
static int floatfield(real_mp)
Always format in scientific notation.
Definition generators.hpp:94
static unsigned int precision(real_mp const &x)
Use the value's own precision.
Definition generators.hpp:97
Karma real-number formatting policy: always scientific, at the type's full precision.
Definition generators.hpp:79
static unsigned int precision(Num)
Use the type's maximum decimal digits.
Definition generators.hpp:84
static int floatfield(Num)
Always format in scientific notation.
Definition generators.hpp:81
Generators emitting numbers in C++ source literal format.
Definition generators.hpp:216
static bool generate(OutputIterator sink, std::complex< double > const &c)
Emit a double-precision complex number as a C++ complex literal.
Definition generators.hpp:220
Generators emitting numbers and vectors in classic Bertini format (real then imaginary).
Definition generators.hpp:113
static bool generate(OutputIterator sink, complex_mp const &c)
Emit a multiprecision complex number in classic format.
Definition generators.hpp:178
static bool generate(OutputIterator sink, Vec< T > const &c)
Emit a vector, one entry per line, in classic format.
Definition generators.hpp:198
static bool generate(OutputIterator sink, double const &c)
Emit a double as a classic-format complex (imaginary part zero).
Definition generators.hpp:117
static bool generate(OutputIterator sink, real_mp const &c)
Emit a multiprecision real in classic format.
Definition generators.hpp:158
static bool generate(OutputIterator sink, std::complex< double > const &c)
Emit a double-precision complex number in classic format.
Definition generators.hpp:137