28#ifndef BERTINI_SYSTEM_HPP
29#define BERTINI_SYSTEM_HPP
38#include <boost/archive/text_oarchive.hpp>
39#include <boost/archive/text_iarchive.hpp>
40#include <boost/serialization/export.hpp>
41#include <boost/serialization/shared_ptr.hpp>
42#include <boost/serialization/vector.hpp>
43#include <boost/serialization/deque.hpp>
44#include <boost/serialization/std_variant.hpp>
45#include <boost/type_index.hpp>
61#include <boost/archive/binary_oarchive.hpp>
62#include <boost/archive/binary_iarchive.hpp>
63#include <boost/iostreams/stream_buffer.hpp>
64#include <boost/iostreams/stream.hpp>
65#include <boost/iostreams/device/back_inserter.hpp>
85 std::vector<std::shared_ptr<node::Node>>
entries;
110 using NE = std::shared_ptr<node::NamedExpression>;
111 using Var = std::shared_ptr<node::Variable>;
112 using Nd = std::shared_ptr<node::Node>;
117 System() : have_path_variable_(false), is_patched_(false), is_differentiated_(false), have_ordering_(false)
132 System(std::vector<Nd>
const& functions);
138 System(std::string
const& input);
218 std::stringstream ss;
219 ss <<
"trying to evaluate system in-place, but number length of vector into which to write the values (" << function_values.size() <<
") doesn't match number of system user-defined functions plus patches ( " <<
NumNaturalFunctions() <<
"+" <<
NumPatches() <<
") = " <<
NumTotalFunctions() <<
"). Use System.NumTotalFunctions() to make the container for in-place evaluation";
220 throw std::runtime_error(ss.str());
223 if (!is_differentiated_)
226 EvalBlocksInPlace<T>(function_values);
228 patch_.EvalInPlace(function_values,
229 std::get<
Vec<T> >(current_variable_values_));
230 CoerceBlockOutputPrecision(function_values);
250 return function_values;
267 template<
typename T,
typename Derived>
268 void EvalInPlace(
Vec<T>& function_values,
const Eigen::MatrixBase<Derived>& variable_values)
const
270 static_assert(std::is_same<typename Derived::Scalar,T>::value,
"scalar types must match");
272 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
274 std::stringstream ss;
275 ss <<
"trying to evaluate system, but number of input variables (" << variable_values.size() <<
") doesn't match number of system variables (" <<
NumVariables() <<
").";
276 throw std::runtime_error(ss.str());
278 if (have_path_variable_)
279 throw std::runtime_error(
"not using a time value for evaluation of system, but path variable IS defined.");
298 template<
typename Derived>
299 typename Derived::PlainObject
Eval(
const Eigen::MatrixBase<Derived>& variable_values)
const
301 typedef typename Derived::Scalar T;
305 return function_values;
321 return function_values;
340 template<
typename Derived,
typename T>
341 void EvalInPlace(
Vec<T> & function_values,
const Eigen::MatrixBase<Derived>& variable_values,
const T & path_variable_value)
const
343 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
345 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
346 throw std::runtime_error(
"trying to evaluate system, but number of variables doesn't match.");
347 if (!have_path_variable_)
348 throw std::runtime_error(
"trying to use a time value for evaluation of system, but no path variable defined.");
376 template<
typename Derived,
typename T>
377 Vec<T> Eval(
const Eigen::MatrixBase<Derived>& variable_values,
const T & path_variable_value)
const
380 EvalInPlace(function_values, variable_values, path_variable_value);
381 return function_values;
397 EvalInPlace(function_values, variable_values, path_variable_value);
398 return function_values;
412 template <
typename T>
419 throw std::runtime_error(
"trying to evaluate jacobian of system in place, but input J doesn't have right number of columns or rows");
422 if (!is_differentiated_)
425 JacobianBlocksInPlace<T>(J);
427 patch_.JacobianInPlace(J, std::get<
Vec<T> >(current_variable_values_));
428 CoerceBlockOutputPrecision(J);
469 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
470 throw std::runtime_error(
"trying to evaluate jacobian, but number of variables doesn't match.");
473 throw std::runtime_error(
"not using a time value for computation of jacobian, but a path variable is defined.");
496 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
497 throw std::runtime_error(
"trying to evaluate jacobian, but number of variables doesn't match.");
500 throw std::runtime_error(
"not using a time value for computation of jacobian, but a path variable is defined.");
521 template<
typename Derived,
typename T>
522 void JacobianInPlace(
Mat<T> & J,
const Eigen::MatrixBase<Derived> & variable_values,
const T & path_variable_value)
const
524 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
526 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
527 throw std::runtime_error(
"trying to evaluate jacobian, but number of variables doesn't match.");
530 throw std::runtime_error(
"trying to use a time value for computation of jacobian, but no path variable defined.");
552 template<
typename Derived,
typename T>
553 Mat<T> Jacobian(
const Eigen::MatrixBase<Derived> & variable_values,
const T & path_variable_value)
const
555 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
558 throw std::runtime_error(
"trying to evaluate jacobian, but number of variables doesn't match.");
561 throw std::runtime_error(
"trying to use a time value for computation of jacobian, but no path variable defined.");
580 if (variable_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
581 throw std::runtime_error(
"trying to evaluate jacobian, but number of variables doesn't match.");
584 throw std::runtime_error(
"using a time value for computation of jacobian, but no path variable is defined.");
600 template<
typename Derived,
typename T>
602 const Eigen::MatrixBase<Derived> & variable_values,
603 const T & path_variable_value)
const
605 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
625 template<
typename Derived,
typename T>
628 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
649 template<
typename Derived,
typename T>
651 const Eigen::MatrixBase<Derived> & variable_values)
const
653 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
672 template<
typename Derived,
typename T>
675 static_assert(std::is_same<typename Derived::Scalar, T>::value,
"scalar types must be the same");
696 std::stringstream ss;
697 ss <<
"trying to evaluate system in place, but number of input functions (" << ds_dt.size() <<
") doesn't match number of system functions (" <<
NumNaturalFunctions() <<
").";
698 throw std::runtime_error(ss.str());
702 throw std::runtime_error(
"computing time derivative of system with no path variable defined");
704 if (!is_differentiated_)
707 TimeDerivBlocksInPlace<T>(ds_dt);
712 CoerceBlockOutputPrecision(ds_dt);
732 throw std::runtime_error(
"computing time derivative of system with no path variable defined");
792 return patch_.NumVariableGroups();
896 if (new_values.size()!=
static_cast<Eigen::Index
>(
NumVariables()))
898 throw std::runtime_error(
"variable vector of different length from system-owned variables in SetVariables");
927 std::get<Vec<T> >(current_variable_values_) = new_values;
943 if (!have_path_variable_)
944 throw std::runtime_error(
"trying to set the value of the path variable, but one is not defined for this system");
949 std::get<T>(current_path_value_) = new_value;
1092 void AddBlock(
Block b) { ThrowIfSealed(
"AddBlock"); blocks_.push_back(std::move(b)); }
1097 std::vector<Block>
const&
Blocks()
const {
return blocks_; }
1111 ThrowIfSealed(
"ClearFunctions");
1112 for (
auto it = blocks_.begin(); it != blocks_.end(); )
1114 if (std::holds_alternative<blocks::PolynomialBlock>(*it))
1115 it = blocks_.erase(it);
1119 InvalidateDifferentiation();
1131 for (
auto const& b : blocks_)
1132 if (!std::holds_alternative<blocks::PolynomialBlock>(b))
1392 return variable_groups_[index];
1399 return VariableGroupSizesFIFO();
1409 template<
typename T>
1413 if (x.size()!=
static_cast<Eigen::Index
>(
NumVariables())){
1414 std::stringstream message;
1415 message <<
"dehomogenizing point with incorrect number of coordinates. input has ";
1416 message << x.size();
1417 message <<
" but system expects ";
1419 throw std::runtime_error(message.str());
1422 if (!have_ordering_)
1423 ConstructOrdering();
1425 return DehomogenizePointFIFO(x);
1442 template<
typename T>
1447 return d.template lpNorm<Eigen::Infinity>();
1454 for (Eigen::Index k{0}; k < d.size(); ++k)
1457 RealT
const a = abs(d(k));
1458 if (a > biggest) biggest = a;
1479 template<
typename T,
typename R>
1499 template<
typename T,
typename R>
1502 using std::abs;
using std::imag;
1506 for (Eigen::Index k{0}; k < d.size(); ++k)
1509 RealT
const a = abs(imag(d(k)));
1510 if (a > biggest) biggest = a;
1512 return biggest <= threshold;
1558 return auxiliary_variable_groups_;
1564 return auxiliary_coordinates_;
1570 return !auxiliary_variable_groups_.empty() || !auxiliary_coordinates_.empty();
1603 template<
typename T>
1608 std::stringstream message;
1609 message <<
"homogenizing point with incorrect number of coordinates. input has ";
1610 message << x.size();
1611 message <<
" but system expects ";
1613 throw std::runtime_error(message.str());
1616 if (!have_ordering_)
1617 ConstructOrdering();
1619 auto x_homogenized = HomogenizePointFIFO(x);
1624 return x_homogenized;
1648 if (index >= fns.size())
1649 throw std::out_of_range(
"System::Function index out of range");
1678 fns.insert(fns.end(), patches.begin(), patches.end());
1719 unsigned affine_counter = 0, hom_counter = 0, fifo_i = 0;
1720 for (
auto const& iter : time_order_of_variable_groups_)
1728 default:
throw std::runtime_error(
"unacceptable VariableGroupType in FIFOIndexOfGroup");
1734 throw std::runtime_error(
"FIFOIndexOfGroup: the given variable group is not a group of this system");
1753 template<
typename T>
1757 if (span.first + span.second >
static_cast<unsigned>(user_point.size()))
1758 throw std::runtime_error(
"CoordinatesOfGroup: point is shorter than the system's variable structure implies");
1759 return user_point.segment(span.first, span.second);
1773 std::pair<unsigned, unsigned>
SpanOfGroup(
unsigned group_fifo_index)
const
1775 unsigned affine_counter = 0, hom_counter = 0, fifo_i = 0, offset = 0;
1776 for (
auto const& iter : time_order_of_variable_groups_)
1778 unsigned group_size;
1784 default:
throw std::runtime_error(
"unacceptable VariableGroupType in SpanOfGroup");
1786 if (fifo_i == group_fifo_index)
1787 return {offset, group_size};
1788 offset += group_size;
1791 throw std::out_of_range(
"SpanOfGroup: group index out of range");
1801 return variable_groups_;
1809 return hom_variable_groups_;
1816 return path_variable_;
1854 template <
typename NumT>
1943 template <
typename T>
1946 return patch_.RescalePoint(x);
1953 template<
typename T>
1956 patch_.RescalePointToFitInPlace(x);
1966 void Describe(std::ostream& out,
bool verbose =
false)
const;
2079 Mat<complex_mp> BuildRandomizationMatrix(std::shared_ptr<System> operand, std::size_t codimension)
const;
2084 std::vector<unsigned> VariableGroupSizesFIFO()
const;
2090 void AutoPatchFIFO();
2101 template<
typename T>
2104 #ifndef BERTINI_DISABLE_ASSERTS
2105 assert(homogenizing_variables_.size()==0 || homogenizing_variables_.size()==
NumVariableGroups() &&
"must have either 0 homogenizing variables, or the number of homogenizing variables must match the number of affine variable groups.");
2108 bool is_homogenized = homogenizing_variables_.size()!=0;
2111 unsigned affine_group_counter = 0;
2112 unsigned hom_group_counter = 0;
2114 unsigned hom_index = 0;
2115 unsigned dehom_index = 0;
2117 for (
auto& iter : time_order_of_variable_groups_)
2124 auto h = x(hom_index++);
2125 for (
unsigned ii = 0; ii < variable_groups_[affine_group_counter].size(); ++ii)
2126 x_dehomogenized(dehom_index++) = x(hom_index++) / h;
2127 affine_group_counter++;
2131 for (
unsigned ii = 0; ii < variable_groups_[affine_group_counter].size(); ++ii)
2132 x_dehomogenized(dehom_index++) = x(hom_index++);
2138 for (
unsigned ii = 0; ii < hom_variable_groups_[hom_group_counter].size(); ++ii)
2139 x_dehomogenized(dehom_index++) = x(hom_index++);
2140 hom_group_counter++;
2145 x_dehomogenized(dehom_index++) = x(hom_index++);
2150 throw std::runtime_error(
"unacceptable VariableGroupType in FIFOVariableOrdering");
2155 return x_dehomogenized;
2165 template<
typename T>
2168 #ifndef BERTINI_DISABLE_ASSERTS
2169 assert(homogenizing_variables_.size()==0 || homogenizing_variables_.size()==
NumVariableGroups() &&
"must have either 0 homogenizing variables, or the number of homogenizing variables must match the number of affine variable groups.");
2172 bool is_homogenized = homogenizing_variables_.size()!=0;
2173 if (!is_homogenized)
2178 unsigned affine_group_counter = 0;
2179 unsigned hom_group_counter = 0;
2181 unsigned dehom_index = 0;
2182 unsigned hom_index = 0;
2184 for (
auto& iter : time_order_of_variable_groups_)
2189 x_homogenized(hom_index++) = T(1);
2190 for (
unsigned ii = 0; ii < variable_groups_[affine_group_counter].size(); ++ii)
2191 x_homogenized(hom_index++) = x(dehom_index++);
2192 affine_group_counter++;
2197 for (
unsigned ii = 0; ii < hom_variable_groups_[hom_group_counter].size(); ++ii)
2198 x_homogenized(hom_index++) = x(dehom_index++);
2199 hom_group_counter++;
2204 x_homogenized(hom_index++) = x(dehom_index++);
2209 throw std::runtime_error(
"unacceptable VariableGroupType in HomogenizePointFIFO");
2214 return x_homogenized;
2220 blocks::PolynomialBlock& PolyBlock()
2222 for (
auto& b : blocks_)
2223 if (
auto* p = std::get_if<blocks::PolynomialBlock>(&b))
2225 blocks_.emplace_back(blocks::PolynomialBlock{});
2226 return std::get<blocks::PolynomialBlock>(blocks_.back());
2231 blocks::PolynomialBlock
const* PolyBlockPtr()
const
2233 for (
auto const& b : blocks_)
2234 if (
auto* p = std::get_if<blocks::PolynomialBlock>(&b))
2240 std::vector<Nd>
const& PolyFunctions()
const
2242 static const std::vector<Nd> none;
2243 auto* p = PolyBlockPtr();
2244 return p ? p->Functions() : none;
2248 void InvalidateDifferentiation()
const
2250 is_differentiated_ =
false;
2251 if (
auto* p = PolyBlockPtr())
2258 void SyncPolyBlock()
const
2260 if (
auto* p = PolyBlockPtr())
2263 if (have_path_variable_) p->SetPathVariable(path_variable_);
2264 else p->ClearPathVariable();
2271 void ConstructOrdering()
const;
2274 template <
typename T>
2275 T CurrentPathValue()
const
2277 if (have_path_variable_)
2278 return std::get<T>(current_path_value_);
2297 template <
typename Derived>
2298 void CoerceBlockOutputPrecision(Eigen::MatrixBase<Derived>& result)
const
2300 using Scalar =
typename Derived::Scalar;
2301 if constexpr (!std::is_same<Scalar, complex_dbl>::value)
2305 auto const& staged = std::get<Vec<complex_mp> >(current_variable_values_);
2311 template <
typename T>
2312 void EvalBlocksInPlace(
Vec<T>& function_values)
const
2314 const auto& vars = std::get<Vec<T> >(current_variable_values_);
2315 const T t = CurrentPathValue<T>();
2316 Eigen::Index row = 0;
2317 for (
auto const& blk : blocks_)
2318 std::visit([&](
auto const& b){
2319 const Eigen::Index n =
static_cast<Eigen::Index
>(b.NumFunctions());
2320 b.template
EvalInPlace<T>(function_values.segment(row, n), vars, t);
2326 template <
typename T>
2327 void JacobianBlocksInPlace(
Mat<T>& J)
const
2329 const auto& vars = std::get<Vec<T> >(current_variable_values_);
2330 const T t = CurrentPathValue<T>();
2331 Eigen::Index row = 0;
2332 for (
auto const& blk : blocks_)
2333 std::visit([&](
auto const& b){
2334 const Eigen::Index n =
static_cast<Eigen::Index
>(b.NumFunctions());
2337 J.block(row, 0, n, J.cols()) = jb;
2343 template <
typename T>
2344 void TimeDerivBlocksInPlace(
Vec<T>& ds_dt)
const
2346 const auto& vars = std::get<Vec<T> >(current_variable_values_);
2347 const T t = CurrentPathValue<T>();
2348 Eigen::Index row = 0;
2349 for (
auto const& blk : blocks_)
2350 std::visit([&](
auto const& b){
2351 const Eigen::Index n =
static_cast<Eigen::Index
>(b.NumFunctions());
2352 b.template TimeDerivInPlace<T>(ds_dt.segment(row, n), vars, t);
2362 void EncodeCanonical(std::ostream& out, node::EncodingContext& ctx)
const;
2367 void DecodeCanonicalFrom(node::DecodingCursor& cursor, node::DecodingContext& ctx);
2371 void ThrowIfSealed(
char const* operation)
const;
2373 bool is_sealed_ =
false;
2374 mutable std::optional<detail::Digest256> sealed_digest_;
2377 std::vector< VariableGroup > variable_groups_;
2378 std::vector< VariableGroup > hom_variable_groups_;
2382 std::vector<unsigned> auxiliary_variable_groups_;
2383 std::vector<unsigned> auxiliary_coordinates_;
2385 std::vector<Nd> pre_homogenization_functions_;
2388 bool have_path_variable_ =
false;
2392 std::vector< NE > explicit_parameters_;
2400 bool is_patched_ =
false;
2402 mutable bool is_differentiated_ =
false;
2404 std::vector<Block> blocks_;
2406 std::vector< VariableGroupType > time_order_of_variable_groups_;
2408 mutable std::tuple< Vec<complex_dbl>,
Vec<complex_mp> > current_variable_values_;
2409 mutable std::tuple< complex_dbl, complex_mp > current_path_value_{};
2412 mutable bool have_ordering_ =
false;
2424 template<
class Archive>
2425 void serialize(Archive & ar,
const unsigned int ){
2426 ar & ungrouped_variables_;
2427 ar & variable_groups_;
2428 ar & hom_variable_groups_;
2430 ar & homogenizing_variables_;
2432 ar & auxiliary_variable_groups_;
2433 ar & auxiliary_coordinates_;
2435 ar & have_path_variable_;
2436 ar & path_variable_;
2438 ar & implicit_parameters_;
2439 ar & explicit_parameters_;
2453 ar & is_differentiated_;
2455 ar & time_order_of_variable_groups_;
2457 ar & pre_homogenization_functions_;
2467 ar & have_ordering_;
2468 ar & variable_ordering_;
2486 if (Archive::is_loading::value)
2495 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
2552 std::string
const& path_variable_name =
"",
2553 std::shared_ptr<node::Node>
const& gamma =
nullptr);
2582 std::string
const& operation,
2583 std::string
const& a_name, std::string
const& b_name);
2628 std::string
const& path_variable_name =
"",
2629 std::shared_ptr<node::Node>
const& gamma =
nullptr);
2654 std::shared_ptr<const System>
InternSystem(std::shared_ptr<System>
const& candidate);
The evaluation-block contract for the block-composed System.
The reader for the canonical exact text encoding of expression trees – the inverse of canonical_encod...
An affine chart on a product of projective spaces.
Definition patch.hpp:85
A linear slice of affine or projective space: a stack of linear forms, M [x ; 1].
Definition slice.hpp:68
The fundamental polynomial system class for Bertini2.
Definition system.hpp:106
const Var & GetPathVariable() const
Get the system's path variable (throws if none is defined).
static System FromCanonicalEncoding(std::string const &text)
Rebuild a system from its canonical encoding text – the inverse of CanonicalEncodingText(),...
friend void swap(System &a, System &b)
The free swap function for systems.
auto HomVariableGroups() const
Get the homogeneous (projective) variable groups in the problem.
Definition system.hpp:1807
void SetPathVariable(T const &new_value) const
Set the current value of the path variable.
Definition system.hpp:941
void AddParameter(NE const &F)
Add an explicit parameter to the system.
size_t NumAuxiliaryCoordinates() const
How many of this system's user coordinates are auxiliary (a coordinate covered both by a group and in...
friend const System operator*(System s, Nd const &N)
Multiply a system by an arbitrary node.
void AddUngroupedVariable(Var const &v)
Add variables to the system which are in neither a regular variable group, nor in a homogeneous group...
void ReinternNodes(node::ReinternMemo &memo)
Re-intern every node this system holds after deserialization (ADR-0042).
friend std::ostream & operator<<(std::ostream &out, const System &s)
Overloaded operator for printing to an arbirtary out stream.
void SimplifyDerivatives() const
Simplify the derivatives / jacobian / etc contained in the system.
void TimeDerivativeInPlace(Vec< T > &ds_dt, const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Compute the time-derivative of a system.
Definition system.hpp:601
Patch GetPatch() const
Get a copy of the system's patch.
Definition system.hpp:1925
void SetAndReset(Vec< T > const &new_space, T const &new_time) const
Stage the system's current point (variables and path value) for a subsequent Eval/Jacobian.
Definition system.hpp:964
void Seal()
Seal this system: memoize its ContentDigest() and forbid structural mutation (hashcons-on-freeze,...
void EvalInPlace(Vec< T > &function_values) const
Evaluate the system using the previously set variable (and time) values, in place.
Definition system.hpp:213
std::vector< int > Degrees() const
Get the degrees of the functions in the system, with respect to all variables.
bool IsPatched() const
Query whether a system is patched.
Definition system.hpp:1933
void AddImplicitParameters(VariableGroup const &v)
Add some implicit parameters to the system.
Vec< T > DehomogenizePoint(Vec< T > const &x) const
Dehomogenize a point, using the variable grouping / structure of the system.
Definition system.hpp:1410
std::size_t Hash() const
In-process hash derived from ContentDigest() (its first 8 bytes).
System Randomize() const
Randomize an overdetermined system down to a square one, returning a NEW system.
std::pair< unsigned, unsigned > SpanOfGroup(unsigned group_fifo_index) const
Where one variable group sits in a user-coordinate point: (offset, size).
Definition system.hpp:1773
bool HasBlocks() const
Whether this system is evaluated from blocks rather than the function tree.
Definition system.hpp:1123
void JacobianInPlace(Mat< T > &J, const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Evaluate the Jacobian of the system, provided a path variable is defined for the system,...
Definition system.hpp:522
bool HaveAuxiliaryCoordinates() const
Whether this system has any auxiliary coordinates at all (the fast path: usually not).
Definition system.hpp:1568
auto Function(unsigned index) const
Get a function by its index, as a function-tree node.
Definition system.hpp:1645
std::vector< unsigned > const & AuxiliaryVariableGroups() const
The auxiliary variable groups, by FIFO index.
Definition system.hpp:1556
System & operator=(const System &other)
The assignment operator.
std::vector< unsigned > VariableGroupSizes() const
Get the sizes of the variable groups, according to the current ordering.
Definition system.hpp:1397
System Randomize(Mat< complex_mp > const &R) const
Randomize using a caller-supplied (exact) coefficient matrix R, leaving the functions in their curren...
void AddFunctions(std::vector< Nd > const &F)
Add some functions to the system.
Vec< T > RescalePointToFitPatch(Vec< T > const &x) const
Rescale a point so it lies on the system's patch, returning the rescaled copy.
Definition system.hpp:1944
void TimeDerivativeInPlace(Vec< T > &ds_dt, const Eigen::MatrixBase< Derived > &variable_values) const
Compute the time-derivative of the system in place, after setting the variable values.
Definition system.hpp:650
Vec< T > Eval(const Vec< T > &variable_values, const T &path_variable_value) const
Evaluate the system at the given variable values and path-variable value.
Definition system.hpp:394
void ReorderFunctionsByDegreeIncreasing()
Sort the functions so they are in INcreasing order by degree.
size_t NumConstants() const
Get the number of constants in this system.
System(std::vector< Nd > const &functions)
Construct a system from a list of functions.
std::vector< int > Degrees(VariableGroup const &vars) const
Get the degrees of the functions in the system, with respect to a group of variables.
void Describe(std::ostream &out, bool verbose=false) const
Human-facing description of the system, block by block.
void CopyFunctions(System const &other)
Append another system's functions to this one (issue #297).
Definition system.hpp:1702
size_t NumImplicitParameters() const
Get the number of implicit parameters in this system.
size_t NumNaturalFunctions() const
Get the number of functions in this system, excluding patches.
bool IsFinite(Vec< T > const &x, R const &threshold) const
Is this point of mine finite, at the given threshold?
Definition system.hpp:1480
VariableGroup VariableOrdering() const
Order the variables, by the order in which the groups were added.
bool IsSealed() const
Whether this system has been sealed against structural mutation (ADR-0042).
VariableGroup const & UngroupedVariables() const
Get the ungrouped variables: those declared to the system but placed in no affine and no projective g...
Definition system.hpp:825
friend const System operator*(Nd const &N, System const &s)
Multiply a system by an arbitrary node.
std::vector< Nd > GetSpaceDerivatives() const
Get the space derivatives.
void JacobianInPlace(Mat< T > &J, const Vec< T > &variable_values) const
Evaluate the Jacobian matrix of the system, provided the system has no path variable defined.
Definition system.hpp:466
Mat< T > Jacobian() const
Evaluate the Jacobian matrix of the system, using the previous space and time values.
Definition system.hpp:444
System()
The default constructor for a system.
Definition system.hpp:117
System ExpandToFunctionTree() const
Build an equivalent pure function-tree System: every block's functions expressed as function-tree nod...
NodeMatrix SymbolicJacobian(bool usercoordinates=true) const
The symbolic Jacobian of the system, as a matrix of expression-tree nodes.
const Var & PathVariable() const
Get the system's path variable node (the raw stored pointer; may be null if unset).
Definition system.hpp:1814
Vec< T > TimeDerivative() const
Compute the time-derivative of a system.
Definition system.hpp:729
Eigen::NumTraits< NumT >::Real CoefficientBound(unsigned num_evaluations=1) const
Compute an estimate of an upper bound of the absolute values of the coefficients in the system.
void AddUngroupedVariables(VariableGroup const &v)
Add variables to the system which are in neither a regular variable group, nor in a homogeneous group...
bool IsSame(System const &other) const
Content equality: equal ContentDigest().
void ReorderFunctionsByDegreeDecreasing()
Sort the functions so they are in DEcreasing order by degree.
bool IsReal(Vec< T > const &x, R const &threshold) const
Is this point of mine real, at the given threshold?
Definition system.hpp:1500
System & operator*=(Nd const &N)
Multiply a system by an arbitrary node.
size_t NumVariableGroups() const
Get the number of affine variable groups in the system.
bool IsPolynomial() const
Checks whether a system is polynomial, overall.
std::vector< unsigned > const & AuxiliaryCoordinates() const
The individually auxiliary coordinates, by index into a user-coordinate point.
Definition system.hpp:1562
Vec< T > Eval(const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Evaluate the system, provided a path variable is defined for the system.
Definition system.hpp:377
void ClearFunctions()
Remove the polynomial block (the System's natural functions), leaving any structured blocks and the v...
Definition system.hpp:1109
int DegreeBound() const
Compute an upper bound on the degree of the system.
System & operator+=(System const &rhs)
Add two systems together.
Vec< T > HomogenizePoint(Vec< T > const &x) const
Take a point in user (dehomogenized) coordinates into this system's internal coordinates.
Definition system.hpp:1604
std::vector< Nd > PatchFunctionsAsNodes() const
The patch equations, as function-tree nodes: one per variable group, or none when the system is unpat...
size_t NumTotalVariableGroups() const
Get the total number of variable groups in the system, including both affine and homogenous.
friend const System operator+(System lhs, System const &rhs)
Add two systems together.
std::vector< Nd > GetNaturalFunctions() const
Get the functions as authored, as function-tree nodes, without the patch.
Definition system.hpp:1661
size_t NumNaturalVariables() const
Get the number of variables in this system, NOT including homogenizing variables.
void AddFunction(Nd const &F)
Add a function to the system, as a bare expression.
std::vector< Slice > Slices() const
Recover the linear-form slices embedded in this system, one per LinearFormsBlock (empty if the system...
System(System const &other)
The copy operator.
void AddBlock(Block b)
Append an evaluation block (products-of-linears, blend, ...).
Definition system.hpp:1092
void AddConstant(NE const &C)
Add a constant function to the system.
void AutoPatch()
Let the system patch itself by the selected variable ordering, using the current variable groups.
Definition system.hpp:1913
std::vector< Block > const & Blocks() const
Read-only access to the system's evaluation blocks (in evaluation order).
Definition system.hpp:1097
void JacobianInPlace(Mat< T > &J) const
Evaluate the Jacobian matrix of the system, using the previous space and time values,...
Definition system.hpp:413
VariableGroup const & AffineVariableGroup(size_t index) const
Get an affine variable group the class has defined.
Definition system.hpp:1390
void Homogenize(VariableGroup const &provided_hom_vars)
Homogenize the system reusing externally-supplied homogenizing variables – one per affine variable gr...
bool HavePathVariable() const
Query whether a path variable is set for this system.
Vec< T > CoordinatesOfGroup(Vec< T > const &user_point, unsigned group_fifo_index) const
Project a user-coordinate point onto one variable group: return just that group's coordinates.
Definition system.hpp:1754
detail::Digest256 ContentDigest() const
The persistent content digest: SHA-256 of CanonicalEncodingText().
Mat< T > Jacobian(const Vec< T > &variable_values) const
Evaluate the Jacobian matrix of the system, provided the system has no path variable defined.
Definition system.hpp:494
Vec< T > TimeDerivative(const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Compute the time-derivative of a system.
Definition system.hpp:626
Vec< T > Eval(const Vec< T > &variable_values) const
Evaluate the system at the given variable values (no path variable defined).
Definition system.hpp:317
size_t NumPatches() const
Get the number of patches in this system.
Definition system.hpp:790
auto InfinityNormOfDehomogenized(Vec< T > const &x) const
The infinity norm of a point after dehomogenization.
Definition system.hpp:1443
Vec< T > TimeDerivative(const Eigen::MatrixBase< Derived > &variable_values) const
Compute the time-derivative of a system.
Definition system.hpp:673
const VariableGroup & Variables() const
Get the variables in the problem.
size_t NumVariables() const
Get the total number of variables in this system, including homogenizing variables.
void Simplify()
Simplify as many aspects of the system as possible.
void SetVariables(const Vec< T > &new_values) const
Set the values of the variables to be equal to the input values.
Definition system.hpp:894
System Randomize(int codimension) const
Randomize down to a chosen number of functions, returning a NEW system.
void EvalInPlace(Vec< T > &function_values, const Eigen::MatrixBase< Derived > &variable_values) const
Evaluate the system, provided the system has no path variable defined, in place.
Definition system.hpp:268
auto VariableGroups() const
Get the affine variable groups in the problem.
Definition system.hpp:1799
void AddHomVariableGroup(VariableGroup const &v)
Add a homogeneous (projective) variable group to the system.
size_t NumUngroupedVariables() const
get the number of variables which are ungrouped.
void ClearBlocks()
Remove all evaluation blocks (the system reverts to its function-tree functions).
Definition system.hpp:1139
std::vector< Nd > NaturalFunctionsAsNodes() const
The system's natural (pre-patch) functions as function-tree expression nodes, expanding any structure...
VariableGroup const & HomogenizingVariables() const
Get the homogenizing variables, one per affine variable group (in group order), or an empty container...
Definition system.hpp:819
size_t NumHomVariableGroups() const
Get the number of homogeneous variable groups in the system.
std::shared_ptr< node::Node > Nd
Shorthand for a shared pointer to a generic expression-tree node.
Definition system.hpp:112
void SetAndReset(Vec< T > const &new_space) const
Stage the system's current point (variables only) for a subsequent Eval/Jacobian.
Definition system.hpp:977
void SetAuxiliaryCoordinates(std::vector< unsigned > coordinates)
Declare individual coordinates auxiliary, for a system whose grouping does not separate them.
friend class boost::serialization::access
Definition system.hpp:2421
std::vector< Nd > GetTimeDerivatives() const
Get the time derivatives of all functions.
void EvalInPlace(Vec< T > &function_values, const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Evaluate the system, provided a path variable is defined for the system, in place.
Definition system.hpp:341
void SetAuxiliaryVariableGroups(std::vector< unsigned > groups)
Declare whole variable groups auxiliary: excluded from every judgement about a point.
Vec< T > Eval() const
Evaluate the system using the previously set variable (and time) values, creating vector of function ...
Definition system.hpp:245
size_t NumParameters() const
Get the number of explicit parameters in this system.
size_t NumTotalFunctions() const
Get the total number of functions, including patches.
bool IsHomogeneous() const
Checks whether a system is homogeneous, overall.
void ClearVariables()
Clear the entire structure of variables in a system.
std::shared_ptr< node::Variable > Var
Shorthand for a shared pointer to a variable node.
Definition system.hpp:111
Mat< T > Jacobian(const Eigen::MatrixBase< Derived > &variable_values, const T &path_variable_value) const
Evaluate the Jacobian of the system, provided a path variable is defined for the system.
Definition system.hpp:553
std::set< std::string > VariableNameSet() const
Collect the names of every variable the user could reference.
bool HasStructuredBlocks() const
Does the system have any non-polynomial (structured) block – products-of-linears, linear-forms,...
Definition system.hpp:1129
std::vector< Nd > GetFunctions() const
Get every row this system evaluates, as function-tree nodes.
Definition system.hpp:1674
unsigned FIFOIndexOfGroup(VariableGroup const &g) const
The FIFO index (0-based) of a variable group – its position in the canonical FIFO ordering (time_orde...
Definition system.hpp:1717
void AddPathVariable(Var const &v)
Add a variable as the Path Variable to a System.
void CopyPatches(System const &other)
Copy the patches from another system into this one.
void CopyVariableStructure(System const &other)
Copy the entire structure of variables from within one system to another.
void AddVariableGroup(VariableGroup const &v)
Add a variable group to the system.
void AddImplicitParameter(Var const &v)
Add an implicit parameter to the system.
System(System &&other)
The move copy operator.
Definition system.hpp:148
void RescalePointToFitPatchInPlace(Vec< T > &x) const
Rescale a point in place so it lies on the system's patch.
Definition system.hpp:1954
bool CoordinateIsAuxiliary(unsigned index) const
Whether one coordinate of a user-coordinate point is auxiliary.
void SimplifyFunctions()
Simplify the functions contained in the system.
std::string CanonicalEncodingText() const
The canonical exact text encoding of this system – the persistent-identity substrate (ADR-0042).
size_t NumHomVariables() const
Get the number of homogenizing variables in this system.
std::shared_ptr< node::NamedExpression > NE
Shorthand for a shared pointer to a named expression (a function of the system).
Definition system.hpp:110
void TimeDerivativeInPlace(Vec< T > &ds_dt) const
Compute the time-derivative of the system in place, using the currently set variable values.
Definition system.hpp:691
Derived::PlainObject Eval(const Eigen::MatrixBase< Derived > &variable_values) const
Evaluate the system, provided the system has no path variable defined.
Definition system.hpp:299
System & operator=(System &&other)=default
The move assignment operator.
Mat< complex_mp > RandomizationMatrix() const
The randomization matrix R of a system produced by Randomize() (its first RandomizationBlock's n x N ...
Mat< T > Jacobian(const Vec< T > &variable_values, const T &path_variable_value) const
Compute the Jacobian of the system at the given variable and path-variable values.
Definition system.hpp:578
void Homogenize()
Homogenize the system, adding new homogenizing variables for each VariableGroup defined for the syste...
void SetVariableGroups(std::vector< VariableGroup > const &groups)
Replace the entire variable-group structure of the system.
void Differentiate() const
Compute and internally store the symbolic Jacobian of the system.
Bertini extensions of the Eigen linear algebra library.
Collects the various header files which define the Bertini2 function tree node types.
The main multiprecision complex number type.
Extensions to the Boost.Multiprecision library.
Definition canonical.hpp:56
std::map< Node const *, std::shared_ptr< Node > > ReinternMemo
Memo for one re-interning pass: loaded node -> its interned replacement.
Definition reintern.hpp:57
Definition algorithm_builder.hpp:36
constexpr char SystemEncodingVersion[]
The version token of the System canonical encoding – the first word of every encoding text and the sc...
Definition system.hpp:2680
System Concatenate(System sys1, System const &sys2)
Concatenate two compatible systems.
@ Ungrouped
Variables not assigned to any group.
Definition node.hpp:81
@ Homogeneous
A projective (homogeneous) variable group.
Definition node.hpp:79
@ Affine
An affine variable group (to be homogenized).
Definition node.hpp:80
std::variant< blocks::PolynomialBlock, blocks::ProductsOfLinearsBlock, blocks::LinearFormsBlock, blocks::BlendBlock< System >, blocks::RandomizationBlock< System > > Block
The closed set of evaluation blocks a System can be composed of.
Definition block.hpp:135
System Clone(System const &sys)
Do a deep clone of the system.
std::complex< double > complex_dbl
The double-precision complex number type.
Definition double_extensions.hpp:47
System MakeMovingHomotopy(System const &fixed, System const &start_moving, System const &end_moving, std::string const &path_variable_name="", std::shared_ptr< node::Node > const &gamma=nullptr)
Form a homotopy that moves ONLY some rows, leaving the rest fixed and evaluated once.
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
std::shared_ptr< const System > LoadSystemUnified(std::istream &in)
Load a System from a text archive and unify it with the live intern universe (ADR-0042): deserialize,...
std::vector< std::shared_ptr< node::Variable > > VariableGroup
An ordered group of variables (the unit of homogenization / variable grouping).
Definition node.hpp:69
NodeMatrix SymbolicJacobian(std::vector< std::shared_ptr< node::Node > > const &functions, VariableGroup const &variables)
The symbolic Jacobian of a list of functions w.r.t.
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
void CheckVariableStructuresMatch(System const &a, System const &b, std::string const &operation, std::string const &a_name, std::string const &b_name)
Throw unless two systems describe points the same way, so that combining them is meaningful.
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
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object.
Definition eigen_extensions.hpp:339
void AdoptVariableStructure(System &into, System const &from)
Give a system that declares no variables the variable structure of another.
System MakeHomotopy(System const &target, System const &start, std::string const &path_variable_name="", std::shared_ptr< node::Node > const &gamma=nullptr)
Form the gamma-trick straight-line homotopy H = (1-t)*target + gamma*t*start.
std::shared_ptr< bertini::node::Node > Simplify(std::shared_ptr< bertini::node::Node > const &n)
Functionally simplify a tree: returns a NEW simplified tree, leaving the input untouched (non-mutatin...
std::shared_ptr< const System > InternSystem(std::shared_ptr< System > const &candidate)
Hash-cons a System: return the live sealed representative with equal ContentDigest() if one exists,...
std::string UniquePathVariableName(System const &target, std::string base="t")
Produce a path-variable name guaranteed not to collide with any variable in target.
Provides the bertini::Patch class.
Re-intern deserialized node DAGs into the live hash-consing tables (ADR-0042).
Self-contained SHA-256 (FIPS 180-4) and the Digest256 value type.
Provides the bertini::StraightLineProgram class.
A matrix of expression-tree nodes (the symbolic Jacobian), stored row-major.
Definition system.hpp:84
size_t rows
the number of rows (functions)
Definition system.hpp:86
std::vector< std::shared_ptr< node::Node > > entries
row-major, length rows*cols
Definition system.hpp:85
size_t cols
the number of columns (variables)
Definition system.hpp:87
Numeric traits for a bertini number type: digit counts, conversions, and companion types.
Definition num_traits.hpp:57
A 256-bit content digest – the output of Sha256, used as a persistent identity key.
Definition sha256.hpp:53
Traversal state for one canonical-encoding pass: the back-reference table.
Definition canonical_encoding.hpp:76