Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
slice.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//slice.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//slice.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 slice.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
32#ifndef BERTINI_SLICE_HPP
33#define BERTINI_SLICE_HPP
34
38
39
40namespace bertini {
41
42
48 class Slice
49 {
50
51 };
52
53
54
58 class LinearSlice : public Slice
59 {
60
61
62 mutable std::tuple<Mat<dbl>, Mat<mpfr_complex> > coefficients_working_;
63 Mat< mpfr_complex > coefficients_highest_precision_;
64
65 mutable std::tuple<Vec<dbl>, Vec<mpfr_complex> > constants_working_;
66 Vec< mpfr_complex > constants_highest_precision_;
67
68 VariableGroup sliced_vars_;
69 unsigned num_dims_sliced_;
70 mutable unsigned precision_;
71
72 bool is_homogeneous_;
73 public:
74
78 static LinearSlice RandomReal(VariableGroup const& v, unsigned dim, bool homogeneous = false, bool orthogonal = true)
79 {
80 typedef void (*funtype) (mpfr_complex&, unsigned); // the type for number generation
82 return Make(v, dim, homogeneous, orthogonal, gen);
83 }
84
88 static LinearSlice RandomComplex(VariableGroup const& v, unsigned dim, bool homogeneous = false, bool orthogonal = true)
89 {
90 typedef void (*funtype) (mpfr_complex&, unsigned); // the type for number generation
91 funtype gen = bertini::multiprecision::RandomComplexAssign;
92 return Make(v, dim, homogeneous, orthogonal, gen);
93 }
94
95
99 template<typename NumT>
100 void Eval(Vec<NumT> & result, Vec<NumT> const& x) const
101 {
102 result = std::get<Mat<NumT> >(coefficients_working_) * x;
103
104 if (!is_homogeneous_)
105 result += std::get<Vec<NumT> >(constants_working_);
106 }
107
111 template<typename NumT>
112 Vec<NumT> Eval(Vec<NumT> const& x) const
113 {
114 if (!is_homogeneous_)
115 return std::get<Mat<NumT> >(coefficients_working_) * x + std::get<Vec<NumT> >(constants_working_);
116 else
117 return std::get<Mat<NumT> >(coefficients_working_) * x;
118 }
119
120
124 template<typename NumT>
125 void Jacobian(Mat<NumT> & result, Mat<NumT> const& x) const
126 {
127 result = std::get<Mat<NumT> >(coefficients_working_);
128 }
129
133 template<typename NumT>
134 Mat<NumT> Jacobian(Mat<NumT> const& x) const
135 {
136 return std::get<Mat<NumT> >(coefficients_working_);
137 }
138
139
140
141
147 unsigned Precision() const
148 {
149 return precision_;
150 }
151
159 void Precision(unsigned new_precision) const
160 {
161 if (new_precision > DoublePrecision())
162 {
163 Mat<mpfr_complex>& coefficients_mpfr = std::get<Mat<mpfr_complex> >(coefficients_working_);
164 Vec<mpfr_complex>& constants_mpfr = std::get<Vec<mpfr_complex> >(constants_working_);
165 for (unsigned ii = 0; ii < Dimension(); ++ii)
166 {
167 for (unsigned jj=0; jj<NumVariables(); ++jj)
168 {
169 coefficients_mpfr(ii,jj).precision(new_precision);
170 if (new_precision>precision_)
171 coefficients_mpfr(ii,jj) = coefficients_highest_precision_(ii,jj);
172 }
173
174 if (!is_homogeneous_)
175 {
176 constants_mpfr(ii).precision(new_precision);
177 if (new_precision>precision_)
178 constants_mpfr(ii) = constants_highest_precision_(ii);
179 }
180 }
181 }
182 precision_ = new_precision;
183 }
184
188 unsigned Dimension() const
189 {
190 return num_dims_sliced_;
191 }
192
196 unsigned NumVariables() const
197 {
198 return sliced_vars_.size();
199 }
200
201
202
209 sliced_vars_(),
210 precision_(DefaultPrecision()),
211 num_dims_sliced_(0),
212 coefficients_highest_precision_(0, 0),
213 is_homogeneous_(false),
214 constants_highest_precision_(static_cast<unsigned>(0))
215 {
216 std::get<Mat<dbl> > (coefficients_working_).resize(Dimension(), NumVariables());
217 std::get<Mat<mpfr_complex> >(coefficients_working_).resize(Dimension(), NumVariables());
218
219 std::get<Vec<dbl> > (constants_working_).resize(Dimension());
220 std::get<Vec<mpfr_complex> >(constants_working_).resize(Dimension());
221 }
222
226 LinearSlice(VariableGroup const& v, unsigned dim, bool homogeneous) : sliced_vars_(v), precision_(DefaultPrecision()), num_dims_sliced_(dim), coefficients_highest_precision_(dim, v.size()), is_homogeneous_(homogeneous), constants_highest_precision_(dim)
227 {
228 std::get<Mat<dbl> > (coefficients_working_).resize(Dimension(), NumVariables());
229 std::get<Mat<mpfr_complex> >(coefficients_working_).resize(Dimension(), NumVariables());
230
231 if (!homogeneous)
232 {
233 std::get<Vec<dbl> > (constants_working_).resize(Dimension());
234 std::get<Vec<mpfr_complex> >(constants_working_).resize(Dimension());
235 }
236 }
237
238
242 static
243 LinearSlice Make(VariableGroup const& v, unsigned dim, bool homogeneous, bool orthogonal, std::function<void(mpfr_complex&, unsigned)> gen)
244 {
245 LinearSlice s(v, dim, homogeneous);
246
247
248
249 if (orthogonal)
250 {
251 using std::min;
252 using std::max;
253
254 auto mindim = min(s.Dimension(),s.NumVariables());
255 auto maxdim = max(s.Dimension(),s.NumVariables());
256
257 bool need_transpose = s.Dimension() < s.NumVariables();
258
259 s.coefficients_highest_precision_.resize(maxdim,mindim);
260
261 for (unsigned ii(0); ii<maxdim; ++ii)
262 for (unsigned jj(0); jj<mindim; ++jj)
263 gen(s.coefficients_highest_precision_(ii,jj), MaxPrecisionAllowed());
264
265 auto prev_precision = DefaultPrecision();
266 DefaultPrecision(MaxPrecisionAllowed());
267
268 auto QR_factorization = Eigen::HouseholderQR<Mat<mpfr_complex> >(s.coefficients_highest_precision_);
269 s.coefficients_highest_precision_ = QR_factorization.householderQ()*Mat<mpfr_complex>::Identity(maxdim, mindim);
270
271 if (need_transpose)
272 s.coefficients_highest_precision_.transposeInPlace();
273
274 DefaultPrecision(prev_precision);
275 }
276 else
277 {
278 for (unsigned ii(0); ii<s.Dimension(); ++ii)
279 for (unsigned jj(0); jj<s.NumVariables(); ++jj)
280 gen(s.coefficients_highest_precision_(ii,jj), MaxPrecisionAllowed());
281 }
282
283 for (unsigned ii(0); ii<s.Dimension(); ++ii)
284 for (unsigned jj(0); jj<s.NumVariables(); ++jj)
285 {
286 std::get<Mat<dbl> >(s.coefficients_working_)(ii,jj) = dbl(s.coefficients_highest_precision_(ii,jj));
287 std::get<Mat<mpfr_complex> >(s.coefficients_working_)(ii,jj) = s.coefficients_highest_precision_(ii,jj);
288 }
289
290 if (!homogeneous)
291 {
292 s.constants_highest_precision_.resize(s.Dimension());
293 std::get<Vec<dbl> >(s.constants_working_).resize(s.Dimension());
294 std::get<Vec<mpfr_complex> >(s.constants_working_).resize(s.Dimension());
295
296 for (unsigned ii(0); ii<s.Dimension(); ++ii)
297 {
298 gen(s.constants_highest_precision_(ii), MaxPrecisionAllowed());
299 std::get<Vec<dbl> >(s.constants_working_)(ii) = dbl(s.constants_highest_precision_(ii));
300 std::get<Vec<mpfr_complex> >(s.constants_working_)(ii) = s.constants_highest_precision_(ii);
301 }
302 }
303
304 assert(s.coefficients_highest_precision_.rows()==s.Dimension());
305 assert(s.coefficients_highest_precision_.cols()==s.NumVariables());
306
307 if (!homogeneous)
308 assert(s.constants_highest_precision_.size()==s.Dimension());
309 else
310 assert(s.constants_highest_precision_.size()==0);
311
312 return s;
313 }
314
315 private:
316
317
318 friend class boost::serialization::access;
319
320 template <typename Archive>
321 void serialize(Archive& ar, const unsigned version) {
322 ar & precision_;
323
324 ar & coefficients_highest_precision_;
325
326 ar & std::get<0>(coefficients_working_);
327 ar & std::get<1>(coefficients_working_);
328 ar & sliced_vars_;
329 }
330
331 friend std::ostream& operator<<(std::ostream&, LinearSlice const&);
332 };
333
337 std::ostream& operator<<(std::ostream& out, LinearSlice const& s);
338} // re: namespace bertini
339
340#endif
341
Slice an affine or projective space with a LinearSlice today!
Definition slice.hpp:59
static LinearSlice RandomComplex(VariableGroup const &v, unsigned dim, bool homogeneous=false, bool orthogonal=true)
Generate a random complex slice.
Definition slice.hpp:88
friend std::ostream & operator<<(std::ostream &, LinearSlice const &)
Provides output streaming for LinearSlice.
Definition slice.cpp:5
unsigned NumVariables() const
Get the number of variables sliced.
Definition slice.hpp:196
static LinearSlice RandomReal(VariableGroup const &v, unsigned dim, bool homogeneous=false, bool orthogonal=true)
Definition slice.hpp:78
void Eval(Vec< NumT > &result, Vec< NumT > const &x) const
Evaluate the function values of the LinearSlice, in-place.
Definition slice.hpp:100
unsigned Dimension() const
Get the dimension of the slice.
Definition slice.hpp:188
void Jacobian(Mat< NumT > &result, Mat< NumT > const &x) const
Evaluate the Jacobian of the LinearSlice, in-place.
Definition slice.hpp:125
LinearSlice()
the default constructor for linear slices.
Definition slice.hpp:208
void Precision(unsigned new_precision) const
Set the precision of the slice.
Definition slice.hpp:159
static LinearSlice Make(VariableGroup const &v, unsigned dim, bool homogeneous, bool orthogonal, std::function< void(mpfr_complex &, unsigned)> gen)
factory function for generating slices
Definition slice.hpp:243
LinearSlice(VariableGroup const &v, unsigned dim, bool homogeneous)
the constructor for linear slices.
Definition slice.hpp:226
unsigned Precision() const
Get the current precision of the slice.
Definition slice.hpp:147
Vec< NumT > Eval(Vec< NumT > const &x) const
Evaluate the function values of the LinearSlice.
Definition slice.hpp:112
Mat< NumT > Jacobian(Mat< NumT > const &x) const
Evaluate the Jacobian of the LinearSlice.
Definition slice.hpp:134
Base class for other Slices.
Definition slice.hpp:49
Bertini extensions of the Eigen linear algebra library.
Collects the various header files which define the Bertini2 function tree node types.
T max(T const &a, T const &b, T const &c)
Three-argument form of max.
Definition mpfr_extensions.hpp:98
Provides an Eigen-like NumTraits struct for querying traits of a number type.
void RandomRealAssign(complex &a, unsigned num_digits)
Definition random.hpp:168