Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
randomization_block.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//randomization_block.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//randomization_block.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 randomization_block.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 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
57
58#pragma once
59
60#include <vector>
61#include <memory>
62#include <stdexcept>
63
64#include <boost/serialization/vector.hpp>
65#include <boost/serialization/shared_ptr.hpp>
66#include <boost/serialization/split_member.hpp>
67
73
74namespace bertini {
75namespace blocks {
76
78template <typename SystemT>
80{
81public:
82 using Var = std::shared_ptr<node::Variable>;
83 using OperandPtr = std::shared_ptr<SystemT>;
84
86 RandomizationBlock() : num_groups_(0), precision_(DefaultPrecision()) {}
87
98 Mat<complex_mp> coefficients,
99 std::vector<std::vector<int>> target_multidegrees,
100 std::vector<std::vector<int>> operand_multidegrees,
101 size_t num_groups)
102 : operand_(std::move(operand)),
103 coefficients_highest_precision_(std::move(coefficients)),
104 target_multidegrees_(std::move(target_multidegrees)),
105 operand_multidegrees_(std::move(operand_multidegrees)),
106 num_groups_(num_groups),
107 precision_(DefaultPrecision())
108 {
109 BuildWorking();
110 }
111
112 // Memory-isolating copy (ADR-0027): the operand System is deep-copied via the
113 // System copy constructor, which shares its immutable node DAG and compiled SLP Program but
114 // gives it its own per-thread evaluation Memory. Everything else (the coefficient matrices,
115 // multidegrees, working buffers) is value state, copied per copy. This lets path tracking
116 // Clone a System into per-thread copies that share no mutable state.
119 : operand_(other.operand_ ? std::make_shared<SystemT>(*other.operand_) : nullptr),
120 coefficients_highest_precision_(other.coefficients_highest_precision_),
121 coefficients_working_(other.coefficients_working_),
122 target_multidegrees_(other.target_multidegrees_),
123 operand_multidegrees_(other.operand_multidegrees_),
124 num_groups_(other.num_groups_),
125 homogenized_(other.homogenized_),
126 hom_vars_(other.hom_vars_),
127 hom_var_index_(other.hom_var_index_),
128 precision_(other.precision_)
129 {}
130
133 {
134 if (this != &other)
135 {
136 operand_ = other.operand_ ? std::make_shared<SystemT>(*other.operand_) : nullptr;
137 coefficients_highest_precision_ = other.coefficients_highest_precision_;
138 coefficients_working_ = other.coefficients_working_;
139 target_multidegrees_ = other.target_multidegrees_;
140 operand_multidegrees_ = other.operand_multidegrees_;
141 num_groups_ = other.num_groups_;
142 homogenized_ = other.homogenized_;
143 hom_vars_ = other.hom_vars_;
144 hom_var_index_ = other.hom_var_index_;
145 precision_ = other.precision_;
146 }
147 return *this;
148 }
149
154
156 size_t NumFunctions() const { return static_cast<size_t>(coefficients_highest_precision_.rows()); }
157
161 std::vector<int> Degrees() const
162 {
163 std::vector<int> d(NumFunctions(), 0);
164 for (size_t i = 0; i < target_multidegrees_.size(); ++i)
165 for (int e : target_multidegrees_[i])
166 d[i] += e;
167 return d;
168 }
169
172 std::vector<int> Degrees(VariableGroup const& vars) const
173 {
174 const int g = GroupIndex(vars);
175 if (g < 0)
176 return Degrees();
177 std::vector<int> d(NumFunctions(), 0);
178 for (size_t i = 0; i < target_multidegrees_.size(); ++i)
179 d[i] = target_multidegrees_[i][static_cast<size_t>(g)];
180 return d;
181 }
182
186 bool IsPolynomial(VariableGroup const& /*vars*/) const { return operand_->IsPolynomial(); }
188 bool IsHomogeneous(VariableGroup const& /*vars*/) const { return homogenized_ ? operand_->IsHomogeneous() : false; }
189
200 void Homogenize(VariableGroup const& /*group*/, Var const& hom_var)
201 {
202 if (homogenized_)
203 return;
204 hom_vars_.push_back(hom_var);
205 if (hom_vars_.size() == num_groups_)
206 {
207 operand_->Homogenize(VariableGroup(hom_vars_));
208 homogenized_ = true;
209 // the hom var of group g now sits at a fixed position of the (shared) variable ordering;
210 // the block reads h_g from there during evaluation.
211 hom_var_index_.assign(num_groups_, -1);
212 auto const& ordering = operand_->Variables();
213 for (size_t g = 0; g < num_groups_; ++g)
214 for (size_t k = 0; k < ordering.size(); ++k)
215 if (ordering[k] == hom_vars_[g]) { hom_var_index_[g] = static_cast<int>(k); break; }
216 }
217 }
218
226 void RestoreHomogenization(std::vector<Var> hom_vars)
227 {
228 if (hom_vars.size() != num_groups_)
229 throw std::invalid_argument("RandomizationBlock: " + std::to_string(hom_vars.size())
230 + " homogenizing variables for " + std::to_string(num_groups_) + " variable groups");
231 hom_vars_ = std::move(hom_vars);
232 homogenized_ = true;
233 hom_var_index_.assign(num_groups_, -1);
234 auto const& ordering = operand_->Variables();
235 for (size_t g = 0; g < num_groups_; ++g)
236 for (size_t k = 0; k < ordering.size(); ++k)
237 if (ordering[k] == hom_vars_[g]) { hom_var_index_[g] = static_cast<int>(k); break; }
238 }
239
241 bool DependsOnPathVariable() const { return operand_->HavePathVariable(); }
242
244 bool HasConstantJacobian() const { return false; }
245
247 void Differentiate() const {}
248
250 OperandPtr const& Operand() const { return operand_; }
252 Mat<complex_mp> const& RandomizationMatrix() const { return coefficients_highest_precision_; }
253
254 // Accessors for the function-tree expansion oracle (System::NaturalFunctionsAsNodes), which
255 // rebuilds g_i = sum_j c_ij * node(f_j) * prod_g h_g^{(D_{i,g}-d_{j,g})}.
257 bool IsHomogenized() const { return homogenized_; }
259 std::vector<Var> const& HomVars() const { return hom_vars_; }
261 std::vector<std::vector<int>> const& TargetMultidegrees() const { return target_multidegrees_; }
263 std::vector<std::vector<int>> const& OperandMultidegrees() const { return operand_multidegrees_; }
265 size_t NumGroups() const { return num_groups_; }
266
271 {
272 for (auto& v : hom_vars_)
273 v = std::static_pointer_cast<node::Variable>(node::Reintern(v, memo));
274 operand_->ReinternNodes(memo);
275 }
276
280 void Describe(std::ostream& out, size_t& row, VariableGroup const& /*vars*/, bool verbose) const
281 {
282 const size_t n = NumFunctions();
283 const size_t N = static_cast<size_t>(coefficients_highest_precision_.cols());
284 out << " ";
286 out << " = R . g (R: " << n << "x" << N << " randomization matrix)\n";
287 row += n;
288
289 const size_t cap = describe_detail::kTerseRowCap;
290
291 auto g = operand_->NaturalFunctionsAsNodes();
292 const size_t gshown = (verbose || g.size() <= cap) ? g.size() : cap;
293 for (size_t j = 0; j < gshown; ++j)
294 out << " g_" << j << " = " << g[j] << "\n";
295 if (gshown < g.size())
296 out << " ... (" << (g.size() - gshown) << " more; describe(verbose=True) for all)\n";
297
298 // the actual randomization matrix below -- 4 significant figures in terse (the default),
299 // full precision in verbose. Shown always (not gated behind verbose) so the numbers a
300 // randomize() produced are visible at a glance.
301 auto const& R = coefficients_highest_precision_;
302 const int sig = describe_detail::CoeffSig(verbose);
303 const Eigen::Index rcap = static_cast<Eigen::Index>(cap);
304 const Eigen::Index rshown = (verbose || R.rows() <= rcap) ? R.rows() : rcap;
305 out << " R =\n";
306 for (Eigen::Index i = 0; i < rshown; ++i)
307 {
308 out << " [ ";
309 for (Eigen::Index j = 0; j < R.cols(); ++j)
310 {
311 if (j) out << ", ";
312 describe_detail::PrintCoeff(out, R(i, j), sig);
313 }
314 out << " ]\n";
315 }
316 if (rshown < R.rows())
317 out << " ... (" << (R.rows() - rshown) << " more rows; describe(verbose=True) for all)\n";
318 }
319
321 unsigned Precision() const { return precision_; }
322
326 void Precision(unsigned new_precision) const
327 {
328 // short-circuit when already materialized here. Each holder of mp values keeps its
329 // own "materialized at" tag; System deliberately keeps none and simply fans out on
330 // every evaluation, which is cheap precisely because of this early return (ADR-0057).
331 if (precision_==new_precision)
332 return;
333 if (new_precision > DoublePrecision())
334 {
335 auto& wm = std::get<Mat<complex_mp>>(coefficients_working_);
336 for (Eigen::Index r = 0; r < wm.rows(); ++r)
337 for (Eigen::Index c = 0; c < wm.cols(); ++c)
338 {
339 wm(r, c).precision(new_precision);
340 if (new_precision > precision_)
341 wm(r, c) = coefficients_highest_precision_(r, c);
342 }
343 }
344 // operand_ is a System: it self-aligns from the point it is evaluated at (ADR-0057)
345 precision_ = new_precision;
346 }
347
353 template <typename T>
354 void EvalInPlace(Eigen::Ref<Vec<T>> result, Vec<T> const& vars, T const& /*path_value*/) const
355 {
356 SyncPrecision(vars);
357 const size_t N = static_cast<size_t>(coefficients_highest_precision_.cols());
358 const Vec<T> f = operand_->template Eval<T>(vars).head(static_cast<Eigen::Index>(N));
359 const auto& C = Working<T>();
360
361 result.setZero();
362 for (size_t i = 0; i < NumFunctions(); ++i)
363 {
364 T acc = Zero<T>();
365 for (size_t j = 0; j < N; ++j)
366 {
367 const T& c = C(static_cast<Eigen::Index>(i), static_cast<Eigen::Index>(j));
368 if (IsZero(c))
369 continue;
370 acc += c * f(static_cast<Eigen::Index>(j)) * HPower<T>(i, j, vars);
371 }
372 result(static_cast<Eigen::Index>(i)) = acc;
373 }
374 }
375
383 template <typename T>
384 void JacobianInPlace(Eigen::Ref<Mat<T>> J, Vec<T> const& vars, T const& /*path_value*/) const
385 {
386 SyncPrecision(vars);
387 const size_t N = static_cast<size_t>(coefficients_highest_precision_.cols());
388 const Vec<T> f = operand_->template Eval<T>(vars).head(static_cast<Eigen::Index>(N));
389 const Mat<T> Jf = operand_->template Jacobian<T>(vars).topRows(static_cast<Eigen::Index>(N));
390 const auto& C = Working<T>();
391
392 J.setZero();
393 for (size_t i = 0; i < NumFunctions(); ++i)
394 {
395 for (size_t j = 0; j < N; ++j)
396 {
397 const T& c = C(static_cast<Eigen::Index>(i), static_cast<Eigen::Index>(j));
398 if (IsZero(c))
399 continue;
400
401 const T W = HPower<T>(i, j, vars); // W_ij = prod_g h_g^{e_g}
402 // operand-Jacobian term: c_ij * W_ij * (d f_j / d x), across all columns.
403 J.row(static_cast<Eigen::Index>(i)) += (c * W) * Jf.row(static_cast<Eigen::Index>(j));
404
405 // h-power terms: only the homogenizing-variable columns pick up f_j * dW/dh_{g'}.
406 if (homogenized_)
407 {
408 for (size_t g = 0; g < num_groups_; ++g)
409 {
410 const int e = Deficit(i, j, g);
411 if (e <= 0 || hom_var_index_[g] < 0)
412 continue; // e<0 means c_ij==0 (already skipped); e==0 -> no dependence
413 // dW/dh_g = e * h_g^{e-1} * prod_{g2 != g} h_{g2}^{e_{g2}}
414 const T dW = MixedPartial<T>(i, j, g, vars);
415 J(static_cast<Eigen::Index>(i), hom_var_index_[g]) += c * f(static_cast<Eigen::Index>(j)) * dW;
416 }
417 }
418 }
419 }
420 }
421
425 template <typename T>
426 void TimeDerivInPlace(Eigen::Ref<Vec<T>> result, Vec<T> const& /*vars*/, T const& /*path_value*/) const
427 {
428 result.setZero();
429 }
430
431private:
437 template <typename T>
438 void SyncPrecision(Vec<T> const& vars) const
439 {
440 if constexpr (!std::is_same<T, complex_dbl>::value)
441 {
442 if (vars.size() > 0)
443 {
444 const unsigned p = bertini::Precision(vars(0));
445 if (p != precision_)
446 Precision(p);
447 }
448 }
449 }
450
451 template <typename T>
452 const Mat<T>& Working() const { return std::get<Mat<T>>(coefficients_working_); }
453
455 template <typename T>
456 T Zero() const
457 {
458 T z(0);
459 if constexpr (!std::is_same<T, complex_dbl>::value) z.precision(precision_);
460 return z;
461 }
462
463 static bool IsZero(complex_dbl const& c) { return c == complex_dbl(0); }
464 static bool IsZero(complex_mp const& c) { return c.real() == 0 && c.imag() == 0; }
465
467 int Deficit(size_t i, size_t j, size_t g) const
468 {
469 return target_multidegrees_[i][g] - operand_multidegrees_[j][g];
470 }
471
473 template <typename T>
474 T HPower(size_t i, size_t j, Vec<T> const& vars) const
475 {
476 T w(1);
477 if constexpr (!std::is_same<T, complex_dbl>::value) w.precision(precision_);
478 if (!homogenized_)
479 return w;
480 for (size_t g = 0; g < num_groups_; ++g)
481 {
482 const int e = Deficit(i, j, g);
483 if (e == 0 || hom_var_index_[g] < 0)
484 continue;
485 w *= IntPow<T>(vars(hom_var_index_[g]), e);
486 }
487 return w;
488 }
489
491 template <typename T>
492 T MixedPartial(size_t i, size_t j, size_t g, Vec<T> const& vars) const
493 {
494 const int eg = Deficit(i, j, g);
495 T d(eg);
496 if constexpr (!std::is_same<T, complex_dbl>::value) d.precision(precision_);
497 d *= IntPow<T>(vars(hom_var_index_[g]), eg - 1);
498 for (size_t g2 = 0; g2 < num_groups_; ++g2)
499 {
500 if (g2 == g)
501 continue;
502 const int e2 = Deficit(i, j, g2);
503 if (e2 == 0 || hom_var_index_[g2] < 0)
504 continue;
505 d *= IntPow<T>(vars(hom_var_index_[g2]), e2);
506 }
507 return d;
508 }
509
511 template <typename T>
512 static T IntPow(T const& base, int e)
513 {
514 T result(1);
515 if constexpr (!std::is_same<T, complex_dbl>::value) result.precision(bertini::Precision(base));
516 for (int k = 0; k < e; ++k)
517 result *= base;
518 return result;
519 }
520
522 int GroupIndex(VariableGroup const& vars) const
523 {
524 auto const& groups = operand_->VariableGroups();
525 for (size_t g = 0; g < groups.size(); ++g)
526 if (SameGroup(groups[g], vars))
527 return static_cast<int>(g);
528 return -1;
529 }
530 static bool SameGroup(VariableGroup const& a, VariableGroup const& b)
531 {
532 if (a.size() != b.size())
533 return false;
534 for (size_t k = 0; k < a.size(); ++k)
535 if (a[k] != b[k])
536 return false;
537 return true;
538 }
539
540 void BuildWorking() const
541 {
542 const auto& M = coefficients_highest_precision_;
543 auto& wd = std::get<Mat<complex_dbl>>(coefficients_working_);
544 auto& wm = std::get<Mat<complex_mp>>(coefficients_working_);
545 wd.resize(M.rows(), M.cols());
546 wm.resize(M.rows(), M.cols());
547 for (Eigen::Index r = 0; r < M.rows(); ++r)
548 for (Eigen::Index c = 0; c < M.cols(); ++c)
549 {
550 wd(r, c) = complex_dbl(M(r, c));
551 wm(r, c) = M(r, c);
552 }
553 }
554
555 OperandPtr operand_;
556 Mat<complex_mp> coefficients_highest_precision_;
557 mutable std::tuple<Mat<complex_dbl>, Mat<complex_mp>> coefficients_working_;
558 std::vector<std::vector<int>> target_multidegrees_;
559 std::vector<std::vector<int>> operand_multidegrees_;
560 size_t num_groups_;
561 bool homogenized_ = false;
562 std::vector<Var> hom_vars_;
563 std::vector<int> hom_var_index_;
564 mutable unsigned precision_;
565
567
568 // Operand held as shared_ptr<SystemT> (non-const, since Homogenize mutates the twin); split
569 // like BlendBlock so serialization never deserializes into a const object.
570 template <typename Archive>
571 void save(Archive& ar, const unsigned /*version*/) const
572 {
573 ar & operand_;
574 ar & coefficients_highest_precision_;
575 ar & std::get<0>(coefficients_working_);
576 ar & std::get<1>(coefficients_working_);
577 ar & target_multidegrees_;
578 ar & operand_multidegrees_;
579 ar & num_groups_;
580 ar & homogenized_;
581 ar & hom_vars_;
582 ar & hom_var_index_;
583 ar & precision_;
584 }
585
586 template <typename Archive>
587 void load(Archive& ar, const unsigned /*version*/)
588 {
589 ar & operand_;
590 ar & coefficients_highest_precision_;
591 ar & std::get<0>(coefficients_working_);
592 ar & std::get<1>(coefficients_working_);
593 ar & target_multidegrees_;
594 ar & operand_multidegrees_;
595 ar & num_groups_;
596 ar & homogenized_;
597 ar & hom_vars_;
598 ar & hom_var_index_;
599 ar & precision_;
600 }
601
602 BOOST_SERIALIZATION_SPLIT_MEMBER()
603};
604
605} // namespace blocks
606} // namespace bertini
std::vector< std::vector< int > > const & OperandMultidegrees() const
Get the operand multidegrees (per operand function, per variable group).
Definition randomization_block.hpp:263
unsigned Precision() const
Get the block's current working precision.
Definition randomization_block.hpp:321
void Reintern(node::ReinternMemo &memo)
Re-intern this block's nodes after deserialization (ADR-0042): the homogenizing variables rebuild thr...
Definition randomization_block.hpp:270
RandomizationBlock(RandomizationBlock &&)=default
Move constructor.
RandomizationBlock & operator=(RandomizationBlock &&)=default
Move assignment.
void EvalInPlace(Eigen::Ref< Vec< T > > result, Vec< T > const &vars, T const &) const
Evaluate the randomized function values into a caller-provided segment.
Definition randomization_block.hpp:354
RandomizationBlock(OperandPtr operand, Mat< complex_mp > coefficients, std::vector< std::vector< int > > target_multidegrees, std::vector< std::vector< int > > operand_multidegrees, size_t num_groups)
Definition randomization_block.hpp:97
size_t NumFunctions() const
Number of randomized functions (rows this block contributes) = n.
Definition randomization_block.hpp:156
void Homogenize(VariableGroup const &, Var const &hom_var)
Homogenize: thread the owning system's homogenizing variable for this group into the operand,...
Definition randomization_block.hpp:200
size_t NumGroups() const
Get the number of variable groups the multidegree bookkeeping spans.
Definition randomization_block.hpp:265
RandomizationBlock()
Construct an empty randomization block at the current default precision.
Definition randomization_block.hpp:86
bool DependsOnPathVariable() const
The randomization itself adds no path-variable dependence; it inherits the operand's.
Definition randomization_block.hpp:241
void Describe(std::ostream &out, size_t &row, VariableGroup const &, bool verbose) const
Human-facing description: terse shows 'f_a..f_b = R .
Definition randomization_block.hpp:280
RandomizationBlock(RandomizationBlock const &other)
Memory-isolating copy constructor (deep-copies the operand system; ADR-0027).
Definition randomization_block.hpp:118
bool IsHomogeneous(VariableGroup const &) const
Query whether the randomized system is homogeneous (iff homogenized and the operand is).
Definition randomization_block.hpp:188
std::vector< std::vector< int > > const & TargetMultidegrees() const
Get the target multidegrees (per randomized row, per variable group).
Definition randomization_block.hpp:261
RandomizationBlock & operator=(RandomizationBlock const &other)
Memory-isolating copy assignment (deep-copies the operand system; ADR-0027).
Definition randomization_block.hpp:132
void RestoreHomogenization(std::vector< Var > hom_vars)
Mark the block homogenized with the given homogenizing variables, WITHOUT touching the operand – for ...
Definition randomization_block.hpp:226
std::vector< int > Degrees() const
The randomized functions' degrees: the (total) target degree of each row, i.e.
Definition randomization_block.hpp:161
std::shared_ptr< node::Variable > Var
Shorthand for a shared pointer to a variable node.
Definition randomization_block.hpp:82
Mat< complex_mp > const & RandomizationMatrix() const
The randomization matrix R (master, highest precision); n x N, row i column j is c_ij.
Definition randomization_block.hpp:252
bool IsPolynomial(VariableGroup const &) const
The randomized system is polynomial / homogeneous exactly when the operand is (System's IsPolynomial/...
Definition randomization_block.hpp:186
void JacobianInPlace(Eigen::Ref< Mat< T > > J, Vec< T > const &vars, T const &) const
Evaluate the randomized Jacobian into a caller-provided block.
Definition randomization_block.hpp:384
void Precision(unsigned new_precision) const
Set the working precision: recast the mpfr working coefficients from the master and bring the operand...
Definition randomization_block.hpp:326
void Differentiate() const
Analytic block: nothing symbolic to differentiate (the operand differentiates itself).
Definition randomization_block.hpp:247
friend class boost::serialization::access
Definition randomization_block.hpp:566
OperandPtr const & Operand() const
The overdetermined operand, for the function-tree expansion oracle and the matrix getter.
Definition randomization_block.hpp:250
std::shared_ptr< SystemT > OperandPtr
Shorthand for a shared pointer to the operand system.
Definition randomization_block.hpp:83
std::vector< Var > const & HomVars() const
Get the homogenizing variables accumulated, one per affine variable group.
Definition randomization_block.hpp:259
std::vector< int > Degrees(VariableGroup const &vars) const
Per-group target degree.
Definition randomization_block.hpp:172
void TimeDerivInPlace(Eigen::Ref< Vec< T > > result, Vec< T > const &, T const &) const
Time-derivative.
Definition randomization_block.hpp:426
bool HasConstantJacobian() const
The randomized Jacobian varies in x (operand Jacobian times constants, plus h-power terms).
Definition randomization_block.hpp:244
bool IsHomogenized() const
Query whether the operand has been homogenized.
Definition randomization_block.hpp:257
Small shared helpers for the per-block Describe methods – the human-facing printing of a block-compos...
Bertini extensions of the Eigen linear algebra library.
Collects the various header files which define the Bertini2 function tree node types.
void PrintCoeff(std::ostream &out, complex_mp const &c, int sig=0)
Print one (complex_mp) coefficient compactly: a real prints as its real part, a pure imaginary as b*i...
Definition describe.hpp:56
int CoeffSig(bool verbose)
The significant-digit count for coefficient printing: 4 for terse (short and legible),...
Definition describe.hpp:68
constexpr size_t kTerseRowCap
How many function rows a block lists in terse (non-verbose) describe before truncating with a ....
Definition describe.hpp:43
void PrintRowLabel(std::ostream &out, size_t row, size_t n)
f_k for a single row, or f_a..f_b for a contiguous range of n rows starting at row.
Definition describe.hpp:71
Definition blend_block.hpp:75
std::map< Node const *, std::shared_ptr< Node > > ReinternMemo
Memo for one re-interning pass: loaded node -> its interned replacement.
Definition reintern.hpp:57
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
constexpr unsigned DoublePrecision()
The number of digits considered "double precision" (16).
Definition num_traits.hpp:152
std::complex< double > complex_dbl
The double-precision complex number type.
Definition double_extensions.hpp:47
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
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
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
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).