Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
observers.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//trackers/observers.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//trackers/observers.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 trackers/observers.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
27
28#pragma once
29
31
33
35#include "bertini2/logging.hpp"
36#include <boost/type_index.hpp>
37
38namespace bertini {
39
40 namespace tracking{
41
42
54 // Reset on Initializing, never on TrackingStarted, and never unsubscribe: a reset at
55 // TrackingStarted comes after the refinement and misses its increases, and an observer
56 // that unsubscribes reports one track forever after (#378).
57 template<class TrackerT>
59 : public TypedObserver< FirstPrecisionRecorder<TrackerT>, TrackerT,
60 Initializing<typename TrackerTraits<TrackerT>::EventEmitterType,
61 typename TrackerTraits<TrackerT>::BaseComplexT>,
62 TrackingStarted<typename TrackerTraits<TrackerT>::EventEmitterType>,
63 PrecisionChanged<typename TrackerTraits<TrackerT>::EventEmitterType> >
64 { BOOST_TYPE_INDEX_REGISTER_CLASS
65
66 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
67 using BCT = typename TrackerTraits<TrackerT>::BaseComplexT;
68
69 public:
70
73 {
74 have_start_ = false;
75 precision_increased_ = false;
76 starting_precision_ = 0;
77 next_precision_ = 0;
78 time_of_first_increase_ = typename TrackerTraits<TrackerT>::BaseComplexT{};
80 }
81
83 ObserveResult OnEvent(TrackingStarted<EmitterT> const& e)
84 {
85 if (!have_start_)
86 {
87 starting_precision_ = e.Get().CurrentPrecision();
88 have_start_ = true;
89 }
91 }
92
95 {
96 if (!have_start_)
97 {
98 starting_precision_ = e.Previous();
99 have_start_ = true;
100 }
101 if (!precision_increased_ && e.Next() > e.Previous())
102 {
103 precision_increased_ = true;
104 next_precision_ = e.Next();
105 time_of_first_increase_ = e.Get().CurrentTime();
106 }
108 }
109
111 unsigned StartPrecision() const
112 {
113 return starting_precision_;
114 }
115
117 unsigned NextPrecision() const
118 {
119 return next_precision_;
120 }
121
124 {
125 return precision_increased_;
126 }
127
130 {
131 return time_of_first_increase_;
132 }
133
134 virtual ~FirstPrecisionRecorder() = default;
135
136 private:
137
138 bool have_start_ = false;
139 unsigned starting_precision_ = 0;
140 unsigned next_precision_ = 0;
141 bool precision_increased_ = false;
142 typename TrackerTraits<TrackerT>::BaseComplexT time_of_first_increase_{};
143 };
144
145
155 template<class TrackerT>
157 : public TypedObserver< MinMaxPrecisionRecorder<TrackerT>, TrackerT,
158 Initializing<typename TrackerTraits<TrackerT>::EventEmitterType,
159 typename TrackerTraits<TrackerT>::BaseComplexT>,
160 TrackingStarted<typename TrackerTraits<TrackerT>::EventEmitterType>,
161 PrecisionChanged<typename TrackerTraits<TrackerT>::EventEmitterType> >
162 { BOOST_TYPE_INDEX_REGISTER_CLASS
163
164 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
165 using BCT = typename TrackerTraits<TrackerT>::BaseComplexT;
166
167 void Include(unsigned p)
168 {
169 if (p < min_precision_)
170 min_precision_ = p;
171 if (p > max_precision_)
172 max_precision_ = p;
173 }
174
175 public:
176
179 {
180 min_precision_ = std::numeric_limits<unsigned>::max();
181 max_precision_ = 0;
183 }
184
186 ObserveResult OnEvent(TrackingStarted<EmitterT> const& e)
187 {
188 Include(e.Get().CurrentPrecision());
190 }
191
194 {
195 Include(e.Previous());
196 Include(e.Next());
198 }
199
201 unsigned MinPrecision() const
202 {
203 return min_precision_;
204 }
205
207 unsigned MaxPrecision() const
208 {
209 return max_precision_;
210 }
211
213 void MinPrecision(unsigned m)
214 { min_precision_ = m;}
215
217 void MaxPrecision(unsigned m)
218 { max_precision_ = m;}
219
220 virtual ~MinMaxPrecisionRecorder() = default;
221
222 private:
223
224 unsigned min_precision_ = std::numeric_limits<unsigned>::max();
225 unsigned max_precision_ = 0;
226 };
227
228
237 // A per-track recorder starts afresh at every endgame sub-track, so a precision raised in
238 // an earlier sub-track and lowered before the last would go unreported (#378).
239 template<class TrackerT>
241 : public TypedObserver< PathPrecisionRecorder<TrackerT>, TrackerT,
242 TrackingStarted<typename TrackerTraits<TrackerT>::EventEmitterType>,
243 PrecisionChanged<typename TrackerTraits<TrackerT>::EventEmitterType> >
244 { BOOST_TYPE_INDEX_REGISTER_CLASS
245
246 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
247
248 void Include(unsigned p)
249 {
250 if (p < min_precision_)
251 min_precision_ = p;
252 if (p > max_precision_)
253 max_precision_ = p;
254 }
255
256 public:
257
259 void Reset()
260 {
261 precision_increased_ = false;
262 time_of_first_increase_ = typename TrackerTraits<TrackerT>::BaseComplexT{};
263 min_precision_ = std::numeric_limits<unsigned>::max();
264 max_precision_ = 0;
265 }
266
268 ObserveResult OnEvent(TrackingStarted<EmitterT> const& e)
269 {
270 Include(e.Get().CurrentPrecision());
272 }
273
276 {
277 Include(e.Previous());
278 Include(e.Next());
279 if (!precision_increased_ && e.Next() > e.Previous())
280 {
281 precision_increased_ = true;
282 time_of_first_increase_ = e.Get().CurrentTime();
283 }
285 }
286
288 bool DidPrecisionIncrease() const { return precision_increased_; }
289
291 typename TrackerTraits<TrackerT>::BaseComplexT TimeOfIncrease() const { return time_of_first_increase_; }
292
294 unsigned MinPrecision() const { return min_precision_; }
295
297 unsigned MaxPrecision() const { return max_precision_; }
298
299 virtual ~PathPrecisionRecorder() = default;
300
301 private:
302
303 bool precision_increased_ = false;
304 typename TrackerTraits<TrackerT>::BaseComplexT time_of_first_increase_{};
305 unsigned min_precision_ = std::numeric_limits<unsigned>::max();
306 unsigned max_precision_ = 0;
307 };
308
309
311 template<class TrackerT>
312 class PrecisionAccumulator : public Observer<TrackerT>
313 { BOOST_TYPE_INDEX_REGISTER_CLASS
314
315 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
316
317 virtual ObserveResult Observe(AnyEvent const& e) override
318 {
319 const TrackingEvent<EmitterT>* p = dynamic_cast<const TrackingEvent<EmitterT>*>(&e);
320 if (p)
321 {
322 precisions_.push_back(p->Get().CurrentPrecision());
323 }
325 }
326
327
328 public:
330 const std::vector<unsigned>& Precisions() const
331 {
332 return precisions_;
333 }
334
335 virtual ~PrecisionAccumulator() = default;
336
337 private:
338 std::vector<unsigned> precisions_;
339 };
340
346 template<class TrackerT, template<class> class EventT = SuccessfulStep>
348 : public TypedObserver< AMPPathAccumulator<TrackerT,EventT>, TrackerT,
349 EventT<typename TrackerTraits<TrackerT>::EventEmitterType> >
350 { BOOST_TYPE_INDEX_REGISTER_CLASS
351
352 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
353
354 public:
355
357 ObserveResult OnEvent(EventT<EmitterT> const& e)
358 {
359 path_.push_back(e.Get().CurrentPoint());
361 }
362
364 const std::vector<Vec<complex_mp> >& Path() const
365 {
366 return path_;
367 }
368
369 virtual ~AMPPathAccumulator() = default;
370
371 private:
372 std::vector<Vec<complex_mp> > path_;
373 };
374
375
376
378 template<class TrackerT>
379 class GoryDetailLogger : public Observer<TrackerT>
380 { BOOST_TYPE_INDEX_REGISTER_CLASS
381 public:
382
384
385 virtual ~GoryDetailLogger() = default;
386
388 virtual ObserveResult Observe(AnyEvent const& e) override
389 {
390
391
392 if (auto p = dynamic_cast<const Initializing<EmitterT,complex_dbl>*>(&e))
393 {
394 // digits to print come from the VALUES being printed -- not from the ambient
395 // default, which need not be the precision anything here was computed at, and
396 // not from the System, which no longer carries one (ADR-0057)
397 BOOST_LOG_TRIVIAL(severity_level::debug) << std::setprecision(static_cast<int>(DoublePrecision()))
398 << "initializing in double, tracking path\nfrom\tt = "
399 << p->StartTime() << "\nto\tt = " << p->EndTime()
400 << "\n from\tx = \n" << p->StartPoint()
401 << "\n tracking system " << p->Get().GetSystem() << "\n\n";
402 }
403 else if (auto p = dynamic_cast<const Initializing<EmitterT,complex_mp>*>(&e))
404 {
405 // ditto: ask the point being logged
406 BOOST_LOG_TRIVIAL(severity_level::debug) << std::setprecision(static_cast<int>(Precision(p->StartPoint())))
407 << "initializing in multiprecision, tracking path\nfrom\tt = " << p->StartTime() << "\nto\tt = " << p->EndTime() << "\n from\tx = \n" << p->StartPoint()
408 << "\n tracking system " << p->Get().GetSystem() << "\n\n";
409 }
410
411 else if(auto p = dynamic_cast<const TrackingEnded<EmitterT>*>(&e))
412 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracking ended";
413
414 else if (auto p = dynamic_cast<const NewStep<EmitterT>*>(&e))
415 {
416 auto& t = p->Get();
417 BOOST_LOG_TRIVIAL(severity_level::trace) << "Tracker iteration " << t.NumTotalStepsTaken() << "\ncurrent precision: " << t.CurrentPrecision();
418
419
420 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(static_cast<int>(t.CurrentPrecision()))
421 << "t = " << t.CurrentTime()
422 << "\ncurrent stepsize: " << t.CurrentStepsize()
423 << "\ndelta_t = " << t.DeltaT()
424 << "\ncurrent x size = " << t.CurrentPoint().size()
425 << "\ncurrent x = " << t.CurrentPoint();
426 }
427
428
429
430 else if (auto p = dynamic_cast<const SingularStartPoint<EmitterT>*>(&e))
431 BOOST_LOG_TRIVIAL(severity_level::trace) << "singular start point";
432 else if (auto p = dynamic_cast<const InfinitePathTruncation<EmitterT>*>(&e))
433 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration indicated going to infinity, truncated path";
434
435
436
437
438 else if (auto p = dynamic_cast<const SuccessfulStep<EmitterT>*>(&e))
439 {
440 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration successful\n\n\n";
441 }
442
443 else if (auto p = dynamic_cast<const FailedStep<EmitterT>*>(&e))
444 {
445 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration unsuccessful\n\n\n";
446 }
447
448
449
450
451
452
453 else if (auto p = dynamic_cast<const SuccessfulPredict<EmitterT,complex_mp>*>(&e))
454 {
455 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(static_cast<int>(Precision(p->ResultingPoint()))) << "prediction successful (complex_mp), result:\n" << p->ResultingPoint();
456 }
457 else if (auto p = dynamic_cast<const SuccessfulPredict<EmitterT,complex_dbl>*>(&e))
458 {
459 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(static_cast<int>(Precision(p->ResultingPoint()))) << "prediction successful (complex_dbl), result:\n" << p->ResultingPoint();
460 }
461
462 else if (auto p = dynamic_cast<const SuccessfulCorrect<EmitterT,complex_mp>*>(&e))
463 {
464 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(static_cast<int>(Precision(p->ResultingPoint()))) << "correction successful (complex_mp), result:\n" << p->ResultingPoint();
465 }
466 else if (auto p = dynamic_cast<const SuccessfulCorrect<EmitterT,complex_dbl>*>(&e))
467 {
468 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(static_cast<int>(Precision(p->ResultingPoint()))) << "correction successful (complex_dbl), result:\n" << p->ResultingPoint();
469 }
470
471
472 else if (auto p = dynamic_cast<const PredictorHigherPrecisionNecessary<EmitterT>*>(&e))
473 BOOST_LOG_TRIVIAL(severity_level::trace) << "Predictor, higher precision necessary";
474 else if (auto p = dynamic_cast<const CorrectorHigherPrecisionNecessary<EmitterT>*>(&e))
475 BOOST_LOG_TRIVIAL(severity_level::trace) << "corrector, higher precision necessary";
476
477
478
479 else if (auto p = dynamic_cast<const CorrectorMatrixSolveFailure<EmitterT>*>(&e))
480 BOOST_LOG_TRIVIAL(severity_level::trace) << "corrector, matrix solve failure or failure to converge";
481 else if (auto p = dynamic_cast<const PredictorMatrixSolveFailure<EmitterT>*>(&e))
482 BOOST_LOG_TRIVIAL(severity_level::trace) << "predictor, matrix solve failure or failure to converge";
483 else if (auto p = dynamic_cast<const FirstStepPredictorMatrixSolveFailure<EmitterT>*>(&e))
484 BOOST_LOG_TRIVIAL(severity_level::trace) << "Predictor, matrix solve failure in initial solve of prediction";
485
486
487 else if (auto p = dynamic_cast<const PrecisionChanged<EmitterT>*>(&e))
488 BOOST_LOG_TRIVIAL(severity_level::debug) << "changing precision from " << p->Previous() << " to " << p->Next();
489
490 else
491 BOOST_LOG_TRIVIAL(severity_level::debug) << "unlogged event, of type: " << boost::typeindex::type_id_runtime(e).pretty_name();
492
494 }
495
496 };
497
498
499
501 template<class TrackerT>
503 : public TypedObserver< StepFailScreenPrinter<TrackerT>, TrackerT,
504 FailedStep<typename TrackerTraits<TrackerT>::EventEmitterType> >
505 { BOOST_TYPE_INDEX_REGISTER_CLASS
506 public:
507
509
511 ObserveResult OnEvent(FailedStep<EmitterT> const& /*e*/)
512 {
513 std::cout << "observed step failure" << std::endl;
515 }
516
517 virtual ~StepFailScreenPrinter() = default;
518 };
519
520 } //re: namespace tracking
521
522}// re: namespace bertini
Contains the abstract base Tracker type, from which all other Trackers inherit.
Strawman Event type, enabling polymorphism.
Definition events.hpp:57
Actual observer type, which you should derive from to extract custom information from observable type...
Definition observer.hpp:117
CRTP base that turns an observer into a set of typed Observe() overloads.
Definition observer.hpp:201
Example usage: PathAccumulator<AMPTracker> path_accumulator;.
Definition observers.hpp:350
ObserveResult OnEvent(EventT< EmitterT > const &e)
On each observed event, append the tracker's current point to the path.
Definition observers.hpp:357
const std::vector< Vec< complex_mp > > & Path() const
Get the accumulated path of space points.
Definition observers.hpp:364
Observer that records the starting precision and the first precision increase of each track: each cal...
Definition observers.hpp:64
TrackerTraits< TrackerT >::BaseComplexT TimeOfIncrease() const
Get the time value at which precision first increased.
Definition observers.hpp:129
ObserveResult OnEvent(TrackingStarted< EmitterT > const &e)
Tracking starts after the start point is refined: the start precision, unless a refinement change alr...
Definition observers.hpp:83
unsigned NextPrecision() const
Get the precision after the first increase.
Definition observers.hpp:117
ObserveResult OnEvent(Initializing< EmitterT, BCT > const &)
A track begins: the record starts afresh.
Definition observers.hpp:72
bool DidPrecisionIncrease() const
Query whether precision increased at all during the track.
Definition observers.hpp:123
unsigned StartPrecision() const
Get the precision tracking started at.
Definition observers.hpp:111
ObserveResult OnEvent(PrecisionChanged< EmitterT > const &e)
A change of precision: the first one gives the start precision, and the first increase is recorded.
Definition observers.hpp:94
Observer that logs verbose ("gory detail") diagnostics for every tracking event.
Definition observers.hpp:380
typename TrackerTraits< TrackerT >::EventEmitterType EmitterT
The event-emitter type.
Definition observers.hpp:383
virtual ObserveResult Observe(AnyEvent const &e) override
Log a human-readable description of the event, dispatching on its dynamic type.
Definition observers.hpp:388
TrackPath is initializing the tracker.
Definition events.hpp:295
Observer that records the minimum and maximum precision of each track: each call to TrackPath,...
Definition observers.hpp:162
ObserveResult OnEvent(TrackingStarted< EmitterT > const &e)
Tracking starts: include the precision it starts at.
Definition observers.hpp:186
void MinPrecision(unsigned m)
Set the recorded minimum precision.
Definition observers.hpp:213
ObserveResult OnEvent(Initializing< EmitterT, BCT > const &)
A track begins: the record starts afresh.
Definition observers.hpp:178
void MaxPrecision(unsigned m)
Set the recorded maximum precision.
Definition observers.hpp:217
unsigned MinPrecision() const
Get the minimum precision observed.
Definition observers.hpp:201
ObserveResult OnEvent(PrecisionChanged< EmitterT > const &e)
A change of precision: include both ends of it.
Definition observers.hpp:193
unsigned MaxPrecision() const
Get the maximum precision observed.
Definition observers.hpp:207
Observer that records the precision a whole path used, across every call to TrackPath that tracks it:...
Definition observers.hpp:244
TrackerTraits< TrackerT >::BaseComplexT TimeOfIncrease() const
The time of the path's first precision increase.
Definition observers.hpp:291
void Reset()
Start the record of a new path.
Definition observers.hpp:259
unsigned MinPrecision() const
The lowest precision the path used; the maximum unsigned value if it saw none.
Definition observers.hpp:294
ObserveResult OnEvent(PrecisionChanged< EmitterT > const &e)
A change of precision: include both ends, and record the path's first increase.
Definition observers.hpp:275
bool DidPrecisionIncrease() const
Whether precision increased anywhere on the path.
Definition observers.hpp:288
ObserveResult OnEvent(TrackingStarted< EmitterT > const &e)
A track of the path starts: include the precision it starts at.
Definition observers.hpp:268
unsigned MaxPrecision() const
The highest precision the path used; 0 if it saw none.
Definition observers.hpp:297
Observer that collects the precision at every tracking event into a vector.
Definition observers.hpp:313
const std::vector< unsigned > & Precisions() const
Get the recorded sequence of precisions.
Definition observers.hpp:330
Event emitted when the tracker's working precision changes.
Definition events.hpp:139
auto Next() const
Get the next precision, what it changed to.
Definition events.hpp:166
auto Previous() const
Get the previous precision.
Definition events.hpp:161
Observer that prints a message to standard out whenever a step fails.
Definition observers.hpp:505
ObserveResult OnEvent(FailedStep< EmitterT > const &)
On a failed step, print a notice to standard out.
Definition observers.hpp:511
typename TrackerTraits< TrackerT >::EventEmitterType EmitterT
The event-emitter type.
Definition observers.hpp:508
The correct part of a time step was successful.
Definition events.hpp:102
The predict part of tracking step was successful.
Definition events.hpp:72
Logging in Bertini using Boost.Log.
Definition adaptive_precision_utilities.hpp:35
Definition algorithm_builder.hpp:36
constexpr unsigned DoublePrecision()
The number of digits considered "double precision" (16).
Definition num_traits.hpp:152
ObserveResult
The result an observer returns from Observe(), telling the observable whether to keep sending it even...
Definition observer.hpp:59
@ KeepObserving
Definition observer.hpp:59
@ SingularStartPoint
Definition config.hpp:62
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object.
Definition eigen_extensions.hpp:339
Contains the observer base types.
Trait lookup mapping a tracker type to its numeric types, event-emitter type, precision config,...
Definition config.hpp:387
Contains the tracker/events base types.