def check_for_interior_convergence_and_update( x_candidate, hessian_info, lambdas, stopping_criteria, converged, ): """Check for interior convergence, update candidate vector and lambdas.""" if lambdas.candidate == 0: x_candidate = np.zeros_like(x_candidate) converged = True s_min, z_min = estimate_smallest_singular_value( hessian_info.upper_triangular) step_len = 2 if step_len**2 * s_min**2 <= stopping_criteria["k_hard"] * lambdas.current: x_candidate = step_len * z_min converged = True lambda_lower_bound = max(lambdas.lower_bound, lambdas.upper_bound - s_min**2) lambda_new_candidate = _get_new_lambda_candidate( lower_bound=lambda_lower_bound, upper_bound=lambdas.candidate) lambdas_new = lambdas._replace( candidate=lambda_new_candidate, lower_bound=lambda_lower_bound, upper_bound=lambdas.candidate, ) return x_candidate, lambdas_new, converged
def _update_candidate_and_parameters_when_candidate_within_trustregion( x_candidate, main_model, hessian_info, lambdas, newton_step, stopping_criteria, converged, ): """Update candidate vector, hessian, and lambdas when x outside trust-region.""" n = len(x_candidate) s_min, z_min = estimate_smallest_singular_value( hessian_info.upper_triangular) step_len = _compute_smallest_step_len_for_candidate_vector( x_candidate, z_min) quadratic_term = x_candidate.T @ hessian_info.hessian_plus_lambda @ x_candidate relative_error = (step_len**2 * s_min**2) / (quadratic_term + lambdas.candidate) if relative_error <= stopping_criteria["k_hard"]: x_candidate = x_candidate + step_len * z_min converged = True lambda_new_lower_bound = max(lambdas.lower_bound, lambdas.candidate - s_min**2) hessian_plus_lambda = main_model.square_terms + newton_step * np.eye(n) _, factorization_unsuccessful = compute_cholesky_factorization( hessian_plus_lambda, lower=False, overwrite_a=False, clean=True, ) if factorization_unsuccessful == 0: hessian_already_factorized = True lambda_new_candidate = newton_step else: hessian_already_factorized = hessian_info.already_factorized lambda_new_lower_bound = max(lambda_new_lower_bound, newton_step) lambda_new_candidate = _get_new_lambda_candidate( lower_bound=lambda_new_lower_bound, upper_bound=lambdas.candidate) hessian_info_new = hessian_info._replace( hessian_plus_lambda=hessian_plus_lambda, already_factorized=hessian_already_factorized, ) lambdas_new = lambdas._replace( candidate=lambda_new_candidate, lower_bound=lambda_new_lower_bound, upper_bound=lambdas.candidate, ) return x_candidate, hessian_info_new, lambdas_new, converged
def test_for_ill_condiotioned_matrix(self): # Ill-conditioned triangular matrix C = np.array([[1, 2, 3, 4], [0, 0.05, 60, 7], [0, 0, 0.8, 9], [0, 0, 0, 10]]) # Get svd decomposition U, s, Vt = svd(C) # Get smallest singular value and correspondent right singular vector. smin_svd = s[-1] zmin_svd = Vt[-1, :] # Estimate smallest singular value smin, zmin = estimate_smallest_singular_value(C) # Check the estimation assert_array_almost_equal(smin, smin_svd, decimal=8) assert_array_almost_equal(abs(zmin), abs(zmin_svd), decimal=8)