Bertini 2 - C++ Core
Software for Numerical Algebraic Geometry
Loading...
Searching...
No Matches
newton_correct.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//newton_correct.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//newton_correct.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 newton_correct.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
33#ifndef BERTINI_NEWTON_CORRECT_HPP
34#define BERTINI_NEWTON_CORRECT_HPP
35
36
39#include "bertini2/system.hpp"
40
41namespace bertini{
42 namespace tracking{
43 namespace correct{
44
45
46
67 template <typename ComplexType, typename RealType>
68 SuccessCode NewtonLoop(Vec<ComplexType> & next_space,
69 System const& S,
70 Vec<ComplexType> const& current_space, // pass by value to get a copy of it
71 ComplexType const& current_time,
72 RealType const& tracking_tolerance,
73 unsigned min_num_newton_iterations,
74 unsigned max_num_newton_iterations)
75 {
76 #ifndef BERTINI_DISABLE_ASSERTS
77 assert(max_num_newton_iterations >= min_num_newton_iterations && "max number newton iterations must be at least the min.");
78 #endif
79
80
81 next_space = current_space;
82 for (unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
83 {
84 auto f = S.Eval(next_space, current_time);
85 auto J = S.Jacobian(next_space, current_time);
86 auto LU = J.lu();
87
88 if (LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=MatrixSuccessCode::Success)
89 return SuccessCode::MatrixSolveFailure;
90
91 auto delta_z = LU.solve(-f);
92 next_space += delta_z;
93
94 if ( (delta_z.norm() < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
95 return SuccessCode::Success;
96 }
97
98 return SuccessCode::FailedToConverge;
99 }
100
101
102
103
122 template <typename ComplexType, typename RealType>
123 SuccessCode NewtonLoop(Vec<ComplexType> & next_space,
124 System const& S,
125 Vec<ComplexType> const& current_space, // pass by value to get a copy of it
126 ComplexType const& current_time,
127 RealType const& tracking_tolerance,
128 unsigned min_num_newton_iterations,
129 unsigned max_num_newton_iterations,
130 AdaptiveMultiplePrecisionConfig const& AMP_config)
131 {
132 #ifndef BERTINI_DISABLE_ASSERTS
133 assert(max_num_newton_iterations >= min_num_newton_iterations && "max number newton iterations must be at least the min.");
134 #endif
135
136
137 next_space = current_space;
138 for (unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
139 {
140 //TODO: wrap these into a single line.
141 auto f = S.Eval(next_space, current_time);
142 auto J = S.Jacobian(next_space, current_time);
143 auto LU = J.lu();
144
145 if (LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=MatrixSuccessCode::Success)
146 return SuccessCode::MatrixSolveFailure;
147
148
149 auto delta_z = LU.solve(-f);
150 next_space += delta_z;
151
152 if ( (delta_z.norm() < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
153 return SuccessCode::Success;
154
155 auto norm_J_inverse = LU.solve(RandomOfUnits<ComplexType>(S.NumVariables())).norm();
156 if (!amp::CriterionB(J.norm(), norm_J_inverse, max_num_newton_iterations - ii, tracking_tolerance, delta_z.norm(), AMP_config))
157 return SuccessCode::HigherPrecisionNecessary;
158
159 if (!amp::CriterionC(norm_J_inverse, next_space, tracking_tolerance, AMP_config))
160 return SuccessCode::HigherPrecisionNecessary;
161 }
162
163 return SuccessCode::FailedToConverge;
164 }
165
166
167
168
169
170
171
194 template <typename ComplexType, typename RealType>
195 SuccessCode NewtonLoop(Vec<ComplexType> & next_space,
196 RealType & norm_delta_z,
197 RealType & norm_J,
198 RealType & norm_J_inverse,
199 RealType & condition_number_estimate,
200 System const& S,
201 Vec<ComplexType> const& current_space, // pass by value to get a copy of it
202 ComplexType const& current_time,
203 RealType const& tracking_tolerance,
204 unsigned min_num_newton_iterations,
205 unsigned max_num_newton_iterations,
206 AdaptiveMultiplePrecisionConfig const& AMP_config)
207 {
208 #ifndef BERTINI_DISABLE_ASSERTS
209 assert(max_num_newton_iterations >= min_num_newton_iterations && "max number newton iterations must be at least the min.");
210 #endif
211
212
213 next_space = current_space;
214 for (unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
215 {
216 //TODO: wrap these into a single line.
217 auto f = S.Eval(next_space, current_time);
218 auto J = S.Jacobian(next_space, current_time);
219 auto LU = J.lu();
220
221
222 if (LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=MatrixSuccessCode::Success)
223 return SuccessCode::MatrixSolveFailure;
224
225
226 auto delta_z = LU.solve(-f);
227 next_space += delta_z;
228
229
230 norm_delta_z = delta_z.norm();
231 norm_J = J.norm();
232 norm_J_inverse = LU.solve(RandomOfUnits<ComplexType>(S.NumVariables())).norm();
233 condition_number_estimate = norm_J*norm_J_inverse;
234
235
236
237 if ( (norm_delta_z < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
238 return SuccessCode::Success;
239
240 if (!amp::CriterionB(norm_J, norm_J_inverse, max_num_newton_iterations - ii, tracking_tolerance, norm_delta_z, AMP_config))
241 return SuccessCode::HigherPrecisionNecessary;
242
243 if (!amp::CriterionC(norm_J_inverse, next_space, tracking_tolerance, AMP_config))
244 return SuccessCode::HigherPrecisionNecessary;
245 }
246
247 return SuccessCode::FailedToConverge;
248 }
249 }
250
251 }
252
253}
254
255#endif
Provides the Adaptive Multiple Precision criteria functions.
bool CriterionC(double const &norm_J_inverse, const Eigen::MatrixBase< Derived > &z, double tracking_tolerance, AdaptiveMultiplePrecisionConfig const &AMP_config)
Check AMP Criterion C.
Definition amp_criteria.hpp:206
bool CriterionB(double const &norm_J, double const &norm_J_inverse, unsigned num_newton_iterations_remaining, double const &tracking_tolerance, double const &norm_of_latest_newton_residual, AdaptiveMultiplePrecisionConfig const &AMP_config)
Check AMP Criterion B.
Definition amp_criteria.hpp:132
The fundamental polynomial system class for Bertini2.
Definition system/system.hpp:99
Mat< T > Jacobian() const
Definition system/system.hpp:531
size_t NumVariables() const
Vec< T > Eval() const
Evaluate the system using the previously set variable (and time) values, creating vector of function ...
Definition system/system.hpp:317
Mat< NumberType > RandomOfUnits(uint rows, uint cols)
Make a random matrix of units (numbers with norm 1).
Definition eigen_extensions.hpp:502
MatrixSuccessCode LUPartialPivotDecompositionSuccessful(Eigen::MatrixBase< Derived > const &LU)
Check the diagonal elements of an LU decomposition for small values and large ratios.
Definition eigen_extensions.hpp:417
SuccessCode NewtonLoop(Vec< ComplexType > &next_space, System const &S, Vec< ComplexType > const &current_space, ComplexType const &current_time, RealType const &tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations)
Run Newton's method in fixed precision.
Definition newton_correct.hpp:68
Definition trackers/config.hpp:154
Collects the various header files which define the Bertini2 systems.
Configs and settings for tracking.