Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
base_endgame.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//base_endgame.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_endgame.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_endgame.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) 2015 - 2025 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// Tim Hodges, Colorado State University
25
26
27
28#ifndef BERTINI_BASE_ENDGAME_HPP
29#define BERTINI_BASE_ENDGAME_HPP
30
31#pragma once
39
40#include <iostream>
41#include <typeinfo>
42
43
45
47
49
54
55#include "bertini2/logging.hpp"
56
58
59
60namespace bertini{ namespace endgame {
61
62
90template<class FlavorT, class PrecT>
91class EndgameBase :
92 public detail::Configured< typename AlgoTraits<FlavorT>::NeededConfigs >,
93 public PrecT,
94 public virtual Observable
95{
96public:
97 using TrackerType = typename PrecT::TrackerType;
98
99 using BaseComplexType = typename tracking::TrackerTraits<TrackerType>::BaseComplexType;
100 using BaseRealType = typename tracking::TrackerTraits<TrackerType>::BaseRealType;
101
102 using EmitterType = FlavorT;
103
104protected:
105
106 using BCT = BaseComplexType;
107 using BRT = BaseRealType;
108
109
110 using Configured = detail::Configured< typename AlgoTraits<FlavorT>::NeededConfigs >;
111 using Configs = typename AlgoTraits<FlavorT>::NeededConfigs;
112 using ConfigsAsTuple = typename Configs::ToTuple;
113
114 // a list of all the needed arithemtic types (complex for complex trackers)
115 using NeededTypes = detail::TypeList<BCT>;
116 using TupOfVec = typename NeededTypes::ToTupleOfVec;
117 using TupOfReal = typename NeededTypes::ToTupleOfReal;
118 using TupleOfTimes = typename NeededTypes::template ToTupleOfCont<TimeCont>;
119 using TupleOfSamps = typename NeededTypes::template ToTupleOfCont<SampCont>;
120
121
122
123 // universal endgame state variables
124 mutable Vec<BCT> final_approximation_;
125 mutable Vec<BCT> previous_approximation_;
126 mutable unsigned int cycle_number_ = 0;
127 mutable NumErrorT approximate_error_;
128
129
130
131
132
138 const FlavorT& AsFlavor() const
139 {
140 return dynamic_cast<const FlavorT&>(*this);
141 }
142
146 FlavorT& AsFlavor()
147 {
148 return dynamic_cast<FlavorT&>(*this);
149 }
150
151public:
152
156 SuccessCode Run(const BCT & start_time, const Vec<BCT> & start_point, BCT const& target_time)
157 {
158 return this->AsFlavor().RunImpl(start_time, start_point, target_time);
159 }
160
166 SuccessCode Run(BCT const& start_time, Vec<BCT> const& start_point)
167 {
168 return Run(start_time, start_point, static_cast<BCT>(0));
169 }
170
171
172 template<typename CT>
173 SuccessCode RefineAllSamples(SampCont<CT> & samples, TimeCont<CT> & times)
174 {
175 for (size_t ii=0; ii<samples.size(); ++ii)
176 {
177 auto refine_success = this->RefineSample(samples[ii], samples[ii], times[ii],
178 this->FinalTolerance() * this->EndgameSettings().sample_point_refinement_factor,
179 this->EndgameSettings().max_num_newton_iterations);
180 if (refine_success != SuccessCode::Success)
181 {
182 // BOOST_LOG_TRIVIAL(severity_level::trace) << "refining failed, code " << int(refine_success);
183 return refine_success;
184 }
185 NotifyObservers(SampleRefined<EmitterType>(AsFlavor()));
186 }
187
188 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec) // known at compile time
189 {
190 auto max_precision = this->EnsureAtUniformPrecision(times, samples);
191 this->GetSystem().precision(max_precision);
192 }
193
194 return SuccessCode::Success;
195 }
196
197
201 SuccessCode RefineSample(Vec<BCT> & result, Vec<BCT> const& current_sample, BCT const& current_time, NumErrorT tol, unsigned max_iterations) const
202 {
203 return this->RefineSampleImpl(result, current_sample, current_time, tol, max_iterations);
204 }
205
206 void ChangePrecision(unsigned p)
207 {
208 AsFlavor().ChangePrecision(p);
209 PrecT::ChangePrecision(p);
210 ChangePrecision(this->final_approximation_,p);
211 ChangePrecision(this->previous_approximation_,p);
212 }
213
214
218 inline
219 const auto & EndgameSettings() const
220 {
221 return Configured::template Get<EndgameConfig>();
222 }
223
224 inline
225 const auto & SecuritySettings() const
226 {
227 return this->template Get<SecurityConfig>();
228 }
229
230 explicit EndgameBase(TrackerType const& tr, const ConfigsAsTuple& settings ) :
231 Configured( settings ), PrecT(tr), EndgamePrecPolicyBase<TrackerType>(tr)
232 {}
233
234
235 template< typename... Ts >
236 explicit
237 EndgameBase(TrackerType const& tr, const Ts&... ts ) : EndgameBase(tr, Configs::Unpermute( ts... ) )
238 {}
239
240
241 inline unsigned CycleNumber() const { return cycle_number_;}
242 inline void CycleNumber(unsigned c) { cycle_number_ = c;}
243 inline void IncrementCycleNumber(unsigned inc) { cycle_number_ += inc;}
244
245
249 inline
250 const auto& FinalTolerance() const
251 {
252 return this->template Get<EndgameConfig>().final_tolerance;
253 }
254
255
256
260 inline
261 void SetFinalTolerance(BRT const& ft){this->template Get<EndgameConfig>().final_tolerance = ft;}
262
263
264
265
269 template<typename CT>
270 inline
271 const Vec<CT>& FinalApproximation() const
272 {
273 return final_approximation_;
274 }
275
279 template<typename CT>
280 inline
281 const Vec<CT>& PreviousApproximation() const
282 {
283 return previous_approximation_;
284 }
285
289 inline
290 NumErrorT ApproximateError() const
291 {
292 return approximate_error_;
293 }
294
295
299 inline
300 const BCT& LatestTime() const
301 {
302 return AsFlavor().LatestTimeImpl();
303 }
304
305 // /**
306 // \brief Get the system being tracked on, which is referred to by the tracker.
307 // */
308 // inline
309 // const System& GetSystem() const
310 // {
311 // return GetTracker().GetSystem();
312 // }
313
314
345 template<typename CT>
346 SuccessCode ComputeInitialSamples(const CT & start_time,const CT & target_time, const Vec<CT> & x_endgame_start, TimeCont<CT> & times, SampCont<CT> & samples) // passed by reference to allow times to be filled as well.
347 {
348 using RT = typename Eigen::NumTraits<CT>::Real;
349 assert(this->template Get<EndgameConfig>().num_sample_points>0 && "number of sample points must be positive");
350
351 if (tracking::TrackerTraits<TrackerType>::IsAdaptivePrec)
352 {
353 assert(Precision(start_time)==Precision(x_endgame_start) && "Computing initial samples requires input time and space with uniform precision");
354 }
355
356 samples.clear();
357 times.clear();
358
359 samples.push_back(x_endgame_start);
360 times.push_back(start_time);
361
362 auto num_vars = this->GetSystem().NumVariables();
363 //start at 1, because the input point is the 0th element.
364 for(int ii=1; ii < this->template Get<EndgameConfig>().num_sample_points; ++ii)
365 {
366 times.emplace_back((times[ii-1] + target_time) * RT(this->template Get<EndgameConfig>().sample_factor)); // next time is a point between the previous time and target time.
367 samples.emplace_back(Vec<CT>(num_vars)); // sample_factor gives us some point between the two, usually the midpoint.
368
369 auto tracking_success = this->GetTracker().TrackPath(samples[ii],times[ii-1],times[ii],samples[ii-1]);
370 this->EnsureAtPrecision(times[ii],Precision(samples[ii]));
371
372 if (tracking_success!=SuccessCode::Success)
373 return tracking_success;
374 }
375
376 return SuccessCode::Success;
377 }
378
379 virtual ~EndgameBase() = default;
380};
381
382} }// end namespaces bertini
383
384
385#endif
void NotifyObservers(AnyEvent const &e) const
Sends an Event (more particularly, AnyEvent) to all watching observers of this object.
Definition observable.hpp:90
Contains the detail/configured helper type, for templated getting/setting/storage of config structs.
Configs and settings for endgames.
Contains the endgames/events base types.
Logging in Bertini using Boost.Log.
The main multiprecision complex number type. This is essentially boost::multiprecision' complex.
Provides the bertini::System class.
Configs and settings for tracking.