Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
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) 2015 - 2021 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// individual authors of this file include:
23// silviana amethyst, university of wisconsin-eau claire
24
30
31#pragma once
32
33
36
37#include <boost/math/special_functions/modf.hpp>
38
39BOOST_MATH_STD_USING
40
41#include <boost/fusion/adapted.hpp>
42#include <boost/fusion/include/adapted.hpp>
43
44#define BOOST_SPIRIT_USE_PHOENIX_V3 1
45
46#include <boost/spirit/include/qi.hpp>
47#include <boost/spirit/include/karma.hpp>
48#include <boost/phoenix/core.hpp>
49#include <boost/phoenix/operator.hpp>
50#include <boost/fusion/include/std_pair.hpp>
51
52
53#include <boost/spirit/include/support_istream_iterator.hpp>
54
55
56
57// BOOST_FUSION_ADAPT_ADT(
58// std::complex<double>,
59// (bool, bool, obj.imag() != 0, /**/)
60// (double, double, obj.real(), /**/)
61// (double, double, obj.imag(), /**/)
62// )
63
64
65// BOOST_FUSION_ADAPT_ADT(
66// bertini::mpfr_complex,
67// (bool, bool, obj.imag() != 0, /**/)
68// (bertini::mpfr_float, bertini::mpfr_float, obj.real(), /**/)
69// (bertini::mpfr_float, bertini::mpfr_float, obj.imag(), /**/)
70// )
71
72
73namespace bertini{
74 namespace generators{
75
76 namespace karma = boost::spirit::karma;
77
78 template <typename Num>
79 struct BertiniNumPolicy : public karma::real_policies<Num>
80 {
81 // we want the numbers always to be in scientific format
82 static int floatfield(Num n) { return std::ios_base::scientific; }
83
84 static unsigned int precision(Num) {
85 return std::numeric_limits<Num>::max_digits10;
86 }
87 };
88
89 template<>
90 struct BertiniNumPolicy<mpfr_float> : public karma::real_policies<mpfr_float>
91 {
92 // we want the numbers always to be in scientific format
93 static int floatfield(mpfr_float n) { return std::ios_base::scientific; }
94
95 static unsigned int precision(mpfr_float const& x) {
96 return x.precision();
97 }
98 };
99
100
101
102 template<typename Num>
103 using FullPrec = boost::spirit::karma::real_generator<Num, BertiniNumPolicy<Num> >;
104
105 FullPrec<double> const full_prec_d = FullPrec<double>();
106 FullPrec<mpfr_float> const full_prec_mp = FullPrec<mpfr_float>();
107
108
109 struct Classic{
110
111 template <typename OutputIterator>
112 static bool generate(OutputIterator sink, double const& c)
113 {
114 using boost::spirit::karma::omit;
115 using boost::spirit::karma::generate;
116
117 return generate(sink,
118
119 // Begin grammar
120 (
121 full_prec_d << " " << full_prec_d
122 ),
123 // End grammar
124
125 c, 0 // Data to output
126 );
127 }
128
129
130 template <typename OutputIterator>
131 static bool generate(OutputIterator sink, std::complex<double> const& c)
132 {
133 using boost::spirit::karma::omit;
134 using boost::spirit::karma::generate;
135
136 return generate(sink,
137
138 // Begin grammar
139 (
140 full_prec_d << " " << full_prec_d
141 ),
142 // End grammar
143
144 c.real(), c.imag() // Data to output
145 );
146 }
147
148
149
150 template <typename OutputIterator>
151 static bool generate(OutputIterator sink, mpfr_float const& c)
152 {
153 using boost::spirit::karma::omit;
154 using boost::spirit::karma::generate;
155
156 return generate(sink,
157
158 // Begin grammar
159 (
160 boost::spirit::karma::string
161 ),
162 // End grammar
163
164 c.str() // Data to output
165 );
166 }
167
168
169 template <typename OutputIterator>
170 static bool generate(OutputIterator sink, mpfr_complex const& c)
171 {
172 using boost::spirit::karma::omit;
173 using boost::spirit::karma::generate;
174
175 return generate(sink,
176
177 // Begin grammar
178 (
179 boost::spirit::karma::string << " " << boost::spirit::karma::string
180 ),
181 // End grammar
182
183 c.real().str(), c.imag().str() // Data to output
184 );
185 }
186
187
188 template <typename OutputIterator, typename T>
189 static bool generate(OutputIterator sink, Vec<T> const& c)
190 {
191 auto s = c.size();
192 for (decltype(s) ii=0; ii<s; ++ii)
193 {
194 bool b = generate(sink, c(ii));
195 if (!b)
196 return b;
197 boost::spirit::karma::generate(sink, (boost::spirit::karma::char_), '\n');
198 }
199 return true;
200 }
201
202 };
203
204
205
206 struct CPlusPlus{
207
208 template <typename OutputIterator>
209 static bool generate(OutputIterator sink, std::complex<double> const& c)
210 {
211 using boost::spirit::karma::omit;
212 using boost::spirit::karma::generate;
213
214 return generate(sink,
215
216 // Begin grammar
217 (
218 !full_prec_d(0.0) << '(' << full_prec_d << ", " << full_prec_d << ')'
219 | omit[full_prec_d] << full_prec_d
220 ),
221 // End grammar
222
223 c.imag(), c.real(), c.imag() // Data to output
224 );
225 }
226 };
227
228
229
230 }
231}
232
Bertini extensions of the Eigen linear algebra library.
The main multiprecision complex number type. This is essentially boost::multiprecision' complex.