Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
base_tracker.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//base_tracker.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//base_tracker.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 base_tracker.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2021 by 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
22// individual authors of this file include:
23// silviana amethyst, university of wisconsin eau claire
24
32
33#ifndef BERTINI_BASE_TRACKER_HPP
34#define BERTINI_BASE_TRACKER_HPP
35
36#include <algorithm>
37//#include "bertini2/tracking/step.hpp"
39#include "bertini2/trackers/newton_corrector.hpp"
40#include "bertini2/logging.hpp"
41
43
44// Must be at the end of the include list
46
49
50namespace bertini{
51
52 namespace tracking{
53
135 template<class D>
136 class Tracker :
137 public Observable,
138 public detail::Configured<
139 typename TrackerTraits< D >::NeededConfigs
140 >
141 {
142 using NeededTypes = typename TrackerTraits< D >::NeededTypes;
143 using BaseComplexType = typename TrackerTraits<D>::BaseComplexType;
144 using BaseRealType = typename TrackerTraits<D>::BaseRealType;
145
146 using CT = BaseComplexType;
147 using RT = BaseRealType;
148
149
150 public:
152 using Stepping = SteppingConfig;
153 using Newton = NewtonConfig;
154 using PrecConf = typename TrackerTraits< D >::PrecisionConfig;
155
156 Tracker(System const& sys) : tracked_system_(std::ref(sys))
157 {
158 predictor_ = std::make_shared< predict::ExplicitRKPredictor >(predict::DefaultPredictor(), tracked_system_);
159 corrector_ = std::make_shared< correct::NewtonCorrector >(tracked_system_);
161 }
162
163
164
165
171 void Setup(Predictor new_predictor_choice,
172 double const& tracking_tolerance,
173 double const& path_truncation_threshold,
174 SteppingConfig const& stepping,
175 NewtonConfig const& newton)
176 {
177 SetPredictor(new_predictor_choice);
178 corrector_->Settings(newton);
179
180 SetTrackingTolerance(tracking_tolerance);
181
182 path_truncation_threshold_ = path_truncation_threshold;
183
184 this->template Set(stepping);
185 this->template Set(newton);
186
187 current_stepsize_ = BaseRealType(stepping.initial_step_size);
188 }
189
190
191 using Config::Get;
192
193
194
202 void SetTrackingTolerance(double const& tracking_tolerance)
203 {
204 if (tracking_tolerance <= 0)
205 throw std::runtime_error("tracking tolerance must be strictly positive");
206
207 tracking_tolerance_ = tracking_tolerance;
208 digits_tracking_tolerance_ = NumTraits<double>::TolToDigits(tracking_tolerance);
209 }
210
211
212 void SetInfiniteTruncationTolerance(double const& tol)
213 {
214 if (tol <= 0)
215 throw std::runtime_error("truncation threshold must be strictly positive");
216
218 }
219
220
232 SuccessCode TrackPath(Vec<CT> & solution_at_endtime,
233 CT const& start_time, CT const& endtime,
234 Vec<CT> const& start_point
235 ) const
236 {
237 if (start_point.size()!=GetSystem().NumVariables())
238 throw std::runtime_error("start point size must match the number of variables in the system to be tracked");
239
240
241
242 SuccessCode initialization_code = TrackerLoopInitialization(start_time, endtime, start_point);
243 if (initialization_code!=SuccessCode::Success)
244 {
246 return initialization_code;
247 }
248
249 // as precondition to this while loop, the correct container, either dbl or mpfr, must have the correct data.
250 while (!IsSymmRelDiffSmall(current_time_,endtime_, Eigen::NumTraits<CT>::epsilon()))
251 {
252 SuccessCode pre_iteration_code = PreIterationCheck();
253 if (pre_iteration_code!=SuccessCode::Success)
254 {
256 return pre_iteration_code;
257 }
258
259 using std::abs;
260 // compute the next delta_t
263 else
265
266
267 step_success_code_ = TrackerIteration();
268
269 if (infinite_path_truncation_ && (CheckGoingToInfinity()==SuccessCode::GoingToInfinity))
270 {
271 OnInfiniteTruncation();
273 return SuccessCode::GoingToInfinity;
274 }
275 else if (step_success_code_==SuccessCode::Success)
276 OnStepSuccess();
277 else
278 OnStepFail();
279
280 }// re: while
281
282
283 CopyFinalSolution(solution_at_endtime);
285 return SuccessCode::Success;
286 }
287
288
289
290
302 template<typename C>
303 SuccessCode Refine(Vec<C> & new_space,
304 Vec<C> const& start_point, C const& current_time) const
305 {
306
307 static_assert(detail::IsTemplateParameter<C,NeededTypes>::value,"complex type for refinement must be a used type for the tracker");
308 return this->AsDerived().RefineImpl(new_space, start_point, current_time);
309 }
310
311
312
313
327 template<typename C>
328 SuccessCode Refine(Vec<C> & new_space,
329 Vec<C> const& start_point, C const& current_time, double const& tolerance, unsigned max_iterations) const
330 {
331 static_assert(detail::IsTemplateParameter<C,NeededTypes>::value,"complex type for refinement must be a used type for the tracker");
332
333 return this->AsDerived().RefineImpl(new_space, start_point, current_time, tolerance, max_iterations);
334 }
335
336
344 void SetPredictor(Predictor new_predictor_choice)
345 {
346 predictor_->PredictorMethod(new_predictor_choice);
347 predictor_order_ = predictor_->Order();
348 }
349
350
354 Predictor GetPredictor() const
355 {
356 return predictor_->PredictorMethod();
357 }
358
359
363 void SetSystem(const System & new_sys)
364 {
365 tracked_system_ = std::ref(new_sys);
366 predictor_->ChangeSystem(tracked_system_);
367 corrector_->ChangeSystem(tracked_system_);
368 }
369
373 const System& GetSystem() const
374 {
375 return tracked_system_.get();
376 }
377
383 unsigned NumTotalStepsTaken () const
384 {
386 }
387
393 void SetStepSize(RT const& new_stepsize) const
394 {
395 current_stepsize_ = new_stepsize;
396 }
397
398
404 void ReinitializeInitialStepSize(bool should_reinitialize_stepsize)
405 {
406 reinitialize_stepsize_ = should_reinitialize_stepsize;
407 }
408
409 virtual ~Tracker() = default;
410
411 auto TrackingTolerance() const
412 {
413 return tracking_tolerance_;
414 }
415
416 auto InfiniteTruncationTolerance() const
417 {
419 }
420
421 private:
422
423 // convert the base tracker into the derived type.
424 const D& AsDerived() const
425 {
426 return static_cast<const D&>(*this);
427 }
428
436 virtual
437 SuccessCode TrackerLoopInitialization(CT const& start_time, CT const& end_time, Vec<CT> const& start_point) const = 0;
438
439
445 virtual
446 SuccessCode PreIterationCheck() const = 0;
447
453 virtual
454 SuccessCode TrackerIteration() const = 0;
455
461 virtual
462 void CopyFinalSolution(Vec<CT> & solution_at_endtime) const = 0;
463
464 // virtual
465 // void CopyFinalSolution(Vec<dbl> & solution_at_endtime) const = 0;
466
467
468 protected:
469
470
471
472
473
474 template <typename ComplexType>
475 SuccessCode CheckGoingToInfinity() const
476 {
477 if (GetSystem().DehomogenizePoint(std::get<Vec<ComplexType> >(current_space_)).norm() > path_truncation_threshold_)
478 return SuccessCode::GoingToInfinity;
479 else
480 return SuccessCode::Success;
481 }
482
483
484
488 virtual
489 void PostTrackCleanup() const
490 {}
491
497 virtual
498 void ResetCounters() const = 0;
499
500
501
502
503 void ResetCountersBase() const
504 {
505 // reset a bunch of counters to 0.
511 }
512
513
526
527 virtual
528 void OnStepSuccess() const = 0;
529
530
542
543
544 virtual
545 void OnStepFail() const = 0;
546
552 virtual
553 SuccessCode CheckGoingToInfinity() const = 0;
554
555 virtual
556 void OnInfiniteTruncation() const = 0;
557
558
559 std::reference_wrapper<const System> tracked_system_;
560
561 bool infinite_path_truncation_ = true;
563
564 // tracking the numbers of things
565 mutable unsigned num_total_steps_taken_;
569 mutable unsigned num_failed_steps_taken_;
570
571
572 // configuration for tracking
573 std::shared_ptr<predict::ExplicitRKPredictor > predictor_; // The predictor to use while tracking
575
576 std::shared_ptr<correct::NewtonCorrector> corrector_;
577
578
579
580 unsigned digits_final_ = 0;
582 NumErrorT tracking_tolerance_ = 1e-5;
584
585 mutable CT endtime_;
586 mutable CT current_time_;
587 mutable CT delta_t_;
588 mutable RT current_stepsize_;
589
590
591 // permanent temporaries
592 mutable RT next_stepsize_;
593 mutable SuccessCode step_success_code_;
594
595
596
600
601 using TupOfVec = typename NeededTypes::ToTupleOfVec;
602 using TupOfReal = typename NeededTypes::ToTupleOfReal;
603
604 mutable TupOfVec current_space_;
605 mutable TupOfVec tentative_space_;
606 mutable TupOfVec temporary_space_;
607
608
609 mutable NumErrorT condition_number_estimate_;
610 mutable NumErrorT error_estimate_;
611 mutable NumErrorT norm_J_;
612 mutable NumErrorT norm_J_inverse_;
613 mutable NumErrorT norm_delta_z_;
614 mutable NumErrorT size_proportion_;
615
616
617
618
619 public:
620
621
622 NumErrorT LatestConditionNumber() const
623 {
624 return this->condition_number_estimate_;
625 }
626
627
628 NumErrorT LatestErrorEstimate() const
629 {
630 return this->error_estimate_;
631 }
632
633
634 NumErrorT LatestNormOfStep() const
635 {
636 return this->norm_delta_z_;
637 }
638
639 void SetInfiniteTruncation(bool b)
640 {
641 infinite_path_truncation_ = b;
642 }
643
644 auto InfiniteTruncation()
645 {
646 return infinite_path_truncation_;
647 }
648
649 unsigned NumVariables() const
650 {
651 return GetSystem().NumVariables();
652 }
653
654 auto CurrentTime() const
655 {
656 return current_time_;
657 }
658
659 auto DeltaT() const
660 {
661 return delta_t_;
662 }
663
664 auto CurrentStepsize() const
665 {
666 return current_stepsize_;
667 }
668
669
670 virtual Vec<CT> CurrentPoint() const = 0;
671
672
673 virtual unsigned CurrentPrecision() const = 0;
674 };
675
676
677
678 } // re: namespace tracking
679} // re: namespace bertini
680
681
682#endif
683
684
Predictor DefaultPredictor()
Get the Bertini2 default predictor.
Definition base_predictor.hpp:58
An abstract observable type, maintaining a list of observers, who can be notified in case of Events.
Definition observable.hpp:48
The fundamental polynomial system class for Bertini2.
Definition system/system.hpp:99
size_t NumVariables() const
Base tracker class for trackers offered in Bertini2.
Definition base_tracker.hpp:141
void ReinitializeInitialStepSize(bool should_reinitialize_stepsize)
Switch resetting of initial step size to that of the stepping settings.
Definition base_tracker.hpp:404
unsigned predictor_order_
Definition base_tracker.hpp:574
Predictor GetPredictor() const
Query the currently set predictor.
Definition base_tracker.hpp:354
SuccessCode Refine(Vec< C > &new_space, Vec< C > const &start_point, C const &current_time, double const &tolerance, unsigned max_iterations) const
Refine a point to a given tolerance.
Definition base_tracker.hpp:328
NumErrorT error_estimate_
Definition base_tracker.hpp:610
virtual void PostTrackCleanup() const
Function to be called before exiting the tracker loop.
Definition base_tracker.hpp:489
CT current_time_
Definition base_tracker.hpp:586
const System & GetSystem() const
Definition base_tracker.hpp:373
unsigned num_successful_steps_since_stepsize_increase_
Definition base_tracker.hpp:598
NumErrorT size_proportion_
Definition base_tracker.hpp:614
SuccessCode TrackPath(Vec< CT > &solution_at_endtime, CT const &start_time, CT const &endtime, Vec< CT > const &start_point) const
Track a start point through time, from a start time to a target time.
Definition base_tracker.hpp:232
void SetSystem(const System &new_sys)
get a const reference to the system.
Definition base_tracker.hpp:363
NumErrorT path_truncation_threshold_
Definition base_tracker.hpp:583
void SetPredictor(Predictor new_predictor_choice)
Change tracker to use a predictor.
Definition base_tracker.hpp:344
unsigned digits_final_
Definition base_tracker.hpp:580
unsigned num_consecutive_successful_steps_
Definition base_tracker.hpp:567
CT endtime_
Definition base_tracker.hpp:585
RT current_stepsize_
Definition base_tracker.hpp:588
unsigned num_total_steps_taken_
Definition base_tracker.hpp:565
unsigned NumTotalStepsTaken() const
See how many steps have been taken.
Definition base_tracker.hpp:383
virtual void ResetCounters() const =0
Reset counters used during tracking.
NumErrorT condition_number_estimate_
Definition base_tracker.hpp:609
TupOfVec current_space_
The current space value.
Definition base_tracker.hpp:604
SuccessCode step_success_code_
Definition base_tracker.hpp:593
unsigned num_failed_steps_taken_
Definition base_tracker.hpp:569
unsigned num_steps_since_last_condition_number_computation_
Definition base_tracker.hpp:597
bool reinitialize_stepsize_
Definition base_tracker.hpp:562
NumErrorT norm_J_inverse_
Definition base_tracker.hpp:612
TupOfVec temporary_space_
Definition base_tracker.hpp:606
void IncrementBaseCountersFail() const
Increment and reset counters after a failed TrackerIteration()
Definition base_tracker.hpp:536
CT delta_t_
Definition base_tracker.hpp:587
void SetStepSize(RT const &new_stepsize) const
Set how large the stepsize should be.
Definition base_tracker.hpp:393
unsigned num_successful_steps_taken_
Definition base_tracker.hpp:566
TupOfVec tentative_space_
Definition base_tracker.hpp:605
unsigned digits_tracking_tolerance_
Definition base_tracker.hpp:581
virtual SuccessCode CheckGoingToInfinity() const =0
Check whether the path is going to infinity, as it tracks.
std::reference_wrapper< const System > tracked_system_
Reference to the system being tracked.
Definition base_tracker.hpp:559
void Setup(Predictor new_predictor_choice, double const &tracking_tolerance, double const &path_truncation_threshold, SteppingConfig const &stepping, NewtonConfig const &newton)
Get the tracker set up for tracking.
Definition base_tracker.hpp:171
unsigned num_consecutive_failed_steps_
Definition base_tracker.hpp:568
NumErrorT tracking_tolerance_
Definition base_tracker.hpp:582
NumErrorT norm_delta_z_
Definition base_tracker.hpp:613
SuccessCode Refine(Vec< C > &new_space, Vec< C > const &start_point, C const &current_time) const
Refine a point to tolerance implicitly internally set.
Definition base_tracker.hpp:303
unsigned num_successful_steps_since_precision_decrease_
Definition base_tracker.hpp:599
NumErrorT norm_J_
Definition base_tracker.hpp:611
void SetTrackingTolerance(double const &tracking_tolerance)
Set how tightly to track the path.
Definition base_tracker.hpp:202
void IncrementBaseCountersSuccess() const
Increment and reset counters after a successful TrackerIteration()
Definition base_tracker.hpp:519
Contains the detail/configured helper type, for templated getting/setting/storage of config structs.
bool IsSymmRelDiffSmall(T const &a, T const &b, typename Eigen::NumTraits< T >::Real const &e)
Check whether two values are very close to each other.
Definition eigen_extensions.hpp:369
Contains the detail/is_template_parameter helper, for checking whether a type is a template parameter...
Logging in Bertini using Boost.Log.
Contains the observable base types.
Includes for the suite of ODE predictors.
Definition configured.hpp:89
Contains the tracker/events base types.