41#ifndef BERTINI_SLICE_HPP
42#define BERTINI_SLICE_HPP
71 bool is_homogeneous_ =
false;
88 assert(
static_cast<size_t>(augmented_coefficients.cols()) == v.size() + 1 &&
89 "a slice coefficient matrix must have (num_variables + 1) columns");
92 s.is_homogeneous_ = homogeneous;
112 if (
static_cast<size_t>(coefficients.cols()) != v.size())
113 throw std::runtime_error(
"Slice::ThroughPoint coefficient block must have num_variables columns (it is not augmented)");
114 if (
static_cast<size_t>(point.size()) != v.size())
115 throw std::runtime_error(
"Slice::ThroughPoint point must have num_variables entries");
117 return FromCoefficients(v, AugmentAffineThroughPoint(coefficients, point),
false);
131 typedef void (*funtype) (
complex_mp&, unsigned);
138 return Make(v, dim, homogeneous, orthogonal,
true, gen, through_point);
152 typedef void (*funtype) (
complex_mp&, unsigned);
155 return Make(v, dim, homogeneous, orthogonal,
false, gen, through_point);
175 const unsigned num_vars =
static_cast<unsigned>(v.size());
180 throw std::invalid_argument(
"Slice: " + std::to_string(dim) +
" linear forms on "
181 + std::to_string(num_vars) +
" variables; a slice cannot have more forms than variables");
182 if (homogeneous && through_point && dim + 1 > num_vars)
183 throw std::invalid_argument(
"Slice: " + std::to_string(dim) +
" homogeneous linear forms through a point on "
184 + std::to_string(num_vars) +
" variables; the forms live in the point's orthogonal complement, which has "
185 + std::to_string(num_vars - 1) +
" dimensions");
187 if (through_point &&
static_cast<unsigned>(through_point->size()) != num_vars)
188 throw std::runtime_error(
"Slice: through_point must have num_variables entries");
210 for (
unsigned ii(0); ii < dim; ++ii)
211 for (
unsigned jj(0); jj < num_vars; ++jj)
215 assert(
static_cast<unsigned>(coeffs.rows()) == dim);
216 assert(
static_cast<unsigned>(coeffs.cols()) == num_vars);
220 if (through_point && homogeneous)
221 return FromCoefficients(v, AugmentHomogeneousThroughPoint(coeffs, *through_point, orthogonal),
true);
223 return FromCoefficients(v, AugmentAffineThroughPoint(coeffs, *through_point),
false);
228 augmented.leftCols(num_vars) = coeffs;
230 augmented.col(num_vars).setZero();
232 for (
unsigned ii(0); ii < dim; ++ii)
242 template<
typename NumT>
247 block_.EvalInPlace<NumT>(result, x, path_value);
253 template<
typename NumT>
264 template<
typename NumT>
269 block_.JacobianInPlace<NumT>(result, x, path_value);
275 template<
typename NumT>
293 return block_.Coefficients();
320 throw std::runtime_error(
"Slice::Concatenate requires both slices to be on the same number of variables");
325 stacked.topRows(A.rows()) = A;
326 stacked.bottomRows(B.rows()) = B;
328 return FromCoefficients(sliced_vars_, stacked, is_homogeneous_ && other.is_homogeneous_);
338 throw std::runtime_error(
"Slice::Head asked for more forms than the slice has");
348 throw std::runtime_error(
"Slice::Tail asked for more forms than the slice has");
358 Mat<complex_mp> sub(
static_cast<Eigen::Index
>(indices.size()), C.cols());
359 for (
size_t ii = 0; ii < indices.size(); ++ii)
362 throw std::runtime_error(
"Slice::Rows asked for a form index outside the slice");
363 sub.row(
static_cast<Eigen::Index
>(ii)) = C.row(indices[ii]);
374 return static_cast<unsigned>(block_.NumFunctions());
382 return static_cast<unsigned>(sliced_vars_.size());
398 return is_homogeneous_;
407 return block_.Precision();
415 block_.Precision(new_precision);
432 const auto num_vars = coeffs.cols();
443 augmented.leftCols(num_vars) = A;
444 augmented.col(num_vars) = -(A * p);
466 const auto dim = coeffs.rows();
467 const auto num_vars = coeffs.cols();
477 real_mp p_norm_sq = p.squaredNorm();
479 throw std::runtime_error(
"Slice: a homogeneous slice through a point needs a nonzero point");
484 A = A - (Ap /
complex_mp(p_norm_sq)) * p.conjugate().transpose();
490 Eigen::HouseholderQR<Mat<complex_mp>> qr(A.transpose());
491 Mat<complex_mp> Q = qr.householderQ() * Mat<complex_mp>::Identity(num_vars, num_vars);
492 A = Q.leftCols(dim).transpose();
496 augmented.leftCols(num_vars) = A;
497 augmented.col(num_vars).setZero();
505 template <
typename Archive>
506 void serialize(Archive& ar,
const unsigned ) {
509 ar & is_homogeneous_;
514 if (Archive::is_loading::value)
515 for (
auto& v : sliced_vars_)
A linear slice of affine or projective space: a stack of linear forms, M [x ; 1].
Definition slice.hpp:68
Slice Concatenate(Slice const &other) const
A new slice stacking this slice's linear forms on top of other's.
Definition slice.hpp:317
void Precision(unsigned new_precision) const
Set the working precision of the slice, in digits.
Definition slice.hpp:413
void Eval(Vec< NumT > &result, Vec< NumT > const &x) const
Evaluate the slice's linear-form values, in-place.
Definition slice.hpp:243
static Slice FromCoefficients(VariableGroup const &v, Mat< complex_mp > const &augmented_coefficients, bool homogeneous=false)
Build a slice directly from an augmented coefficient matrix.
Definition slice.hpp:86
Mat< complex_mp > const & Coefficients() const
The augmented coefficient matrix: one row per linear form, (Dimension) x (NumVariables+1),...
Definition slice.hpp:291
static Slice ThroughPoint(VariableGroup const &v, Mat< complex_mp > const &coefficients, Vec< complex_mp > const &point)
Build an affine slice whose every linear form vanishes at a given point.
Definition slice.hpp:110
bool IsHomogeneous() const
Whether the slice was authored without constant terms (passes through the origin).
Definition slice.hpp:396
VariableGroup const & Variables() const
The variables the slice is a function of.
Definition slice.hpp:388
unsigned Dimension() const
The dimension of the slice – the number of linear forms.
Definition slice.hpp:372
unsigned NumVariables() const
The number of variables sliced.
Definition slice.hpp:380
Slice Tail(unsigned m) const
A new slice over the same variables built from the last m linear forms.
Definition slice.hpp:345
Vec< NumT > Eval(Vec< NumT > const &x) const
Evaluate the slice's linear-form values.
Definition slice.hpp:254
Mat< NumT > Jacobian(Vec< NumT > const &x) const
The slice's Jacobian (its constant variable-coefficient matrix).
Definition slice.hpp:276
friend std::ostream & operator<<(std::ostream &, Slice const &)
Provides output streaming for Slice.
void Jacobian(Mat< NumT > &result, Vec< NumT > const &x) const
The slice's Jacobian (its constant variable-coefficient matrix), in-place.
Definition slice.hpp:265
blocks::LinearFormsBlock const & AsLinearFormsBlock() const
The underlying linear-forms block (eval / Jacobian / precision engine).
Definition slice.hpp:297
Slice Head(unsigned m) const
A new slice over the same variables built from the first m linear forms.
Definition slice.hpp:335
static Slice RandomComplex(VariableGroup const &v, unsigned dim, bool homogeneous=false, bool orthogonal=true, Vec< complex_mp > const *through_point=nullptr)
Generate a random complex slice.
Definition slice.hpp:150
Slice()=default
An empty slice (zero forms, zero variables).
unsigned Precision() const
Get the current working precision of the slice, in digits.
Definition slice.hpp:405
Slice Rows(std::vector< unsigned > const &indices) const
A new slice over the same variables built from the chosen linear forms.
Definition slice.hpp:355
void AddTo(System &s) const
Add this slice's linear forms to a System as a LinearFormsBlock. (Defined in slice....
friend class boost::serialization::access
Definition slice.hpp:503
static Slice Make(VariableGroup const &v, unsigned dim, bool homogeneous, bool orthogonal, bool real, std::function< void(complex_mp &, unsigned)> gen, Vec< complex_mp > const *through_point=nullptr)
Factory for generating slices.
Definition slice.hpp:173
System AsSystem() const
A standalone System whose functions are exactly this slice's linear forms (over the slice's variable ...
static Slice RandomReal(VariableGroup const &v, unsigned dim, bool homogeneous=false, bool orthogonal=true, Vec< complex_mp > const *through_point=nullptr)
Produce a random real slice on a variable group, slicing a given number of dimensions.
Definition slice.hpp:129
The fundamental polynomial system class for Bertini2.
Definition system.hpp:106
Bertini extensions of the Eigen linear algebra library.
Collects the various header files which define the Bertini2 function tree node types.
void RandomComplexBoundedModulusAssign(complex &a, unsigned num_digits)
Assign to a a random complex number whose modulus is pulled toward 1, at the given precision.
Definition random.hpp:355
void RandomRealBoundedModulusAssign(complex &a, unsigned num_digits)
Assign to a a random REAL number (imaginary part 0) whose modulus is pulled toward 1,...
Definition random.hpp:415
std::shared_ptr< Node > Reintern(std::shared_ptr< Node > const &root, ReinternMemo &memo)
Rebuild the DAG rooted at root through the interning factories (memoized, post-order),...
Definition algorithm_builder.hpp:36
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
std::vector< std::shared_ptr< node::Variable > > VariableGroup
An ordered group of variables (the unit of homogenization / variable grouping).
Definition node.hpp:69
std::ostream & operator<<(typename std::enable_if< std::is_enum< T >::value, std::ostream >::type &stream, const T &e)
Method for printing class enums to streams.
Definition stream_enum.hpp:45
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
constexpr unsigned MaxPrecisionAllowed()
The maximum precision (digits) the library will escalate to.
Definition num_traits.hpp:166
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
Mat< NumberType > RandomConjugateOrthonormalMatrix(unsigned int rows, unsigned int cols)
Make a random conjugate-orthonormal matrix (orthonormal rows when rows<=cols, orthonormal columns whe...
Definition eigen_extensions.hpp:602
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object.
Definition eigen_extensions.hpp:339
Provides an Eigen-like NumTraits struct for querying traits of a number type.
Re-intern deserialized node DAGs into the live hash-consing tables (ADR-0042).