Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
explicit_predictors.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.0.
2//
3//bertini2/trackers/explicit_predictors.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//bertini2/trackers/explicit_predictors.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 bertini2/trackers/explicit_predictors.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// copyright 2015
17// James B. Collins
18// West Texas A&M University
19// Department of Mathematics
20// Spring 2016
21//
22// silviana amethyst, university of wisconsin-eau claire
23
24
25
31
32#ifndef BERTINI_EXPLICIT_PREDICTORS_HPP
33#define BERTINI_EXPLICIT_PREDICTORS_HPP
34
36
39#include <Eigen/LU>
40
41#include <boost/type_index.hpp>
42
45
46namespace bertini{
47 namespace tracking{
48 namespace predict{
49
50
51 // Constant,
52 // Euler,
53 // Heun,
54 // RK4,
55 // HeunEuler,
56 // RKNorsett34,
57 // RKF45,
58 // RKCashKarp45,
59 // RKDormandPrince56,
60 // RKVerner67
61
69 inline
74
75
84 inline
85 unsigned Order(Predictor predictor_choice)
86 {
87 switch (predictor_choice)
88 {
90 return 0;
91 case (Predictor::Euler):
92 return 1;
93 case (Predictor::Heun):
94 return 2;
96 return 2;
98 return 3;
99 case (Predictor::RK4):
100 return 4;
101 case (Predictor::RKF45):
102 return 4;
104 return 4;
106 return 5;
108 return 6;
109 default:
110 {
111 throw std::runtime_error("incompatible predictor choice in Order");
112 }
113 }
114 }
115
122 inline bool HasErrorEstimate(Predictor predictor_choice)
123 {
124 switch (predictor_choice)
125 {
126 case (Predictor::Constant):
127 return false;
128 case (Predictor::Euler):
129 return false;
130 case (Predictor::Heun):
131 return false;
133 return true;
135 return true;
136 case (Predictor::RK4):
137 return false;
138 case (Predictor::RKF45):
139 return true;
141 return true;
143 return true;
145 return true;
146 default:
147 {
148 throw std::runtime_error("incompatible predictor choice in HasErrorEstimate");
149 }
150 }
151 }
152
153
154
178 {
179 public:
180
186 ExplicitRKPredictor(const System& S) : s_(0), current_precision_(DefaultPrecision())
187 {
188 ChangeSystem(S);
190 }
191
198 ExplicitRKPredictor(Predictor method, const System& S) : s_(0), current_precision_(DefaultPrecision())
199 {
200 ChangeSystem(S);
201 PredictorMethod(method);
202 }
203
204
205
206
213 {
214 predictor_ = method;
215 p_ = predict::Order(method);
216 switch(method)
217 {
219 {
220 s_ = 1;
221 Mat<double>& arefd = std::get< Mat<double> >(a_);
222 Vec<double>& brefd = std::get< Vec<double> >(b_);
223 Vec<double>& crefd = std::get< Vec<double> >(c_);
224 crefd.resize(s_); crefd(0) = 0;
225 arefd.resize(s_,s_); arefd(0,0) = 0;
226 brefd.resize(s_); brefd(0) = 0;
227 Mat<real_mp>& arefmp = std::get< Mat<real_mp> >(a_);
228 Vec<real_mp>& brefmp = std::get< Vec<real_mp> >(b_);
229 Vec<real_mp>& crefmp = std::get< Vec<real_mp> >(c_);
230 crefmp.resize(s_); crefmp(0) = 0;
231 arefmp.resize(s_,s_); arefmp(0,0) = 0;
232 brefmp.resize(s_); brefmp(0) = 0;
233 uses_embedded_ = false;
234
235 break;
236 }
237 case Predictor::Euler:
238 {
239 s_ = 1;
240 Mat<double>& arefd = std::get< Mat<double> >(a_);
241 Vec<double>& brefd = std::get< Vec<double> >(b_);
242 Vec<double>& crefd = std::get< Vec<double> >(c_);
243 crefd.resize(s_); crefd(0) = static_cast<double>(cEuler_(0));
244 arefd.resize(s_,s_); arefd(0,0) = static_cast<double>(aEuler_(0,0));
245 brefd.resize(s_); brefd(0) = static_cast<double>(bEuler_(0));
246 Mat<real_mp>& arefmp = std::get< Mat<real_mp> >(a_);
247 Vec<real_mp>& brefmp = std::get< Vec<real_mp> >(b_);
248 Vec<real_mp>& crefmp = std::get< Vec<real_mp> >(c_);
249 crefmp.resize(s_); crefmp(0) = static_cast<real_mp>(cEuler_(0));
250 arefmp.resize(s_,s_); arefmp(0,0) = static_cast<real_mp>(aEuler_(0,0));
251 brefmp.resize(s_); brefmp(0) = static_cast<real_mp>(bEuler_(0));
252 uses_embedded_ = false;
253 break;
254 }
256 {
257 s_ = 2;
258
259 FillButcherTable<double>(static_cast<int>(s_),aHeunEuler_, bHeunEuler_, b_minus_bstarHeunEuler_, cHeunEuler_);
260 FillButcherTable<real_mp>(static_cast<int>(s_),aHeunEuler_, bHeunEuler_, b_minus_bstarHeunEuler_, cHeunEuler_);
261
262 break;
263 }
264 case Predictor::RK4:
265 {
266 s_ = 4;
267
268 FillButcherTable<double>(static_cast<int>(s_),aRK4_, bRK4_, cRK4_);
269 FillButcherTable<real_mp>(static_cast<int>(s_),aRK4_, bRK4_, cRK4_);
270
271 break;
272 }
273
274 case Predictor::RKF45:
275 {
276 s_ = 6;
277
278 FillButcherTable<double>(static_cast<int>(s_),aRKF45_, bRKF45_, b_minus_bstarRKF45_, cRKF45_);
279 FillButcherTable<real_mp>(static_cast<int>(s_),aRKF45_, bRKF45_, b_minus_bstarRKF45_, cRKF45_);
280
281 break;
282 }
283
285 {
286 s_ = 6;
287
288 FillButcherTable<double>(static_cast<int>(s_),aRKCK45_, bRKCK45_, b_minus_bstarRKCK45_, cRKCK45_);
289 FillButcherTable<real_mp>(static_cast<int>(s_),aRKCK45_, bRKCK45_, b_minus_bstarRKCK45_, cRKCK45_);
290
291 break;
292 }
293
295 {
296 s_ = 8;
297
298 FillButcherTable<double>(static_cast<int>(s_),aRKDP56_, bRKDP56_, b_minus_bstarRKDP56_, cRKDP56_);
299 FillButcherTable<real_mp>(static_cast<int>(s_),aRKDP56_, bRKDP56_, b_minus_bstarRKDP56_, cRKDP56_);
300
301 break;
302 }
303
305 {
306 s_ = 10;
307
308 FillButcherTable<double>(static_cast<int>(s_),aRKV67_, bRKV67_, b_minus_bstarRKV67_, cRKV67_);
309 FillButcherTable<real_mp>(static_cast<int>(s_),aRKV67_, bRKV67_, b_minus_bstarRKV67_, cRKV67_);
310
311 break;
312 }
313
314 default:
315 {
316 throw std::runtime_error("incompatible predictor choice in ExplicitPredict");
317 }
318 }
319 ResizeK();
320 }; // re: PredictorMethod
321
322
323
324
325
331 void ChangeSystem(const System& S)
332 {
333 numTotalFunctions_ = static_cast<unsigned>(S.NumTotalFunctions());
334 numVariables_ = static_cast<unsigned>(S.NumVariables());
335 // you cannot set K_ here, because s_ may not have been set
336 std::get< Mat<complex_dbl> >(dh_dx_0_).resize(numTotalFunctions_, numVariables_);
337 std::get< Mat<complex_mp> >(dh_dx_0_).resize(numTotalFunctions_, numVariables_);
338 std::get< Mat<complex_dbl> >(dh_dx_temp_).resize(numTotalFunctions_, numVariables_);
339 std::get< Mat<complex_mp> >(dh_dx_temp_).resize(numTotalFunctions_, numVariables_);
340 std::get< Vec<complex_dbl> >(dh_dt_temp_).resize(numTotalFunctions_);
341 std::get< Vec<complex_mp> >(dh_dt_temp_).resize(numTotalFunctions_);
342 std::get< Vec<complex_dbl> >(step_temp_).resize(numTotalFunctions_);
343 std::get< Vec<complex_mp> >(step_temp_).resize(numTotalFunctions_);
344 std::get< Vec<complex_dbl> >(rand_temp_) = RandomOfUnits<complex_dbl>(numVariables_);
345 probe_as_drawn_ = RandomOfUnits<complex_mp>(numVariables_);
346 std::get< Vec<complex_mp> >(rand_temp_) = probe_as_drawn_;
347 std::get< Vec<complex_dbl> >(solve_temp_).resize(numVariables_);
348 std::get< Vec<complex_mp> >(solve_temp_).resize(numVariables_);
349
350 std::get< Vec<complex_dbl> >(stage_pt_temp_).resize(numVariables_);
351 std::get< Vec<complex_mp> >(stage_pt_temp_).resize(numVariables_);
352 std::get< Vec<complex_dbl> >(err_temp_).resize(numTotalFunctions_);
353 std::get< Vec<complex_mp> >(err_temp_).resize(numTotalFunctions_);
354
355 ResizeK();
356 }
357
358
360 void ResizeK()
361 {
362 std::get< Mat<complex_dbl> >(K_).resize(numTotalFunctions_, s_);
363 std::get< Mat<complex_mp> >(K_).resize(numTotalFunctions_, s_);
364
365 std::get< linalg::PartialPivLU<complex_dbl> >(LU_).ChangeSize(numVariables_);
366 std::get< linalg::PartialPivLU<complex_mp> >(LU_).ChangeSize(numVariables_);
367 }
368
369
378 void SetConditionProbe(std::tuple< Vec<complex_dbl>, Vec<complex_mp> > const& probe)
379 {
380 std::get< Vec<complex_dbl> >(rand_temp_) = std::get< Vec<complex_dbl> >(probe);
381 probe_as_drawn_ = std::get< Vec<complex_mp> >(probe);
382 std::get< Vec<complex_mp> >(rand_temp_) = probe_as_drawn_;
383 }
384
385
389 unsigned precision() const
390 {
391 return current_precision_;
392 }
393
400 void ChangePrecision(unsigned new_precision)
401 {
402 Precision(std::get< Mat<complex_mp> >(K_),new_precision);
403
404 Precision(std::get< Vec<complex_mp> >(dh_dt_temp_),new_precision);
405 Precision(std::get< Mat<complex_mp> >(dh_dx_0_),new_precision);
406 Precision(std::get< Mat<complex_mp> >(dh_dx_temp_),new_precision);
407 Precision(std::get< Vec<complex_mp> >(step_temp_),new_precision);
408 // the probe is re-derived from the stored copy, never rounded in place: a drop
409 // in precision would otherwise destroy digits that a later rise cannot restore
410 {
411 auto& probe = std::get< Vec<complex_mp> >(rand_temp_);
412 probe = probe_as_drawn_;
413 Precision(probe, new_precision);
414 }
415 Precision(std::get< Vec<complex_mp> >(solve_temp_),new_precision);
416 Precision(std::get< Vec<complex_mp> >(stage_pt_temp_),new_precision);
417 Precision(std::get< Vec<complex_mp> >(err_temp_),new_precision);
418 std::get< linalg::PartialPivLU<complex_mp> >(LU_).ChangePrecision(new_precision);
419
420 Precision(std::get< Mat<real_mp> >(a_),new_precision);
421 Precision(std::get< Vec<real_mp> >(b_),new_precision);
422 Precision(std::get< Vec<real_mp> >(b_minus_bstar_),new_precision);
423 Precision(std::get< Vec<real_mp> >(c_),new_precision);
424
425 PredictorMethod(predictor_);
426
427 current_precision_ = new_precision;
428
430 }
431
434 {
435#ifndef NDEBUG
436 // ThreadPrecision: correct when running on a std::thread worker,
437 // where precision is set via SetThreadPrecision (thread-local only).
438 assert(current_precision_==ThreadPrecision());
439
440 Vec<complex_mp>& dhdttemp = std::get< Vec<complex_mp> >(dh_dt_temp_);
441 Mat<complex_mp>& dhdx0 = std::get< Mat<complex_mp> >(dh_dx_0_);
442 Mat<complex_mp>& dhdxtemp = std::get< Mat<complex_mp> >(dh_dx_temp_);
443
444 Mat<real_mp>& a = std::get< Mat<real_mp> >(a_);
445 Vec<real_mp>& b = std::get< Vec<real_mp> >(b_);
446 Vec<real_mp>& bstar = std::get< Vec<real_mp> >(b_minus_bstar_);
447 Vec<real_mp>& c = std::get< Vec<real_mp> >(c_);
448
449
450
451 assert(Precision(dhdttemp)==current_precision_);
452 assert(Precision(dhdx0)==current_precision_);
453 assert(Precision(dhdxtemp)==current_precision_);
454
455 assert(Precision(a)==current_precision_);
456 assert(Precision(b)==current_precision_);
457 if (uses_embedded_)
458 assert(Precision(bstar)==current_precision_);
459 assert(Precision(c)==current_precision_);
460#endif
461 }
462
463
480
481 template<typename ComplexT>
483 StepMetadata & meta,
484 System const& S,
485 const Vec<ComplexT>& current_space, ComplexT current_time,
486 ComplexT const& delta_t,
487 unsigned & num_steps_since_last_condition_number_computation,
488 unsigned frequency_of_CN_estimation,
489 NumErrorT const& tracking_tolerance,
490 AdaptiveMultiplePrecisionConfig const* AMP_config = nullptr)
491 {
492 auto step_success = FullStep(next_space, S, current_space, current_time, delta_t);
493
494 // Condition estimate (norm_J, norm_J_inverse, condition_number_estimate) is always
495 // computed -- it is reported and used by the fixed-precision path too.
497 num_steps_since_last_condition_number_computation, frequency_of_CN_estimation);
498
499 // Fixed-precision (nullptr): just the prediction + condition estimate, no AMP criteria.
500 if (AMP_config == nullptr)
501 return step_success;
502
504 if (predict::HasErrorEstimate(predictor_))
506
507 if (step_success != SuccessCode::Success)
508 return step_success;
509
510 if (!amp::CriterionA<ComplexT>(meta.norm_J, meta.norm_J_inverse, *AMP_config))
512 if (!amp::CriterionC<ComplexT>(meta.norm_J_inverse, current_space, tracking_tolerance, *AMP_config))
514
515 return step_success;
516 }
517
518
519
520
521
522
523
524
531 {
532 return predictor_;
533 }
534
535
536
537
545 inline
546 unsigned Order()
547 {
548 return p_;
549 }
550
556 inline bool HasErrorEstimate()
557 {
558 return predict::HasErrorEstimate(predictor_);
559 }
560
561
562
563
564
565
566 protected:
568 //
569 // Protected Methods
570 //
572
573
574
586
587 template<typename ComplexT>
589 System const& S,
590 Vec<ComplexT> const& current_space, ComplexT const& current_time,
591 ComplexT const& delta_t)
592 {
593
594 // If using constant predictor
595 if(s_ == 0)
596 {
597 next_space = current_space;
599 }
600
601 using RealT = typename Eigen::NumTraits<ComplexT>::Real;
602
603 Mat<ComplexT>& Kref = std::get< Mat<ComplexT> >(K_);
604 Mat<RealT>& aref = std::get< Mat<RealT> >(a_);
605 Vec<RealT>& bref = std::get< Vec<RealT> >(b_);
606 Vec<RealT>& cref = std::get< Vec<RealT> >(c_);
607 Kref.fill(ComplexT(0));
608 Vec<ComplexT>& temp = std::get< Vec<ComplexT> >(step_temp_);
609
610 if(EvalRHS(S, current_space, current_time, Kref, 0) != SuccessCode::Success)
611 {
613 }
614
615 Vec<ComplexT>& stage_pt = std::get< Vec<ComplexT> >(stage_pt_temp_);
616 for(unsigned ii = 1; ii < s_; ++ii)
617 {
618 temp.setZero(); // see https://github.com/bertiniteam/b2/issues/198
619 for(unsigned jj = 0; jj < ii; ++jj)
620 temp += aref(ii,jj)*Kref.col(jj);
621
622 // Evaluate into the preallocated stage-point scratch rather than passing the
623 // expression (current_space + delta_t*temp) to EvalRHS's const Vec& param, which
624 // would materialize a fresh temporary Vec every stage.
625 stage_pt.noalias() = current_space + delta_t*temp;
626 if(EvalRHS<ComplexT>(S, stage_pt, current_time + cref(ii)*delta_t, Kref, ii) != SuccessCode::Success)
628 }
629
630
631 temp.setZero();
632 for(unsigned ii = 0; ii < s_; ++ii)
633 temp += bref(ii)*Kref.col(ii);
634
635 // next_space is a distinct buffer from current_space/temp, so noalias avoids a
636 // materialized temporary for the axpy.
637 next_space.noalias() = current_space + delta_t*temp;
638
640 };
641
642
650 template<typename ComplexT>
651 void SetNormsCond(NumErrorT & norm_J, NumErrorT & norm_J_inverse, NumErrorT & condition_number_estimate, unsigned & num_steps_since_last_condition_number_computation, unsigned frequency_of_CN_estimation)
652 {
653 // Calculate condition number and update if needed
654 linalg::PartialPivLU<ComplexT>& LUref = std::get< linalg::PartialPivLU<ComplexT> >(LU_);
655 Mat<ComplexT>& dhdxref = std::get< Mat<ComplexT> >(dh_dx_0_);
656
657 Vec<ComplexT> const& randy = std::get< Vec<ComplexT> >(rand_temp_);
658 Vec<ComplexT>& solve_ref = std::get< Vec<ComplexT> >(solve_temp_);
659 LUref.Solve(randy, solve_ref);
660
661 norm_J = NumErrorT(dhdxref.norm());
662 norm_J_inverse = NumErrorT(solve_ref.norm());
663
664
665 if (num_steps_since_last_condition_number_computation >= frequency_of_CN_estimation)
666 {
667 condition_number_estimate = NumErrorT(norm_J * norm_J_inverse);
668 num_steps_since_last_condition_number_computation = 1; // reset the counter to 1
669 }
670 else // no need to compute the condition number
671 num_steps_since_last_condition_number_computation++;
672 }
673
674
684
685 template<typename ComplexT>
686 SuccessCode SetErrorEstimate(NumErrorT & error_estimate, ComplexT const& delta_t)
687 {
688 using RealT = typename Eigen::NumTraits<ComplexT>::Real;
689
690 Mat<ComplexT>& Kref = std::get< Mat<ComplexT> >(K_);
691 Vec<RealT>& b_minus_bstar_ref = std::get< Vec<RealT> >(b_minus_bstar_);
692
693 Vec<ComplexT>& err = std::get< Vec<ComplexT> >(err_temp_); // reused scratch, not a fresh per-step alloc
694
695 err.setZero();
696 for(unsigned ii = 0; ii < s_; ++ii)
697 {
698 err += (b_minus_bstar_ref(ii))*Kref.col(ii);
699 }
700
701 err *= delta_t;
702
703 error_estimate = NumErrorT(err.norm());
704
706 };
707
708
709
710
711
712
722
723 template<typename ComplexT>
724 SuccessCode SetSizeProportion(NumErrorT & size_proportion, ComplexT const& delta_t)
725 {
726 if(predict::HasErrorEstimate(predictor_))
727 {
728 NumErrorT err_est;
729 SetErrorEstimate(err_est, delta_t);
730
731 using std::pow;
732 size_proportion = err_est/NumErrorT(pow(abs(delta_t), p_+1));
733
735 }
736 else
737 {
738 // No embedded error estimate (e.g. Euler, RK4). AMP2 (bhswAMP2, Eqs 9-10)
739 // derives the size proportion $a$ from the prediction step itself, written as
740 // the initial Newton residual: ||d|| = a|s|. The predicted step in z is
741 // delta_t*(sum_i b_i K_i), so ||d|| = |delta_t|*||K|| and therefore
742 // a = ||d|| / |s| = ||K|| ~ maxCoeff(|K|),
743 // with NO further division by |delta_t|. The previous
744 // maxCoeff(K)/|delta_t|^p over-divided by the step: it inflated $a$ like
745 // 1/|delta_t|^p as the step shrank, spuriously escalating AMP precision
746 // (DigitsB) on small steps. $a$ is meant to be an O(1), step-independent
747 // proportionality constant -- see SetSizeProportion's error-estimate branch,
748 // which divides err_est by |delta_t|^(p+1) for exactly the same reason
749 // (AMP3 / bhsODEAMP Eq. 6).
750 Mat<ComplexT>& Kref = std::get< Mat<ComplexT> >(K_);
751 size_proportion = NumErrorT(Kref.array().abs().maxCoeff());
753 }
754 };
755
756
757
769
770 template<typename ComplexT>
772 const Vec<ComplexT>& space, const ComplexT& time, Mat<ComplexT> & K, unsigned stage)
773 {
774
775
776 if (std::is_same<ComplexT, complex_mp>::value)
778
779 if(stage == 0)
780 {
781 linalg::PartialPivLU<ComplexT>& LUref = std::get< linalg::PartialPivLU<ComplexT> >(LU_);
782 Mat<ComplexT>& dhdxref = std::get< Mat<ComplexT> >(dh_dx_0_);
783
784 if (!std::is_same<ComplexT,complex_dbl>::value)
785 {
786 assert(ThreadPrecision()==current_precision_);
787
788 assert(Precision(space)==current_precision_);
789 assert(Precision(time)==current_precision_);
790 assert(Precision(dhdxref)==current_precision_);
791 assert(Precision(K)==current_precision_);
792 }
793 S.SetAndReset<ComplexT>(space, time);
794 S.JacobianInPlace(dhdxref);
795 // Factor a copy of dh/dx (dh_dx_0_ is read again in SetNormsCond); health check folded in.
796 auto lu_code = LUref.Factor(dhdxref);
797 if (!std::is_same<ComplexT,complex_dbl>::value)
798 {
799 assert(Precision(dhdxref)==current_precision_);
800 assert(Precision(LUref.Factors())==current_precision_);
801 }
802
803 if (lu_code!=MatrixSuccessCode::Success)
805
806 Vec<ComplexT>& dhdtref = std::get< Vec<ComplexT> >(dh_dt_temp_);
807 S.TimeDerivativeInPlace(dhdtref);
808 dhdtref = -dhdtref; // in place; Solve needs materialized rhs
809 LUref.Solve(dhdtref, K.col(stage));
810
812
813 }
814 else
815 {
816 S.SetAndReset<ComplexT>(space, time);
817
818 Mat<ComplexT>& dhdxtempref = std::get< Mat<ComplexT> >(dh_dx_temp_);
819 S.JacobianInPlace(dhdxtempref);
820 linalg::PartialPivLU<ComplexT>& LU_temp = std::get< linalg::PartialPivLU<ComplexT> >(LU_);
821 // dh_dx_temp_ is pure scratch here -> factor destructively, skipping the copy.
822 if (LU_temp.FactorDestructive(dhdxtempref)!=MatrixSuccessCode::Success)
824
825 Vec<ComplexT>& dhdtref = std::get< Vec<ComplexT> >(dh_dt_temp_);
826 S.TimeDerivativeInPlace(dhdtref);
827 dhdtref = -dhdtref; // in place; Solve needs materialized rhs
828 LU_temp.Solve(dhdtref, K.col(stage));
829
831 }
832 }
833
834
835
836
837
838
839
840
841 private:
843 //
844 // Private Methods
845 //
847
848
849
860
861 template<typename RealT>
862 void FillButcherTable(int stages, const Mat<mpq_rational>& a,
863 const Mat<mpq_rational> & b,
864 const Mat<mpq_rational> & b_minus_bstar,
865 const Mat<mpq_rational> & c)
866 {
867 Mat<RealT>& aref = std::get< Mat<RealT> >(a_);
868 aref.resize(stages, stages);
869 for(int ii = 0; ii < stages; ++ii)
870 {
871 for(unsigned jj = 0; jj < s_; ++jj)
872 {
873 aref(ii,jj) = static_cast<RealT>(a(ii,jj));
874 }
875 }
876
877 Vec<RealT>& bref = std::get< Vec<RealT> >(b_);
878 bref.resize(stages);
879 for(int ii = 0; ii < stages; ++ii)
880 {
881 bref(ii) = static_cast<RealT>(b(ii));
882 }
883
884 Vec<RealT>& b_minus_bstar_ref = std::get< Vec<RealT> >(b_minus_bstar_);
885 b_minus_bstar_ref.resize(stages);
886 for(int ii = 0; ii < stages; ++ii)
887 {
888 b_minus_bstar_ref(ii) = static_cast<RealT>(b_minus_bstar(ii));
889 }
890
891 Vec<RealT>& cref = std::get< Vec<RealT> >(c_);
892 cref.resize(stages);
893 for(int ii = 0; ii < stages; ++ii)
894 {
895 cref(ii) = static_cast<RealT>(c(ii));
896
897 }
898 uses_embedded_ = true;
899 }
900
901
902
903
904
914
915 template<typename RealT>
916 void FillButcherTable(int stages, const Mat<mpq_rational>& a,
917 const Mat<mpq_rational> & b,
918 const Mat<mpq_rational> & c)
919 {
920 Mat<RealT>& aref = std::get< Mat<RealT> >(a_);
921 aref.resize(stages, stages);
922 for(int ii = 0; ii < stages; ++ii)
923 {
924 for(unsigned jj = 0; jj < s_; ++jj)
925 {
926 aref(ii,jj) = static_cast<RealT>(a(ii,jj));
927 }
928 }
929
930 Vec<RealT>& bref = std::get< Vec<RealT> >(b_);
931 bref.resize(stages);
932 for(int ii = 0; ii < stages; ++ii)
933 {
934 bref(ii) = static_cast<RealT>(b(ii));
935 }
936
937 Vec<RealT>& cref = std::get< Vec<RealT> >(c_);
938 cref.resize(stages);
939 for(int ii = 0; ii < stages; ++ii)
940 {
941 cref(ii) = static_cast<RealT>(c(ii));
942
943 }
944 uses_embedded_ = false;
945 }
946
947
948
949
950
951
953 //
954 // Private Data Members
955 //
957
958 unsigned numTotalFunctions_; // Number of total functions for the current system
959 unsigned numVariables_; // Number of variables for the current system
960 mutable std::tuple< Mat<complex_dbl>, Mat<complex_mp> > K_; // All the stage variables. Each column represents a different stage.
961 Predictor predictor_; // Method for prediction
962 unsigned p_; //Order of the prediction method
963 mutable std::tuple< Mat<complex_dbl>, Mat<complex_mp> > dh_dx_0_; // Jacobian for the initial stage. Use for AMP testing
964 mutable std::tuple< Mat<complex_dbl>, Mat<complex_mp> > dh_dx_temp_; // Temporary jacobian for all other stages
965 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > dh_dt_temp_; // Temporary time derivative used for all stages
966 // std::tuple< Eigen::PartialPivLU<Mat<complex_dbl>>, Eigen::PartialPivLU<Mat<complex_mp>> > LU_0_; // LU from the intial stage used for AMP testing
967
968 mutable std::tuple< linalg::PartialPivLU<complex_dbl>, linalg::PartialPivLU<complex_mp> > LU_;
969
970 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > step_temp_; // reused scratch for FullStep stage accumulation
971 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > rand_temp_; // reused scratch: random RHS for norm_J_inverse
972 Vec<complex_mp> probe_as_drawn_;
973 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > solve_temp_; // reused scratch: LU solve result
974 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > stage_pt_temp_; // reused scratch: RK stage point (current_space + delta_t*temp)
975 mutable std::tuple< Vec<complex_dbl>, Vec<complex_mp> > err_temp_; // reused scratch: embedded-RK error estimate vector
976
977
978 // Butcher Table (notation from https://en.wikipedia.org/wiki/List_of_Runge%E2%80%93Kutta_methods )
979 mutable unsigned s_; // Number of stages
980 mutable std::tuple< Mat<double>, Mat<real_mp> > a_;
981 mutable std::tuple< Vec<double>, Vec<real_mp> > b_;
982 mutable std::tuple< Vec<double>, Vec<real_mp> > b_minus_bstar_;
983 mutable std::tuple< Vec<double>, Vec<real_mp> > c_;
984
985 mutable bool uses_embedded_;
986 mutable unsigned current_precision_;
987
988
989
990
991
992 // The Butcher tables in exact mpq_rational form. Defined inline in-header
993 // (C++17 inline variables) so they need no out-of-line definition -- this is
994 // what lets the Windows link drop the /WHOLEARCHIVE workaround (issue #287).
995 // Each XxxPtr_ array is declared before its matrix, so the matrix initializer
996 // (which reads the array) is sequenced after it within any using TU.
997 // Euler
998 inline static const mpq_rational aEulerPtr_[] = {mpq_rational(0,1)};
999 inline static const Eigen::Matrix<mpq_rational,1,1> aEuler_ = Eigen::Matrix<mpq_rational,1,1>(aEulerPtr_);
1000 inline static const mpq_rational bEulerPtr_[] = {mpq_rational(1,1)};
1001 inline static const Eigen::Matrix<mpq_rational,1,1> bEuler_ = Eigen::Matrix<mpq_rational,1,1>(bEulerPtr_);
1002 inline static const mpq_rational cEulerPtr_[] = {mpq_rational(0,1)};
1003 inline static const Eigen::Matrix<mpq_rational,1,1> cEuler_ = Eigen::Matrix<mpq_rational,1,1>(cEulerPtr_);
1004
1005 // Heun-Euler
1006 inline static const mpq_rational aHeunEulerPtr_[] = {mpq_rational(0,1), mpq_rational(1,1), mpq_rational(0,1), mpq_rational(0,1)};
1007 inline static const Eigen::Matrix<mpq_rational,2,2> aHeunEuler_ = Eigen::Matrix<mpq_rational,2,2>(aHeunEulerPtr_);
1008 inline static const mpq_rational bHeunEulerPtr_[] = {mpq_rational(1,2), mpq_rational(1,2)};
1009 inline static const Eigen::Matrix<mpq_rational,2,1> bHeunEuler_ = Eigen::Matrix<mpq_rational,2,1>(bHeunEulerPtr_);
1010 inline static const mpq_rational b_minus_bstarHeunEulerPtr_[] = {mpq_rational(-1,2), mpq_rational(1,2)};
1011 inline static const Eigen::Matrix<mpq_rational,2,1> b_minus_bstarHeunEuler_ = Eigen::Matrix<mpq_rational,2,1>(b_minus_bstarHeunEulerPtr_);
1012 inline static const mpq_rational cHeunEulerPtr_[] = {mpq_rational(0,1), mpq_rational(1,1)};
1013 inline static const Eigen::Matrix<mpq_rational,2,1> cHeunEuler_ = Eigen::Matrix<mpq_rational,2,1>(cHeunEulerPtr_);
1014
1015 // RK4
1016 inline static const mpq_rational aRK4Ptr_[] = {mpq_rational(0,1), mpq_rational(1,2), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(1,2), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(1,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1)};
1017 inline static const Eigen::Matrix<mpq_rational,4,4> aRK4_ = Eigen::Matrix<mpq_rational,4,4>(aRK4Ptr_);
1018 inline static const mpq_rational bRK4Ptr_[] = {mpq_rational(1,6), mpq_rational(1,3), mpq_rational(1,3),mpq_rational(1,6)};
1019 inline static const Eigen::Matrix<mpq_rational,4,1> bRK4_ = Eigen::Matrix<mpq_rational,4,1>(bRK4Ptr_);
1020 inline static const mpq_rational cRK4Ptr_[] = {mpq_rational(0,1), mpq_rational(1,2), mpq_rational(1,2),mpq_rational(1,1)};
1021 inline static const Eigen::Matrix<mpq_rational,4,1> cRK4_ = Eigen::Matrix<mpq_rational,4,1>(cRK4Ptr_);
1022
1023 // RKF45
1024 inline static const mpq_rational aRKF45Ptr_[] = {mpq_rational(0,1), mpq_rational(1,4),mpq_rational(3,32), mpq_rational(1932,2197),mpq_rational(439,216),mpq_rational(-8,27), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(9,32), mpq_rational(-7200,2197),mpq_rational(-8,1),mpq_rational(2,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(7296,2197),mpq_rational(3680,513),mpq_rational(-3544,2565), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(-845,4104),mpq_rational(1859,4104), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(-11,40), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1)};
1025 inline static const Eigen::Matrix<mpq_rational,6,6> aRKF45_ = Eigen::Matrix<mpq_rational,6,6>(aRKF45Ptr_);
1026 inline static const mpq_rational bRKF45Ptr_[] = {mpq_rational(16,135), mpq_rational(0,1), mpq_rational(6656,12825), mpq_rational(28561,56430),mpq_rational(-9,50),mpq_rational(2,55)};
1027 inline static const Eigen::Matrix<mpq_rational,6,1> bRKF45_ = Eigen::Matrix<mpq_rational,6,1>(bRKF45Ptr_);
1028 inline static const mpq_rational b_minus_bstarRKF45Ptr_[] = {mpq_rational(1,360), mpq_rational(0,1), mpq_rational(-128,4275), mpq_rational(-2197,75240),mpq_rational(1,50),mpq_rational(2,55)};
1029 inline static const Eigen::Matrix<mpq_rational,6,1> b_minus_bstarRKF45_ = Eigen::Matrix<mpq_rational,6,1>(b_minus_bstarRKF45Ptr_);
1030 inline static const mpq_rational cRKF45Ptr_[] = {mpq_rational(0,1), mpq_rational(1,4), mpq_rational(3,8), mpq_rational(12,13),mpq_rational(1,1),mpq_rational(1,2)};
1031 inline static const Eigen::Matrix<mpq_rational,6,1> cRKF45_ = Eigen::Matrix<mpq_rational,6,1>(cRKF45Ptr_);
1032
1033 // RK Cash-Karp45
1034 inline static const mpq_rational aRKCK45Ptr_[] = {mpq_rational(0,1), mpq_rational(1,5),mpq_rational(3,40), mpq_rational(3,10),mpq_rational(-11,54),mpq_rational(1631,55296), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(9,40), mpq_rational(-9,10),mpq_rational(5,2),mpq_rational(175,512), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(6,5),mpq_rational(-70,27),mpq_rational(575,13824), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(35,27),mpq_rational(44275,110592), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(253,4096), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1)};
1035 inline static const Eigen::Matrix<mpq_rational,6,6> aRKCK45_ = Eigen::Matrix<mpq_rational,6,6>(aRKCK45Ptr_);
1036 inline static const mpq_rational bRKCK45Ptr_[] = {mpq_rational(37,378), mpq_rational(0,1), mpq_rational(250,621), mpq_rational(125,594),mpq_rational(0,1),mpq_rational(512,1771)};
1037 inline static const Eigen::Matrix<mpq_rational,6,1> bRKCK45_ = Eigen::Matrix<mpq_rational,6,1>(bRKCK45Ptr_);
1038 inline static const mpq_rational b_minus_bstarRKCK45Ptr_[] = {mpq_rational(-277,64512), mpq_rational(0,1), mpq_rational(6925,370944), mpq_rational(-6925,202752),mpq_rational(-277,14336),mpq_rational(277,7084)};
1039 inline static const Eigen::Matrix<mpq_rational,6,1> b_minus_bstarRKCK45_ = Eigen::Matrix<mpq_rational,6,1>(b_minus_bstarRKCK45Ptr_);
1040 inline static const mpq_rational cRKCK45Ptr_[] = {mpq_rational(0,1), mpq_rational(1,5), mpq_rational(3,10), mpq_rational(3,5),mpq_rational(1,1),mpq_rational(7,8)};
1041 inline static const Eigen::Matrix<mpq_rational,6,1> cRKCK45_ = Eigen::Matrix<mpq_rational,6,1>(cRKCK45Ptr_);
1042
1043 // RK Dormand-Prince 56
1044 inline static const mpq_rational aRKDP56Ptr_[] = {mpq_rational(0,1), mpq_rational(1,10),mpq_rational(-2,81), mpq_rational(615,1372),mpq_rational(3243,5500),mpq_rational(-26492,37125),mpq_rational(5561,2376),mpq_rational(465467,266112), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(20,81), mpq_rational(-270,343),mpq_rational(-54,55),mpq_rational(72,55),mpq_rational(-35,11),mpq_rational(-2945,1232), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(1053,1372),mpq_rational(50949,71500),mpq_rational(2808,23375),mpq_rational(-24117,31603),mpq_rational(-5610201,14158144), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(4998,17875),mpq_rational(-24206,37125),mpq_rational(899983,200772),mpq_rational(10513573,3212352), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(338,459),mpq_rational(-5225,1836),mpq_rational(-424325,205632), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(3925,4056),mpq_rational(376225,454272), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1)};
1045 inline static const Eigen::Matrix<mpq_rational,8,8> aRKDP56_ = Eigen::Matrix<mpq_rational,8,8>(aRKDP56Ptr_);
1046 inline static const mpq_rational bRKDP56Ptr_[] = {mpq_rational(821,10800), mpq_rational(0,1), mpq_rational(19683,71825), mpq_rational(175273,912600),mpq_rational(395,3672),mpq_rational(785,2704),mpq_rational(3,50),mpq_rational(0,1)};
1047 inline static const Eigen::Matrix<mpq_rational,8,1> bRKDP56_ = Eigen::Matrix<mpq_rational,8,1>(bRKDP56Ptr_);
1048 inline static const mpq_rational b_minus_bstarRKDP56Ptr_[] = {mpq_rational(13,2400), mpq_rational(0,1), mpq_rational(-19683,618800), mpq_rational(2401,31200),mpq_rational(-65,816),mpq_rational(15,416),mpq_rational(521,5600),mpq_rational(-1,10)};
1049 inline static const Eigen::Matrix<mpq_rational,8,1> b_minus_bstarRKDP56_ = Eigen::Matrix<mpq_rational,8,1>(b_minus_bstarRKDP56Ptr_);
1050 inline static const mpq_rational cRKDP56Ptr_[] = {mpq_rational(0,1), mpq_rational(1,10), mpq_rational(2,9), mpq_rational(3,7),mpq_rational(3,5),mpq_rational(4,5),mpq_rational(1,1),mpq_rational(1,1)};
1051 inline static const Eigen::Matrix<mpq_rational,8,1> cRKDP56_ = Eigen::Matrix<mpq_rational,8,1>(cRKDP56Ptr_);
1052
1053 // RK Verner 67
1054 inline static const mpq_rational aRKV67Ptr_[] = {mpq_rational(0,1), mpq_rational(1,12),mpq_rational(0,1), mpq_rational(1,16),mpq_rational(21,16),mpq_rational(1344688,250563),mpq_rational(-559,384),mpq_rational(-625,224),mpq_rational(-12253,99144),mpq_rational(30517,2512), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(1,6), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(3,16),mpq_rational(-81,16),mpq_rational(-1709184,83521),mpq_rational(6,1),mpq_rational(12,1),mpq_rational(16,27),mpq_rational(-7296,157), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(9,2),mpq_rational(1365632,83521),mpq_rational(-204,47),mpq_rational(-456,47),mpq_rational(16,459),mpq_rational(268728,7379), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(-78208,250563),mpq_rational(14,39),mpq_rational(48,91),mpq_rational(29072,161109),mpq_rational(2472,2041), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(-4913,78208),mpq_rational(14739,136864),mpq_rational(-2023,75816),mpq_rational(-3522621,10743824), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(6,7),mpq_rational(112,12393),mpq_rational(132,157), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(-12393,4396), mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1),mpq_rational(0,1)};
1055 inline static const Eigen::Matrix<mpq_rational,10,10> aRKV67_ = Eigen::Matrix<mpq_rational,10,10>(aRKV67Ptr_);
1056 inline static const mpq_rational bRKV67Ptr_[] = {mpq_rational(2881,40320), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(1216,2961),mpq_rational(-2624,4095),mpq_rational(24137569,57482880),mpq_rational(-4,21),mpq_rational(0,1),mpq_rational(4131,3920),mpq_rational(-157,1260)};
1057 inline static const Eigen::Matrix<mpq_rational,10,1> bRKV67_ = Eigen::Matrix<mpq_rational,10,1>(bRKV67Ptr_);
1058 inline static const mpq_rational b_minus_bstarRKV67Ptr_[] = {mpq_rational(-17,2688), mpq_rational(0,1), mpq_rational(0,1), mpq_rational(272,4935),mpq_rational(-272,273),mpq_rational(24137569,57482880),mpq_rational(-34,105),mpq_rational(-7,90),mpq_rational(4131,3920),mpq_rational(-157,1260)};
1059 inline static const Eigen::Matrix<mpq_rational,10,1> b_minus_bstarRKV67_ = Eigen::Matrix<mpq_rational,10,1>(b_minus_bstarRKV67Ptr_);
1060 inline static const mpq_rational cRKV67Ptr_[] = {mpq_rational(0,1), mpq_rational(1,12), mpq_rational(1,6), mpq_rational(1,4),mpq_rational(3,4),mpq_rational(16,17),mpq_rational(1,2),mpq_rational(1,1),mpq_rational(2,3),mpq_rational(1,1)};
1061 inline static const Eigen::Matrix<mpq_rational,10,1> cRKV67_ = Eigen::Matrix<mpq_rational,10,1>(cRKV67Ptr_);
1062
1063
1064
1065 }; //re: ExplicitRKPredictor class
1066
1067
1068
1069
1070
1071
1072
1074 // Explicit instantiation declarations — suppress re-instantiation in every
1075 // including TU. The definitions live in core/src/tracking/explicit_predictors.cpp.
1076 // Concrete types: complex_dbl = std::complex<double>, complex_mp (multiprecision).
1077 // NumErrorT = double (from bertini2/common/config.hpp).
1078
1080 Vec<complex_dbl>&, StepMetadata&, System const&, Vec<complex_dbl> const&, complex_dbl, complex_dbl const&,
1081 unsigned&, unsigned, NumErrorT const&, AdaptiveMultiplePrecisionConfig const*);
1083 Vec<complex_mp>&, StepMetadata&, System const&, Vec<complex_mp> const&, complex_mp, complex_mp const&,
1084 unsigned&, unsigned, NumErrorT const&, AdaptiveMultiplePrecisionConfig const*);
1085
1087 Vec<complex_dbl>&, System const&, Vec<complex_dbl> const&, complex_dbl const&, complex_dbl const&);
1089 Vec<complex_mp>&, System const&, Vec<complex_mp> const&, complex_mp const&, complex_mp const&);
1090
1092 double&, double&, double&, unsigned&, unsigned);
1094 double&, double&, double&, unsigned&, unsigned);
1095
1098
1101
1103 System const&, Vec<complex_dbl> const&, complex_dbl const&, Mat<complex_dbl>&, unsigned);
1105 System const&, Vec<complex_mp> const&, complex_mp const&, Mat<complex_mp>&, unsigned);
1106
1107 extern template void ExplicitRKPredictor::FillButcherTable<double>(
1108 int, Mat<mpq_rational> const&, Mat<mpq_rational> const&,
1109 Mat<mpq_rational> const&, Mat<mpq_rational> const&);
1110 extern template void ExplicitRKPredictor::FillButcherTable<real_mp>(
1111 int, Mat<mpq_rational> const&, Mat<mpq_rational> const&,
1112 Mat<mpq_rational> const&, Mat<mpq_rational> const&);
1113
1114 extern template void ExplicitRKPredictor::FillButcherTable<double>(
1115 int, Mat<mpq_rational> const&, Mat<mpq_rational> const&, Mat<mpq_rational> const&);
1116 extern template void ExplicitRKPredictor::FillButcherTable<real_mp>(
1117 int, Mat<mpq_rational> const&, Mat<mpq_rational> const&, Mat<mpq_rational> const&);
1119
1120 } // re: predict
1121 }// re: tracking
1122}// re: bertini
1123
1124#endif
Provides the Adaptive Multiple Precision criteria functions.
The fundamental polynomial system class for Bertini2.
Definition system.hpp:106
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
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 JacobianInPlace(Mat< T > &J) const
Evaluate the Jacobian matrix of the system, using the previous space and time values,...
Definition system.hpp:413
size_t NumVariables() const
Get the total number of variables in this system, including homogenizing variables.
size_t NumTotalFunctions() const
Get the total number of functions, including patches.
Stateful partial-pivot LU factor/solve with preallocated, precision-adjustable banks.
Definition lu_solver.hpp:58
MatrixSuccessCode FactorDestructive(Mat< NumT > &A)
Factor A destructively (no copy): on return A holds the L\U factors.
Definition lu_solver.hpp:99
MatrixSuccessCode Factor(Mat< NumT > const &A)
Factor a copy of A with partial pivoting; A is preserved.
Definition lu_solver.hpp:90
Mat< NumT > const & Factors() const
The factored matrix (L below the diagonal, U on and above), for the caller's LUPartialPivotDecomposit...
Definition lu_solver.hpp:147
void Solve(Vec< NumT > const &b, Eigen::MatrixBase< OutDerived > const &x_out) const
Solve A x = b using the stored factors.
Definition lu_solver.hpp:111
SuccessCode FullStep(Vec< ComplexT > &next_space, System const &S, Vec< ComplexT > const &current_space, ComplexT const &current_time, ComplexT const &delta_t)
Performs a full prediction step from current_time to current_time + delta_t.
Definition explicit_predictors.hpp:588
SuccessCode EvalRHS(System const &S, const Vec< ComplexT > &space, const ComplexT &time, Mat< ComplexT > &K, unsigned stage)
Evaluates the RHS of the Davidenko differential equation at a particular time and space.
Definition explicit_predictors.hpp:771
void ChangePrecision(unsigned new_precision)
/brief Change the precision of the predictor variables and reassign the Butcher table variables.
Definition explicit_predictors.hpp:400
unsigned precision() const
get the current precision of the predictor
Definition explicit_predictors.hpp:389
Predictor PredictorMethod()
Get the currently used prediction method.
Definition explicit_predictors.hpp:530
bool HasErrorEstimate()
Get whether the current prediction method provides an error estimate.
Definition explicit_predictors.hpp:556
SuccessCode SetErrorEstimate(NumErrorT &error_estimate, ComplexT const &delta_t)
Computes the error estimate of this prediction step.
Definition explicit_predictors.hpp:686
ExplicitRKPredictor(Predictor method, const System &S)
Constructor for a particular predictor method.
Definition explicit_predictors.hpp:198
void PrecisionSanityCheck() const
Assert (in debug builds) that the predictor's state is all at the expected precision.
Definition explicit_predictors.hpp:433
SuccessCode Predict(Vec< ComplexT > &next_space, StepMetadata &meta, System const &S, const Vec< ComplexT > &current_space, ComplexT current_time, ComplexT const &delta_t, unsigned &num_steps_since_last_condition_number_computation, unsigned frequency_of_CN_estimation, NumErrorT const &tracking_tolerance, AdaptiveMultiplePrecisionConfig const *AMP_config=nullptr)
Perform a generic predictor step.
Definition explicit_predictors.hpp:482
unsigned Order()
Get the order of the currently used prediction method.
Definition explicit_predictors.hpp:546
void SetConditionProbe(std::tuple< Vec< complex_dbl >, Vec< complex_mp > > const &probe)
Adopt an externally-owned condition-number probe direction (both precisions).
Definition explicit_predictors.hpp:378
ExplicitRKPredictor(const System &S)
Construct a predictor to work on a system.
Definition explicit_predictors.hpp:186
void ResizeK()
Resize the internal Runge-Kutta stage matrix K to match the current system and stage count.
Definition explicit_predictors.hpp:360
void PredictorMethod(Predictor method)
/brief Sets the local variables to correspond to a particular predictor method
Definition explicit_predictors.hpp:212
void SetNormsCond(NumErrorT &norm_J, NumErrorT &norm_J_inverse, NumErrorT &condition_number_estimate, unsigned &num_steps_since_last_condition_number_computation, unsigned frequency_of_CN_estimation)
Compute and (when due) refresh the Jacobian norms and condition-number estimate.
Definition explicit_predictors.hpp:651
SuccessCode SetSizeProportion(NumErrorT &size_proportion, ComplexT const &delta_t)
Compute the size proportion variable for AMP computation.
Definition explicit_predictors.hpp:724
void ChangeSystem(const System &S)
Change the system (number of total functions) that the predictor uses.
Definition explicit_predictors.hpp:331
Bertini extensions of the Eigen linear algebra library.
A stateful partial-pivot LU solver that owns precision-adjustable temporary banks.
Extensions to the Boost.Multiprecision library.
bool CriterionA(double const &norm_J, double const &norm_J_inverse, AdaptiveMultiplePrecisionConfig const &AMP_config)
Check AMP Criterion A.
Definition amp_criteria.hpp:67
bool CriterionC(double const &norm_J_inverse, const Eigen::MatrixBase< Derived > &z, NumErrorT tracking_tolerance, AdaptiveMultiplePrecisionConfig const &AMP_config)
Check AMP Criterion C.
Definition amp_criteria.hpp:202
Definition explicit_predictors.hpp:48
bool HasErrorEstimate(Predictor predictor_choice)
Ask whether a predictor method provides an error estimate.
Definition explicit_predictors.hpp:122
Predictor DefaultPredictor()
Get the Bertini2 default predictor.
Definition explicit_predictors.hpp:70
unsigned Order(Predictor predictor_choice)
The order of the predictor.
Definition explicit_predictors.hpp:85
Definition adaptive_precision_utilities.hpp:35
Predictor
The predictor (ODE integration) method used during path tracking.
Definition config.hpp:55
@ RKCashKarp45
Definition config.hpp:63
@ Euler
Definition config.hpp:57
@ RKNorsett34
Definition config.hpp:61
@ RKDormandPrince56
Definition config.hpp:64
@ RKVerner67
Definition config.hpp:65
@ RKF45
Definition config.hpp:62
@ HeunEuler
Definition config.hpp:60
@ Constant
Definition config.hpp:56
@ Heun
Definition config.hpp:58
@ RK4
Definition config.hpp:59
Definition algorithm_builder.hpp:36
@ Success
The decomposition looks healthy.
Definition eigen_extensions.hpp:465
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
Mat< NumberType > RandomOfUnits(unsigned int rows, unsigned int cols)
Make a random matrix of units (numbers with norm 1).
Definition eigen_extensions.hpp:565
complex_dbl pow(const complex_dbl &z, int power)
Compute +,- integral powers of a std::complex<double> number.
Definition double_extensions.hpp:92
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
double NumErrorT
The numeric type used to hold error/tolerance magnitudes throughout Bertini2 – tracking tolerances,...
Definition num_traits.hpp:48
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
SuccessCode
Definition config.hpp:42
@ MatrixSolveFailureFirstPartOfPrediction
Definition config.hpp:57
@ Success
Definition config.hpp:51
@ MatrixSolveFailure
Definition config.hpp:56
@ HigherPrecisionNecessary
Definition config.hpp:52
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
unsigned ThreadPrecision()
Get the current thread's precision (digits).
Definition mpfr_complex.hpp:183
boost::multiprecision::number< boost::multiprecision::backends::gmp_rational, boost::multiprecision::et_on > mpq_rational
The exact rational number type.
Definition mpfr_extensions.hpp:55
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object.
Definition eigen_extensions.hpp:339
Holds the program parameters with respect to Adaptive Multiple Precision.
Definition config.hpp:214
Metadata produced by a single predict or correct step.
Definition config.hpp:84
NumErrorT error_estimate
embedded-method error estimate (predictor, embedded only).
Definition config.hpp:89
NumErrorT condition_number_estimate
norm_J * norm_J_inverse (refreshed per frequency_of_CN_estimation).
Definition config.hpp:87
NumErrorT size_proportion
AMP "a" (predictor only).
Definition config.hpp:88
NumErrorT norm_J_inverse
estimate of ||J^{-1}|| via the condition probe.
Definition config.hpp:86
NumErrorT norm_J
||J|| (Frobenius) at the step.
Definition config.hpp:85
Provides the bertini::System class.