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//endgames/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//endgames/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 endgames/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#include "bertini2/logging.hpp"
33
34#include <boost/type_index.hpp>
35
36#include <vector>
37
38namespace bertini {
39
40 namespace endgame{
41
42
48template <typename EndgameT>
49struct GoryDetailLogger : public Observer<EndgameT>
50{BOOST_TYPE_INDEX_REGISTER_CLASS
51
52using EmitterT = EndgameT;
53using BCT = typename EndgameT::BaseComplexT;
54
55virtual ~GoryDetailLogger() = default;
56
57virtual ObserveResult Observe(AnyEvent const& e) override
58{
59 if(auto p = dynamic_cast<const TimeAdvanced<EmitterT>*>(&e))
60 {
61 BOOST_LOG_TRIVIAL(severity_level::debug) << "time advanced " << p->Get().LatestTime();
62 }
63
64 else if (auto p = dynamic_cast<const SampleRefined<EmitterT>*>(&e))
65 {
66 BOOST_LOG_TRIVIAL(severity_level::debug) << "refined a sample, huzzah";
67 }
68
69 else if (auto p = dynamic_cast<const CircleAdvanced<EmitterT>*>(&e))
70 {
71 BOOST_LOG_TRIVIAL(severity_level::debug) << "advanced around the circle, to " << p->NewSample()<< " at time " << p->NewTime();
72 }
73
74 else if (auto p = dynamic_cast<const ClosedLoop<EmitterT>*>(&e))
75 {
76 BOOST_LOG_TRIVIAL(severity_level::debug) << "closed a loop, cycle number " << p->Get().CycleNumber();
77 }
78 else if (auto p = dynamic_cast<const ApproximatedRoot<EmitterT>*>(&e))
79 {
80 BOOST_LOG_TRIVIAL(severity_level::debug) << "approximated the target root. approximation " << p->Get().template FinalApproximation<BCT>() << " with error " << p->Get().ApproximateError();
81 }
82
83 else if (auto p = dynamic_cast<const PrecisionChanged<AMPEndgame>*>(&e))
84 {
85 BOOST_LOG_TRIVIAL(severity_level::debug) << "precision changed from " << p->Previous() << " to " << p->Next();
86 }
87
88 else if (auto p = dynamic_cast<const InEGOperatingZone<EmitterT>*>(&e))
89 {
90 BOOST_LOG_TRIVIAL(severity_level::debug) << "made it to the endgame operating zone at time " << p->Get().LatestTime();
91 }
92
93 else if(auto p = dynamic_cast<const Converged<EmitterT>*>(&e))
94 {
95 BOOST_LOG_TRIVIAL(severity_level::debug) << "converged at time " << p->Get().LatestTime() << " with result " << p->Get().template FinalApproximation<BCT>() << " and residual " << p->Get().ApproximateError();
96 }
97 else if (auto p = dynamic_cast<const Initializing<EmitterT>*>(&e))
98 {
99 BOOST_LOG_TRIVIAL(severity_level::debug) << "starting running " << boost::typeindex::type_id<EmitterT>().pretty_name();
100 }
101 else
102 {
103 BOOST_LOG_TRIVIAL(severity_level::debug) << "unprogrammed response for event of type " << boost::typeindex::type_id_runtime(e).pretty_name();
104 }
105
107}
108
109}; // gory detail
110
111
112
124template <typename EndgameT>
125struct EventRecorder : public Observer<EndgameT>
126{BOOST_TYPE_INDEX_REGISTER_CLASS
127
128using EmitterT = EndgameT;
129using BCT = typename EndgameT::BaseComplexT;
130
131unsigned num_events = 0;
132unsigned num_time_advanced = 0;
133unsigned num_sample_refined = 0;
135unsigned num_closed_loop = 0;
137unsigned num_in_eg_zone = 0;
138unsigned num_converged = 0;
140
144
145virtual ObserveResult Observe(AnyEvent const& e) override
146{
147 ++num_events;
148 if (auto p = dynamic_cast<const TimeAdvanced<EmitterT>*>(&e))
149 { ++num_time_advanced; (void)p->Get().LatestTime(); }
150
151 else if (dynamic_cast<const SampleRefined<EmitterT>*>(&e))
152 { ++num_sample_refined; }
153
154 else if (auto p = dynamic_cast<const CircleAdvanced<EmitterT>*>(&e))
155 { ++num_circle_advanced; last_circle_point = p->NewSample(); last_circle_time = p->NewTime(); }
156
157 else if (dynamic_cast<const ClosedLoop<EmitterT>*>(&e))
158 { ++num_closed_loop; }
159
160 else if (auto p = dynamic_cast<const ApproximatedRoot<EmitterT>*>(&e))
161 { ++num_approximated_root; (void)p->Get().template FinalApproximation<BCT>(); (void)p->Get().ApproximateError(); }
162
163 else if (dynamic_cast<const InEGOperatingZone<EmitterT>*>(&e))
164 { ++num_in_eg_zone; }
165
166 else if (auto p = dynamic_cast<const Converged<EmitterT>*>(&e))
167 { ++num_converged; converged_point = p->Get().template FinalApproximation<BCT>(); (void)p->Get().LatestTime(); }
168
169 else if (dynamic_cast<const PrecisionChanged<AMPEndgame>*>(&e))
171
173}
174
175}; // EventRecorder
176
177
178
211template <typename EndgameT>
212struct SampleSequenceCollector : public Observer<EndgameT>
213{BOOST_TYPE_INDEX_REGISTER_CLASS
214
215using EmitterT = EndgameT;
216using BCT = typename EndgameT::BaseComplexT;
217
218std::vector<Vec<BCT>> path_samples;
219std::vector<BCT> path_times;
220
221std::vector<Vec<BCT>> circle_samples;
222std::vector<BCT> circle_times;
223
224std::vector<Vec<BCT>> approximations;
225std::vector<BCT> approximation_times;
226std::vector<NumErrorT> approximation_errors;
227std::vector<unsigned> cycle_numbers;
228
229std::vector<BCT> advance_times;
230
231// Run boundaries. One entry per endgame Run, holding the size each bucket had when that
232// run began -- so a collector attached to a whole solve can still tell one path from the
233// next. Samples of run j are path_samples[run_path_starts[j] .. run_path_starts[j+1]).
234std::vector<size_t> run_path_starts;
235std::vector<size_t> run_circle_starts;
236std::vector<size_t> run_approx_starts;
237
239
241void Clear()
242{
243 path_samples.clear(); path_times.clear();
244 circle_samples.clear(); circle_times.clear();
245 approximations.clear(); approximation_times.clear();
246 approximation_errors.clear(); cycle_numbers.clear();
247 advance_times.clear();
248 run_path_starts.clear(); run_circle_starts.clear();
249 run_approx_starts.clear();
251}
252
254size_t NumRuns() const { return run_path_starts.size(); }
255
257size_t NumSamples() const { return path_samples.size(); }
258
259virtual ObserveResult Observe(AnyEvent const& e) override
260{
261 if (auto p = dynamic_cast<const ComputedSamplePoint<EmitterT>*>(&e))
262 {
263 path_samples.push_back(p->NewSample());
264 path_times.push_back(p->NewTime());
265 }
266
267 else if (auto p = dynamic_cast<const CircleAdvanced<EmitterT>*>(&e))
268 {
269 circle_samples.push_back(p->NewSample());
270 circle_times.push_back(p->NewTime());
271 }
272
273 else if (auto p = dynamic_cast<const ApproximatedRoot<EmitterT>*>(&e))
274 {
275 approximations.push_back(p->Get().template FinalApproximation<BCT>());
276 approximation_times.push_back(p->Get().LatestTime());
277 approximation_errors.push_back(p->Get().ApproximateError());
278 cycle_numbers.push_back(p->Get().CycleNumber());
279 }
280
281 else if (auto p = dynamic_cast<const TimeAdvanced<EmitterT>*>(&e))
282 {
283 advance_times.push_back(p->Get().LatestTime());
284 }
285
286 else if (dynamic_cast<const Initializing<EmitterT>*>(&e))
287 {
288 run_path_starts.push_back(path_samples.size());
289 run_circle_starts.push_back(circle_samples.size());
290 run_approx_starts.push_back(approximations.size());
291 }
292
293 else if (dynamic_cast<const PrecisionChanged<EmitterT>*>(&e))
294 {
296 }
297
298 else if (dynamic_cast<const SamplesRecomputedAtHigherPrecision<EmitterT>*>(&e))
299 {
300 // The endgame needed a higher precision before it had its first approximation, and
301 // tracks its sample window again at the new precision. The samples it announced at
302 // the lower precision are superseded: drop them as the endgame does, so the sequence
303 // holds one approach at one precision and its times keep marching toward the target.
304 if (!run_path_starts.empty())
305 {
306 path_samples.resize(run_path_starts.back());
307 path_times.resize(run_path_starts.back());
308 circle_samples.resize(run_circle_starts.back());
309 circle_times.resize(run_circle_starts.back());
310 approximations.resize(run_approx_starts.back());
313 cycle_numbers.resize(run_approx_starts.back());
314 }
315 }
316
318}
319
320}; // SampleSequenceCollector
321
322
323 } //re: namespace endgames
324}// re: namespace bertini
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
Advanced around the circle around target time.
Definition events.hpp:157
A new sample point on the path was computed, adding one point to the sequence of the endgame's approa...
Definition events.hpp:118
Event emitted when the endgame's working precision changes.
Definition events.hpp:220
Contains the endgames/events base types.
Logging in Bertini using Boost.Log.
Definition endgames.hpp:44
Definition algorithm_builder.hpp:36
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
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
Contains the observer base types.
Counts endgame events and captures their payloads, for tests and diagnostics.
Definition observers.hpp:126
unsigned num_precision_changed
Number of precision-changed events observed.
Definition observers.hpp:139
unsigned num_closed_loop
Number of closed-loop events observed.
Definition observers.hpp:135
unsigned num_in_eg_zone
Number of in-endgame-zone events observed.
Definition observers.hpp:137
unsigned num_converged
Number of converged events observed.
Definition observers.hpp:138
BCT last_circle_time
The most-recent circle sample time captured from an event.
Definition observers.hpp:142
unsigned num_sample_refined
Number of SampleRefined events observed.
Definition observers.hpp:133
EndgameT EmitterT
The endgame type emitting the observed events.
Definition observers.hpp:128
unsigned num_events
Total number of events observed.
Definition observers.hpp:131
unsigned num_approximated_root
Number of approximated-root events observed.
Definition observers.hpp:136
typename EndgameT::BaseComplexT BCT
The boundary complex type of the observed endgame.
Definition observers.hpp:129
Vec< BCT > last_circle_point
The most-recent circle sample point captured from an event.
Definition observers.hpp:141
Vec< BCT > converged_point
The converged root point captured from a converged event.
Definition observers.hpp:143
virtual ObserveResult Observe(AnyEvent const &e) override
Observe the observable object being observed.
Definition observers.hpp:145
unsigned num_time_advanced
Number of TimeAdvanced events observed.
Definition observers.hpp:132
unsigned num_circle_advanced
Number of circle-advanced events observed.
Definition observers.hpp:134
Logs the endgame run, with gory detail.
Definition observers.hpp:50
EndgameT EmitterT
The event-emitter type.
Definition observers.hpp:52
virtual ObserveResult Observe(AnyEvent const &e) override
Observe the observable object being observed.
Definition observers.hpp:57
typename EndgameT::BaseComplexT BCT
The complex number type.
Definition observers.hpp:53
Collects an endgame's approach to the root as a time-indexed sequence, for callers that need to watch...
Definition observers.hpp:213
size_t NumRuns() const
Definition observers.hpp:254
std::vector< size_t > run_circle_starts
Index into circle_samples where each run's circle points begin.
Definition observers.hpp:235
std::vector< Vec< BCT > > approximations
Root approximations, from ApproximatedRoot.
Definition observers.hpp:224
std::vector< BCT > path_times
The time at which each path sample was computed.
Definition observers.hpp:219
std::vector< BCT > circle_times
The time of each circle sample.
Definition observers.hpp:222
typename EndgameT::BaseComplexT BCT
The boundary complex type of the observed endgame.
Definition observers.hpp:216
std::vector< BCT > advance_times
Times at which TimeAdvanced fired (that event carries no payload).
Definition observers.hpp:229
EndgameT EmitterT
The endgame type emitting the observed events.
Definition observers.hpp:215
size_t num_precision_increases
How many times the endgame raised its working precision (PrecisionChanged), over every run observed....
Definition observers.hpp:238
std::vector< unsigned > cycle_numbers
The endgame's cycle number at each approximation.
Definition observers.hpp:227
std::vector< Vec< BCT > > path_samples
Points on the path, from ComputedSamplePoint – the sequence.
Definition observers.hpp:218
std::vector< BCT > approximation_times
The endgame's latest time at each approximation.
Definition observers.hpp:225
void Clear()
Forget everything collected so far, so one collector can be reused across paths.
Definition observers.hpp:241
std::vector< NumErrorT > approximation_errors
The endgame's reported error at each approximation.
Definition observers.hpp:226
std::vector< size_t > run_approx_starts
Index into approximations where each run's approximations begin.
Definition observers.hpp:236
virtual ObserveResult Observe(AnyEvent const &e) override
Observe the observable object being observed.
Definition observers.hpp:259
std::vector< Vec< BCT > > circle_samples
Circle-track points, from CircleAdvanced (Cauchy only).
Definition observers.hpp:221
size_t NumSamples() const
Definition observers.hpp:257
std::vector< size_t > run_path_starts
Index into path_samples where each run's samples begin.
Definition observers.hpp:234