Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
trackers/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) 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
25
31
32#pragma once
33
35
37
39#include "bertini2/logging.hpp"
40#include <boost/type_index.hpp>
41
42namespace bertini {
43
44 namespace tracking{
45
46
47 template<class TrackerT>
48 class FirstPrecisionRecorder : public Observer<TrackerT>
49 { BOOST_TYPE_INDEX_REGISTER_CLASS
50
51 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
52
53 virtual void Observe(AnyEvent const& e) override
54 {
55 if(auto p = dynamic_cast<const TrackingStarted<EmitterT>*>(&e))
56 {
57 precision_increased_ = false;
58 starting_precision_ = p->Get().CurrentPrecision();
59 }
60 else if (auto p = dynamic_cast<const PrecisionChanged<EmitterT>*>(&e))
61 {
62 auto& t = p->Get();
63 auto next = p->Next();
64 if (next > p->Previous())
65 {
66 precision_increased_ = true;
67 next_precision_ = next;
68 time_of_first_increase_ = t.CurrentTime();
69 t.RemoveObserver(*this);
70 }
71
72 }
73 }
74
75
76
77
78 public:
79
80 unsigned StartPrecision() const
81 {
82 return starting_precision_;
83 }
84
85 unsigned NextPrecision() const
86 {
87 return next_precision_;
88 }
89
90 bool DidPrecisionIncrease() const
91 {
92 return precision_increased_;
93 }
94
95 typename TrackerTraits<TrackerT>::BaseComplexType TimeOfIncrease() const
96 {
97 return time_of_first_increase_;
98 }
99
100 virtual ~FirstPrecisionRecorder() = default;
101
102 private:
103
104 unsigned starting_precision_;
105 unsigned next_precision_;
106 bool precision_increased_;
107 typename TrackerTraits<TrackerT>::BaseComplexType time_of_first_increase_;
108 };
109
110
111 template<class TrackerT>
112 class MinMaxPrecisionRecorder : public Observer<TrackerT>
113 { BOOST_TYPE_INDEX_REGISTER_CLASS
114
115 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
116
117 virtual void Observe(AnyEvent const& e) override
118 {
119 if (auto p = dynamic_cast<const PrecisionChanged<EmitterT>*>(&e))
120 {
121 auto next_precision = p->Next();
122 if (next_precision < min_precision_)
123 min_precision_ = next_precision;
124 if (next_precision > max_precision_)
125 max_precision_ = next_precision;
126 }
127 else if(auto p = dynamic_cast<const TrackingStarted<EmitterT>*>(&e))
128 {
129 min_precision_ = p->Get().CurrentPrecision();
130 max_precision_ = p->Get().CurrentPrecision();
131 }
132 }
133
134
135
136
137 public:
138
139 unsigned MinPrecision() const
140 {
141 return min_precision_;
142 }
143
144 unsigned MaxPrecision() const
145 {
146 return max_precision_;
147 }
148
149 void MinPrecision(unsigned m)
150 { min_precision_ = m;}
151
152 void MaxPrecision(unsigned m)
153 { max_precision_ = m;}
154
155 virtual ~MinMaxPrecisionRecorder() = default;
156
157 private:
158
159 unsigned min_precision_ = std::numeric_limits<unsigned>::max();
160 unsigned max_precision_ = 0;
161 };
162
163
164 template<class TrackerT>
165 class PrecisionAccumulator : public Observer<TrackerT>
166 { BOOST_TYPE_INDEX_REGISTER_CLASS
167
168 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
169
170 virtual void Observe(AnyEvent const& e) override
171 {
172 const TrackingEvent<EmitterT>* p = dynamic_cast<const TrackingEvent<EmitterT>*>(&e);
173 if (p)
174 {
175 precisions_.push_back(p->Get().CurrentPrecision());
176 }
177 }
178
179
180 public:
181 const std::vector<unsigned>& Precisions() const
182 {
183 return precisions_;
184 }
185
186 virtual ~PrecisionAccumulator() = default;
187
188 private:
189 std::vector<unsigned> precisions_;
190 };
191
196 template<class TrackerT, template<class> class EventT = SuccessfulStep>
197 class AMPPathAccumulator : public Observer<TrackerT>
198 { BOOST_TYPE_INDEX_REGISTER_CLASS
199
200 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
201
202 virtual void Observe(AnyEvent const& e) override
203 {
204 const EventT<EmitterT>* p = dynamic_cast<const EventT<EmitterT>*>(&e);
205 if (p)
206 {
207 path_.push_back(p->Get().CurrentPoint());
208 }
209 }
210
211
212 public:
213 const std::vector<Vec<mpfr_complex> >& Path() const
214 {
215 return path_;
216 }
217
218 virtual ~AMPPathAccumulator() = default;
219
220 private:
221 std::vector<Vec<mpfr_complex> > path_;
222 };
223
224
225
226 template<class TrackerT>
227 class GoryDetailLogger : public Observer<TrackerT>
228 { BOOST_TYPE_INDEX_REGISTER_CLASS
229 public:
230
231 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
232
233 virtual ~GoryDetailLogger() = default;
234
235 virtual void Observe(AnyEvent const& e) override
236 {
237
238
239 if (auto p = dynamic_cast<const Initializing<EmitterT,dbl>*>(&e))
240 {
241 BOOST_LOG_TRIVIAL(severity_level::debug) << std::setprecision(p->Get().GetSystem().precision())
242 << "initializing in double, tracking path\nfrom\tt = "
243 << p->StartTime() << "\nto\tt = " << p->EndTime()
244 << "\n from\tx = \n" << p->StartPoint()
245 << "\n tracking system " << p->Get().GetSystem() << "\n\n";
246 }
247 else if (auto p = dynamic_cast<const Initializing<EmitterT,mpfr_complex>*>(&e))
248 {
249 BOOST_LOG_TRIVIAL(severity_level::debug) << std::setprecision(p->Get().GetSystem().precision())
250 << "initializing in multiprecision, tracking path\nfrom\tt = " << p->StartTime() << "\nto\tt = " << p->EndTime() << "\n from\tx = \n" << p->StartPoint()
251 << "\n tracking system " << p->Get().GetSystem() << "\n\n";
252 }
253
254 else if(auto p = dynamic_cast<const TrackingEnded<EmitterT>*>(&e))
255 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracking ended";
256
257 else if (auto p = dynamic_cast<const NewStep<EmitterT>*>(&e))
258 {
259 auto& t = p->Get();
260 BOOST_LOG_TRIVIAL(severity_level::trace) << "Tracker iteration " << t.NumTotalStepsTaken() << "\ncurrent precision: " << t.CurrentPrecision();
261
262
263 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(t.CurrentPrecision())
264 << "t = " << t.CurrentTime()
265 << "\ncurrent stepsize: " << t.CurrentStepsize()
266 << "\ndelta_t = " << t.DeltaT()
267 << "\ncurrent x size = " << t.CurrentPoint().size()
268 << "\ncurrent x = " << t.CurrentPoint();
269 }
270
271
272
273 else if (auto p = dynamic_cast<const SingularStartPoint<EmitterT>*>(&e))
274 BOOST_LOG_TRIVIAL(severity_level::trace) << "singular start point";
275 else if (auto p = dynamic_cast<const InfinitePathTruncation<EmitterT>*>(&e))
276 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration indicated going to infinity, truncated path";
277
278
279
280
281 else if (auto p = dynamic_cast<const SuccessfulStep<EmitterT>*>(&e))
282 {
283 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration successful\n\n\n";
284 }
285
286 else if (auto p = dynamic_cast<const FailedStep<EmitterT>*>(&e))
287 {
288 BOOST_LOG_TRIVIAL(severity_level::trace) << "tracker iteration unsuccessful\n\n\n";
289 }
290
291
292
293
294
295
296 else if (auto p = dynamic_cast<const SuccessfulPredict<EmitterT,mpfr_complex>*>(&e))
297 {
298 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(Precision(p->ResultingPoint())) << "prediction successful (mpfr_complex), result:\n" << p->ResultingPoint();
299 }
300 else if (auto p = dynamic_cast<const SuccessfulPredict<EmitterT,dbl>*>(&e))
301 {
302 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(Precision(p->ResultingPoint())) << "prediction successful (dbl), result:\n" << p->ResultingPoint();
303 }
304
305 else if (auto p = dynamic_cast<const SuccessfulCorrect<EmitterT,mpfr_complex>*>(&e))
306 {
307 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(Precision(p->ResultingPoint())) << "correction successful (mpfr_complex), result:\n" << p->ResultingPoint();
308 }
309 else if (auto p = dynamic_cast<const SuccessfulCorrect<EmitterT,dbl>*>(&e))
310 {
311 BOOST_LOG_TRIVIAL(severity_level::trace) << std::setprecision(Precision(p->ResultingPoint())) << "correction successful (dbl), result:\n" << p->ResultingPoint();
312 }
313
314
315 else if (auto p = dynamic_cast<const PredictorHigherPrecisionNecessary<EmitterT>*>(&e))
316 BOOST_LOG_TRIVIAL(severity_level::trace) << "Predictor, higher precision necessary";
317 else if (auto p = dynamic_cast<const CorrectorHigherPrecisionNecessary<EmitterT>*>(&e))
318 BOOST_LOG_TRIVIAL(severity_level::trace) << "corrector, higher precision necessary";
319
320
321
322 else if (auto p = dynamic_cast<const CorrectorMatrixSolveFailure<EmitterT>*>(&e))
323 BOOST_LOG_TRIVIAL(severity_level::trace) << "corrector, matrix solve failure or failure to converge";
324 else if (auto p = dynamic_cast<const PredictorMatrixSolveFailure<EmitterT>*>(&e))
325 BOOST_LOG_TRIVIAL(severity_level::trace) << "predictor, matrix solve failure or failure to converge";
326 else if (auto p = dynamic_cast<const FirstStepPredictorMatrixSolveFailure<EmitterT>*>(&e))
327 BOOST_LOG_TRIVIAL(severity_level::trace) << "Predictor, matrix solve failure in initial solve of prediction";
328
329
330 else if (auto p = dynamic_cast<const PrecisionChanged<EmitterT>*>(&e))
331 BOOST_LOG_TRIVIAL(severity_level::debug) << "changing precision from " << p->Previous() << " to " << p->Next();
332
333 else
334 BOOST_LOG_TRIVIAL(severity_level::debug) << "unlogged event, of type: " << boost::typeindex::type_id_runtime(e).pretty_name();
335 }
336
337 };
338
339
340
341 template<class TrackerT>
342 class StepFailScreenPrinter : public Observer<TrackerT>
343 { BOOST_TYPE_INDEX_REGISTER_CLASS
344 public:
345
346 using EmitterT = typename TrackerTraits<TrackerT>::EventEmitterType;
347
348 virtual void Observe(AnyEvent const& e) override
349 {
350 if (auto p = dynamic_cast<const FailedStep<EmitterT>*>(&e))
351 std::cout << "observed step failure" << std::endl;
352 }
353
354 virtual ~StepFailScreenPrinter() = default;
355 };
356
357 } //re: namespace tracking
358
359}// re: namespace bertini
Contains the abstract base Tracker type, from which all other Trackers inherit.
Strawman Event type, enabling polymorphism.
Definition detail/events.hpp:47
Actual observer type, which you should derive from to extract custom information from observable type...
Definition observer.hpp:82
Definition trackers/observers.hpp:198
TrackPath is initializing the tracker.
Definition trackers/events.hpp:298
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object. If the object is empty, it's the precision of a default-constru...
Definition eigen_extensions.hpp:292
Logging in Bertini using Boost.Log.
Contains the observer base types.
Contains the tracker/events base types.