Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
amp_endgame.hpp
1//This file is part of Bertini 2.
2//
3//amp_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//amp_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 amp_endgame.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// Tim Hodges, Colorado State University
25
26
27
28#pragma once
29
35
38
41
44namespace bertini{ namespace endgame {
45
46
47
51class AMPEndgame : public virtual EndgamePrecPolicyBase<tracking::AMPTracker>
52{
53public:
54 using TrackerT = tracking::AMPTracker;
55 using EmitterType = AMPEndgame;
56
57 template<typename... T>
58 static
59 unsigned EnsureAtUniformPrecision(T& ...args)
60 {
62 }
63
64 static
65 void EnsureAtPrecision(double & obj, unsigned prec)
66 {
67 if (prec!=DoublePrecision())
68 throw std::runtime_error("attempting to adjust precision of double to non-double precision");
69 }
70
71 static
72 void EnsureAtPrecision(std::complex<double> & obj, unsigned prec)
73 {
74 if (prec!=DoublePrecision())
75 throw std::runtime_error("attempting to adjust precision of std::complex<double> to non-double precision");
76 }
77
78 static
79 void EnsureAtPrecision(mpfr_float & obj, unsigned prec)
80 {
82 Precision(obj,prec);
83 }
84
85 static
86 void EnsureAtPrecision(mpfr_complex & obj, unsigned prec)
87 {
89 Precision(obj,prec);
90 }
91
92
93
94 SuccessCode RefineSampleImpl(Vec<mpfr_complex> & result, Vec<mpfr_complex> const& current_sample, mpfr_complex const& current_time, NumErrorT tol, unsigned max_iterations) const
95 {
96
98 assert(Precision(current_time)==Precision(current_sample) && "precision of sample and time to be refined in AMP endgame must match");
99
100 using RT = mpfr_float;
101 using std::max;
102 auto& TR = this->GetTracker();
103 TR.ChangePrecision(Precision(current_time));
104
105 auto refinement_success = this->GetTracker().Refine(result,current_sample,current_time,
106 tol,
107 max_iterations);
108
109
110 if (refinement_success==SuccessCode::HigherPrecisionNecessary ||
111 refinement_success==SuccessCode::FailedToConverge)
112 {
113
114
115 using bertini::Precision;
116
117 auto prev_precision = DefaultPrecision();
118 auto higher_precision = max(prev_precision,LowestMultiplePrecision())+ PrecisionIncrement();
119 DefaultPrecision(higher_precision);
120 this->GetTracker().ChangePrecision(higher_precision);
121
122 NotifyObservers(PrecisionChanged<EmitterType>(*this, prev_precision, higher_precision));
123
124 auto next_sample_higher_prec = current_sample;
125 Precision(next_sample_higher_prec, higher_precision);
126
127 auto result_higher_prec = Vec<mpfr_complex>(current_sample.size());
128
129 auto time_higher_precision = current_time;
130 Precision(time_higher_precision,higher_precision);
131
132 assert(time_higher_precision.precision()==DefaultPrecision());
133 refinement_success = this->GetTracker().Refine(result_higher_prec,
134 next_sample_higher_prec,
135 time_higher_precision,
136 tol,
137 max_iterations);
138
139 Precision(result, higher_precision);
140 result = result_higher_prec;
141
142 assert(Precision(result)==DefaultPrecision());
143 }
144 return refinement_success;
145 }
146
147
148
149
150 explicit
151 AMPEndgame(TrackerT const& new_tracker) : EndgamePrecPolicyBase<TrackerT>(new_tracker)
152 {}
153
154 virtual ~AMPEndgame() = default;
155
156}; // re: class AMPEndgame
157
158
159template<>
160struct EGPrecSelector<tracking::AMPTracker>
161{
162 using type = AMPEndgame;
163};
164
165
166} } // end namespaces
167
168
169
Functions for dealing with precisions of objects, particularly in the context of adaptive precision.
unsigned EnsureAtUniformPrecision(TimeCont< dbl > &times, SampCont< dbl > &samples)
Does not a thing, because cannot.
Definition adaptive_precision_utilities.hpp:114
Contains the AMPTracker type, and necessary functions.
void NotifyObservers(AnyEvent const &e) const
Sends an Event (more particularly, AnyEvent) to all watching observers of this object.
Definition observable.hpp:90
Specifies some necessaries for AMP style endgame implementations, which differ from the fixed precisi...
Definition amp_endgame.hpp:52
const tracking::AMPTracker & GetTracker() const
Definition prec_base.hpp:73
Functor-like class for tracking paths on a system.
Definition amp_tracker.hpp:346
SuccessCode ChangePrecision(unsigned new_precision) const
Definition amp_tracker.hpp:1303
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 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
Configs and settings for endgames.
Contains the endgames/events base types.
T max(T const &a, T const &b, T const &c)
Three-argument form of max.
Definition mpfr_extensions.hpp:98
Contains the observable base types.
Contains a parent class, EndgamePrecPolicyBase (an observable), from which the fixed double,...
Definition endgames/config.hpp:67