SuccessCode NewtonLoop(Vec<ComplexType> & next_space, System const& S, Vec<ComplexType> const& current_space, // pass by value to get a copy of it ComplexType const& current_time, RealType const& tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations) { #ifndef BERTINI_DISABLE_ASSERTS assert(max_num_newton_iterations >= min_num_newton_iterations && "max number newton iterations must be at least the min."); #endif next_space = current_space; for (unsigned ii = 0; ii < max_num_newton_iterations; ++ii) { auto f = S.Eval(next_space, current_time); auto J = S.Jacobian(next_space, current_time); auto LU = J.lu(); if (LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=MatrixSuccessCode::Success) return SuccessCode::MatrixSolveFailure; auto delta_z = LU.solve(-f); next_space += delta_z; if ( (delta_z.norm() < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) ) return SuccessCode::Success; } return SuccessCode::FailedToConverge; }
SuccessCode NewtonLoop(Vec<ComplexType> & next_space, RealType & norm_delta_z, RealType & norm_J, RealType & norm_J_inverse, RealType & condition_number_estimate, System const& S, Vec<ComplexType> const& current_space, // pass by value to get a copy of it ComplexType const& current_time, RealType const& tracking_tolerance, unsigned min_num_newton_iterations, unsigned max_num_newton_iterations, config::AdaptiveMultiplePrecisionConfig const& AMP_config) { #ifndef BERTINI_DISABLE_ASSERTS assert(max_num_newton_iterations >= min_num_newton_iterations && "max number newton iterations must be at least the min."); #endif next_space = current_space; for (unsigned ii = 0; ii < max_num_newton_iterations; ++ii) { //TODO: wrap these into a single line. auto f = S.Eval(next_space, current_time); auto J = S.Jacobian(next_space, current_time); auto LU = J.lu(); if (LUPartialPivotDecompositionSuccessful(LU.matrixLU())!=MatrixSuccessCode::Success) return SuccessCode::MatrixSolveFailure; auto delta_z = LU.solve(-f); next_space += delta_z; norm_delta_z = delta_z.norm(); norm_J = J.norm(); norm_J_inverse = LU.solve(RandomOfUnits<ComplexType>(S.NumVariables())).norm(); condition_number_estimate = norm_J*norm_J_inverse; if ( (norm_delta_z < tracking_tolerance) && (ii >= (min_num_newton_iterations-1)) ) return SuccessCode::Success; if (!amp::CriterionB(norm_J, norm_J_inverse, max_num_newton_iterations - ii, tracking_tolerance, norm_delta_z, AMP_config)) return SuccessCode::HigherPrecisionNecessary; if (!amp::CriterionC(norm_J_inverse, next_space, tracking_tolerance, AMP_config)) return SuccessCode::HigherPrecisionNecessary; } return SuccessCode::FailedToConverge; }