9#ifndef BERTINI_NEWTON_CORRECTOR_HPP
10#define BERTINI_NEWTON_CORRECTOR_HPP
49 NewtonCorrector(
const System& S) : current_precision_(DefaultPrecision())
67 void Settings(
const NewtonConfig& newton_settings)
69 newton_config_ = newton_settings;
84 Precision(std::get< Vec<mpfr_complex> >(f_temp_), new_precision);
85 Precision(std::get< Vec<mpfr_complex> >(step_temp_), new_precision);
86 Precision(std::get< Mat<mpfr_complex> >(J_temp_), new_precision);
88 std::get< Eigen::PartialPivLU<Mat<mpfr_complex>> >(LU_) = Eigen::PartialPivLU<Mat<mpfr_complex>>(numTotalFunctions_);
90 current_precision_ = new_precision;
94 unsigned precision()
const
96 return current_precision_;
109 std::get< Mat<dbl> >(J_temp_).resize(numTotalFunctions_, numVariables_);
110 std::get< Mat<mpfr_complex> >(J_temp_).resize(numTotalFunctions_, numVariables_);
111 std::get< Vec<dbl> >(f_temp_).resize(numTotalFunctions_);
112 std::get< Vec<mpfr_complex> >(f_temp_).resize(numTotalFunctions_);
113 std::get< Vec<dbl> >(step_temp_).resize(numTotalFunctions_);
114 std::get< Vec<mpfr_complex> >(step_temp_).resize(numTotalFunctions_);
140 template <
typename ComplexType>
141 SuccessCode
Correct(Vec<ComplexType> & next_space,
143 Vec<ComplexType>
const& current_space,
144 ComplexType
const& current_time,
145 NumErrorT
const& tracking_tolerance,
146 unsigned min_num_newton_iterations,
147 unsigned max_num_newton_iterations)
149 #ifndef BERTINI_DISABLE_ASSERTS
150 assert(max_num_newton_iterations >= min_num_newton_iterations &&
"max number newton iterations must be at least the min.");
153 Vec<ComplexType>& step_ref = std::get< Vec<ComplexType> >(step_temp_);
155 next_space = current_space;
156 for (
unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
159 auto success_code = EvalIterationStep(step_ref, S, next_space, current_time);
160 if(success_code != SuccessCode::Success)
163 next_space += step_ref;
165 if ( (step_ref.template lpNorm<Eigen::Infinity>() < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
166 return SuccessCode::Success;
169 return SuccessCode::FailedToConverge;
197 template <
typename ComplexType>
198 SuccessCode
Correct(Vec<ComplexType> & next_space,
200 Vec<ComplexType>
const& current_space,
201 ComplexType
const& current_time,
202 NumErrorT
const& tracking_tolerance,
203 unsigned min_num_newton_iterations,
204 unsigned max_num_newton_iterations,
207 #ifndef BERTINI_DISABLE_ASSERTS
208 assert(max_num_newton_iterations >= min_num_newton_iterations &&
"max number newton iterations must be at least the min.");
211 Vec<ComplexType>& step_ref = std::get< Vec<ComplexType> >(step_temp_);
213 next_space = current_space;
214 for (
unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
217 auto success_code = EvalIterationStep(step_ref, S, next_space, current_time);
218 if(success_code != SuccessCode::Success)
221 next_space += step_ref;
223 Mat<ComplexType>& J_temp_ref = std::get< Mat<ComplexType> >(J_temp_);
224 Eigen::PartialPivLU< Mat<ComplexType> >& LU_ref = std::get< Eigen::PartialPivLU< Mat<ComplexType> > >(LU_);
226 if ( (step_ref.template lpNorm<Eigen::Infinity>() < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
227 return SuccessCode::Success;
231 if (!
amp::CriterionB<ComplexType>(NumErrorT(J_temp_ref.norm()), norm_J_inverse, max_num_newton_iterations - ii, tracking_tolerance, NumErrorT(step_ref.template lpNorm<Eigen::Infinity>()), AMP_config))
232 return SuccessCode::HigherPrecisionNecessary;
235 return SuccessCode::HigherPrecisionNecessary;
238 return SuccessCode::FailedToConverge;
268 template <
typename ComplexType>
269 SuccessCode
Correct(Vec<ComplexType> & next_space,
270 NumErrorT & norm_delta_z,
272 NumErrorT & norm_J_inverse,
273 NumErrorT & condition_number_estimate,
275 Vec<ComplexType>
const& current_space,
276 ComplexType
const& current_time,
277 NumErrorT
const& tracking_tolerance,
278 unsigned min_num_newton_iterations,
279 unsigned max_num_newton_iterations,
282 #ifndef BERTINI_DISABLE_ASSERTS
283 assert(max_num_newton_iterations >= min_num_newton_iterations &&
"max number newton iterations must be at least the min.");
286 Vec<ComplexType>& step_ref = std::get< Vec<ComplexType> >(step_temp_);
288 next_space = current_space;
289 for (
unsigned ii = 0; ii < max_num_newton_iterations; ++ii)
292 auto success_code = EvalIterationStep(step_ref, S, next_space, current_time);
293 if(success_code != SuccessCode::Success)
296 next_space += step_ref;
298 Mat<ComplexType>& J_temp_ref = std::get< Mat<ComplexType> >(J_temp_);
299 Eigen::PartialPivLU< Mat<ComplexType> >& LU_ref = std::get< Eigen::PartialPivLU< Mat<ComplexType> > >(LU_);
302 norm_delta_z = NumErrorT(step_ref.template lpNorm<Eigen::Infinity>());
303 norm_J = NumErrorT(J_temp_ref.norm());
305 condition_number_estimate = NumErrorT(norm_J*norm_J_inverse);
307 if ( (norm_delta_z < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) )
308 return SuccessCode::Success;
310 if (!
amp::CriterionB<ComplexType>(norm_J, norm_J_inverse, max_num_newton_iterations - ii, tracking_tolerance, norm_delta_z, AMP_config))
311 return SuccessCode::HigherPrecisionNecessary;
314 return SuccessCode::HigherPrecisionNecessary;
317 return SuccessCode::FailedToConverge;
340 template<
typename ComplexType,
typename Derived>
341 SuccessCode EvalIterationStep(Vec<ComplexType> & newton_step,
343 const Eigen::MatrixBase<Derived>& current_space,
const ComplexType& current_time)
345 Vec<ComplexType>& f_temp_ref = std::get< Vec<ComplexType> >(f_temp_);
346 Mat<ComplexType>& J_temp_ref = std::get< Mat<ComplexType> >(J_temp_);
348 Eigen::PartialPivLU< Mat<ComplexType> >& LU_ref = std::get< Eigen::PartialPivLU< Mat<ComplexType> > >(LU_);
350 S.SetAndReset<ComplexType>(current_space, current_time);
353 LU_ref = J_temp_ref.lu();
356 return SuccessCode::MatrixSolveFailure;
358 newton_step = LU_ref.solve(-f_temp_ref);
360 return SuccessCode::Success;
372 unsigned numTotalFunctions_;
373 unsigned numVariables_;
375 std::tuple< Vec<dbl>, Vec<mpfr_complex> > f_temp_;
376 std::tuple< Vec<dbl>, Vec<mpfr_complex> > step_temp_;
377 std::tuple< Mat<dbl>, Mat<mpfr_complex> > J_temp_;
379 std::tuple< Eigen::PartialPivLU<Mat<dbl>>, Eigen::PartialPivLU<Mat<mpfr_complex>> > LU_;
381 unsigned current_precision_;
383 NewtonConfig newton_config_;
Provides the Adaptive Multiple Precision criteria functions.
bool CriterionC(double const &norm_J_inverse, const Eigen::MatrixBase< Derived > &z, double tracking_tolerance, AdaptiveMultiplePrecisionConfig const &_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 &_config)
Check AMP Criterion B.
Definition amp_criteria.hpp:132
The fundamental polynomial system class for Bertini2.
Definition system/system.hpp:99
void EvalInPlace(Vec< T > &function_values) const
Evaluate the system using the previously set variable (and time) values, in place.
Definition system/system.hpp:272
void JacobianInPlace(Mat< T > &J) const
Evaluate the Jacobian matrix of the system, using the previous space and time values,...
Definition system/system.hpp:470
size_t NumVariables() const
size_t NumTotalFunctions() const
void Settings(const NewtonConfig &newton_settings)
Sets the Newton configuration settings.
Definition newton_corrector.hpp:67
SuccessCode Correct(Vec< ComplexType > &next_space, System const &S, Vec< ComplexType > const ¤t_space, ComplexType const ¤t_time, NumErrorT const &tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations, AdaptiveMultiplePrecisionConfig const &_config)
Run Newton's method in multiple precision.
Definition newton_corrector.hpp:198
SuccessCode Correct(Vec< ComplexType > &next_space, System const &S, Vec< ComplexType > const ¤t_space, ComplexType const ¤t_time, NumErrorT const &tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations)
Run Newton's method in fixed precision.
Definition newton_corrector.hpp:141
SuccessCode Correct(Vec< ComplexType > &next_space, NumErrorT &norm_delta_z, NumErrorT &norm_J, NumErrorT &norm_J_inverse, NumErrorT &condition_number_estimate, System const &S, Vec< ComplexType > const ¤t_space, ComplexType const ¤t_time, NumErrorT const &tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations, AdaptiveMultiplePrecisionConfig const &_config)
Run Newton's method in multiple precision.
Definition newton_corrector.hpp:269
void ChangeSystem(const System &S)
Change the system(number of total functions) that the predictor uses.
Definition newton_corrector.hpp:105
void ChangePrecision(unsigned new_precision)
Definition newton_corrector.hpp:82
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
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
Definition trackers/config.hpp:154
Provides the bertini::System class.
Configs and settings for tracking.