Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
    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)
    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)