31#ifndef BERTINI_PATCH_HPP
32#define BERTINI_PATCH_HPP
44#include <boost/archive/text_oarchive.hpp>
45#include <boost/archive/text_iarchive.hpp>
47#include <boost/serialization/vector.hpp>
95 Patch() : precision_(DefaultPrecision())
104 variable_group_sizes_ = other.variable_group_sizes_;
105 precision_ = DefaultPrecision();
108 std::vector<Vec<mpfr_complex> >& coefficients_mpfr = std::get<std::vector<Vec<mpfr_complex> > >(this->coefficients_working_);
109 std::vector<Vec<dbl> >& coefficients_dbl = std::get<std::vector<Vec<dbl> > >(this->coefficients_working_);
112 coefficients_mpfr.resize(variable_group_sizes_.size());
113 coefficients_dbl.resize(variable_group_sizes_.size());
117 auto curr_size = variable_group_sizes_[ii];
119 coefficients_highest_precision_[ii].resize(curr_size);
120 coefficients_dbl[ii].resize(curr_size);
121 coefficients_mpfr[ii].resize(curr_size);
123 for (
unsigned jj(0); jj<curr_size; jj++)
125 coefficients_highest_precision_[ii](jj).precision(other.coefficients_highest_precision_[ii](jj).precision());
127 coefficients_highest_precision_[ii](jj) = other.coefficients_highest_precision_[ii](jj);
129 coefficients_dbl[ii](jj) = dbl(coefficients_highest_precision_[ii](jj));
130 coefficients_mpfr[ii](jj) = mpfr_complex(coefficients_highest_precision_[ii](jj));
132 assert(coefficients_highest_precision_[ii](jj) == other.coefficients_highest_precision_[ii](jj));
147 Patch(std::vector<unsigned>
const& sizes) : variable_group_sizes_(sizes), coefficients_highest_precision_(sizes.size()), precision_(DefaultPrecision())
150 using bertini::multiprecision::RandomComplex;
152 std::vector<Vec<mpfr_complex> >& coefficients_mpfr = std::get<std::vector<Vec<mpfr_complex> > >(coefficients_working_);
153 std::vector<Vec<dbl> >& coefficients_dbl = std::get<std::vector<Vec<dbl> > >(coefficients_working_);
155 coefficients_highest_precision_.resize(sizes.size());
156 coefficients_dbl.resize(sizes.size());
157 coefficients_mpfr.resize(sizes.size());
159 for (
size_t ii=0; ii<sizes.size(); ++ii)
162 coefficients_highest_precision_[ii].resize(sizes[ii]);
163 for (
unsigned jj=0; jj<sizes[ii]; ++jj)
165 multiprecision::RandomComplexAssign(coefficients_highest_precision_[ii](jj), MaxPrecisionAllowed());
168 coefficients_dbl[ii].resize(sizes[ii]);
169 for (
unsigned jj=0; jj<sizes[ii]; ++jj)
171 coefficients_dbl[ii](jj) = dbl(coefficients_highest_precision_[ii](jj));
176 coefficients_mpfr[ii].resize(sizes[ii]);
177 for (
unsigned jj=0; jj<sizes[ii]; ++jj)
179 coefficients_mpfr[ii](jj) = coefficients_highest_precision_[ii](jj);
180 coefficients_mpfr[ii](jj).precision(precision_);
183 assert(
Precision(coefficients_mpfr[ii](0))==precision_);
207 p.variable_group_sizes_ = sizes;
211 std::vector<Vec<mpfr_complex> >& coefficients_mpfr = std::get<std::vector<Vec<mpfr_complex> > >(p.coefficients_working_);
212 std::vector<Vec<dbl> >& coefficients_dbl = std::get<std::vector<Vec<dbl> > >(p.coefficients_working_);
214 p.coefficients_highest_precision_.resize(sizes.size());
215 coefficients_mpfr.resize(sizes.size());
216 coefficients_dbl.resize(sizes.size());
218 for (
size_t ii=0; ii<sizes.size(); ++ii)
220 p.coefficients_highest_precision_[ii].resize(sizes[ii]);
221 for (
unsigned jj=0; jj<sizes[ii]; ++jj)
224 coefficients_mpfr[ii] = p.coefficients_highest_precision_[ii];
225 Precision(coefficients_mpfr[ii],DefaultPrecision());
226 assert(
Precision(coefficients_mpfr[ii](0))==DefaultPrecision());
228 coefficients_dbl[ii].resize(sizes[ii]);
229 for (
unsigned jj=0; jj<sizes[ii]; ++jj)
230 coefficients_dbl[ii](jj) = dbl(p.coefficients_highest_precision_[ii](jj));
256 if (precision_==new_precision)
260 std::vector<Vec<mpfr_complex> >& coefficients_mpfr = std::get<std::vector<Vec<mpfr_complex> > >(coefficients_working_);
264 for (
unsigned jj=0; jj<variable_group_sizes_[ii]; ++jj)
266 if (new_precision>precision_)
268 coefficients_mpfr[ii](jj) = coefficients_highest_precision_[ii](jj);
269 coefficients_mpfr[ii](jj).precision(new_precision);
272 coefficients_mpfr[ii](jj).precision(new_precision);
274 assert(
Precision(coefficients_mpfr[ii](jj))==new_precision);
278 precision_ = new_precision;
296 template<
typename Derived,
typename T>
297 void EvalInPlace(Eigen::MatrixBase<Derived> & function_values, Vec<T>
const& x)
const
299 static_assert(std::is_same<typename Derived::Scalar,T>::value,
"scalar types must match");
301 #ifndef BERTINI_DISABLE_ASSERTS
304 std::stringstream ss;
305 ss <<
"container for function values must be of length at least as long as the number of variable groups. the input vector into which to write is of length " << function_values.size();
306 throw std::runtime_error(ss.str());
314 const std::vector<Vec<T> >& coefficients = std::get<std::vector<Vec<T> > >(coefficients_working_);
320 T& value = function_values(ii+offset);
322 for (
unsigned jj=0; jj<variable_group_sizes_[ii]; ++jj)
324 value += x(counter)*coefficients[ii](jj);
337 Vec<T>
Eval(Vec<T>
const& x)
const
341 return function_values;
354 template<
typename Derived,
typename T>
357 static_assert(std::is_same<typename Derived::Scalar,T>::value,
"scalar types must match");
360 #ifndef BERTINI_DISABLE_ASSERTS
361 assert(jacobian.rows()>=
NumVariableGroups() &&
"input jacobian must have at least as many rows as variable groups");
362 assert(jacobian.cols()==
NumVariables() &&
"input jacobian must have as many columns as the patch has variables");
365 &&
"precision of input vector must match current working precision of patch during evaluation"
369 const std::vector<Vec<T> >& coefficients = std::get<std::vector<Vec<T> > >(coefficients_working_);
374 for (
unsigned jj=0; jj<variable_group_sizes_[ii]; ++jj)
375 jacobian(ii+offset,counter++) = coefficients[ii](jj);
406 #ifndef BERTINI_DISABLE_ASSERTS
407 assert(x.size() ==
NumVariables() &&
"input point for rescaling to fit a patch must have same length as total number of variables being patched, in all variable groups.");
409 &&
"precision of input vector must match current working precision of patch during rescaling"
413 const std::vector<Vec<T> >& coefficients = std::get<std::vector<Vec<T> > >(coefficients_working_);
415 unsigned starting_index_counter(0);
418 auto subvec = x.segment(starting_index_counter,variable_group_sizes_[ii]);
419 subvec /= subvec.transpose() * coefficients[ii];
420 starting_index_counter += variable_group_sizes_[ii];
431 template <
typename T>
434 Vec<T> x_rescaled = x;
446 return variable_group_sizes_.size();
455 unsigned num_vars(0);
456 for (
auto v : variable_group_sizes_)
462 friend std::ostream& operator<<(std::ostream & out,
Patch const& p)
466 for (
auto& c : p.coefficients_highest_precision_)
468 out <<
"patch " << counter++ <<
" has " << c.size() <<
" coefficients:\n";
471 out <<
"current patch precision: " << p.
Precision() <<
"\n";
487 if (variable_group_sizes_[ii]!=rhs.variable_group_sizes_[ii])
490 if (coefficients_highest_precision_[ii]!=rhs.coefficients_highest_precision_[ii])
502 return !(*
this==rhs);
513 std::vector< Vec< mpfr_complex > > coefficients_highest_precision_;
515 mutable std::tuple< std::vector< Vec< mpfr_complex > >, std::vector< Vec< dbl > > > coefficients_working_;
517 std::vector<unsigned> variable_group_sizes_;
519 mutable unsigned precision_;
523 friend class boost::serialization::access;
525 template <
typename Archive>
526 void serialize(Archive& ar,
const unsigned version) {
529 ar & coefficients_highest_precision_;
531 ar & std::get<0>(coefficients_working_);
532 ar & std::get<1>(coefficients_working_);
533 ar & variable_group_sizes_;
An affine chart on a product of projective spaces.
Definition patch.hpp:86
Vec< T > RescalePoint(Vec< T > const &x) const
Rescale a point so that it satisfies the patch equations herein contained.
Definition patch.hpp:432
void JacobianInPlace(Eigen::MatrixBase< Derived > &jacobian, Vec< T > const &x) const
Evaluate the Jacobian matrix, in place.
Definition patch.hpp:355
Vec< T > Eval(Vec< T > const &x) const
Evaluate the patch at a point.
Definition patch.hpp:337
void Precision(unsigned new_precision) const
Set the precision of the patch.
Definition patch.hpp:254
void RescalePointToFitInPlace(Vec< T > &x) const
Rescale a point so that it satisfies the patch equations herein contained.
Definition patch.hpp:404
static Patch RandomReal(std::vector< unsigned > const &sizes)
Construct random REAL patch on a space.
Definition patch.hpp:200
unsigned NumVariableGroups() const
Get the number of variable groups.
Definition patch.hpp:444
Patch()
Default constructor.
Definition patch.hpp:95
void EvalInPlace(Eigen::MatrixBase< Derived > &function_values, Vec< T > const &x) const
Evaluate the patch at a point, in place.
Definition patch.hpp:297
Patch(std::vector< unsigned > const &sizes)
Constructor making a random complex patch on a space whose structure is described by the input argume...
Definition patch.hpp:147
Mat< T > Jacobian(Vec< T > const &x) const
Evaluate the Jacobian matrix, in place.
Definition patch.hpp:385
static Patch Random(std::vector< unsigned > const &sizes)
Construct a random complex patch on a space.
Definition patch.hpp:191
unsigned Precision() const
Get the current precision of the patch.
Definition patch.hpp:242
unsigned NumVariables() const
Get the number of variables in the patch.
Definition patch.hpp:453
bool operator==(Patch const &rhs) const
Check whether two patches are the same.
Definition patch.hpp:480
Patch(Patch const &other)
Definition patch.hpp:102
bool operator!=(Patch const &rhs) const
Check whether two patches are different.
Definition patch.hpp:500
Bertini extensions of the Eigen linear algebra library.
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object. If the object is empty, it's the precision of a default-constru...
Definition eigen_extensions.hpp:292
The main multiprecision complex number type. This is essentially boost::multiprecision' complex.
Extensions to the Boost.Multiprecision library.
Provides an Eigen-like NumTraits struct for querying traits of a number type.
complex RandomReal()
Definition random.hpp:180
void RandomRealAssign(complex &a, unsigned num_digits)
Definition random.hpp:168