QPALM main
Proximal Augmented Lagrangian method for Quadratic Programs
Loading...
Searching...
No Matches
newton.c
Go to the documentation of this file.
1/**
2 * @file newton.c
3 * @author Ben Hermans
4 * @brief Functions to calculate the semismooth Newton direction.
5 * @details The functions in this file concern the calculation of the semismooth Newton direction.
6 * Factorizing, updating the factorization and solving the linear system are performed by functions in
7 * solver_interface.c.
8 */
9# ifdef __cplusplus
10extern "C" {
11# endif // ifdef __cplusplus
12
13#include <qpalm/newton.h>
14#include <qpalm/lin_alg.h>
15#include <stdio.h>
16
18
21
23 {
24 #ifdef QPALM_USE_LADEL
25 // NB FACTORIZE_KKT only defined with LADEL for now
26 // TODO (optionally) extract the ladel functions and bury them, use cholmod also for kkt
27 ladel_diag d;
28 d.diag_elem = 1.0/work->gamma;
29 if (work->settings->proximal) d.diag_size = work->data->n;
30 else d.diag_size = 0;
31
32 if (work->solver->first_factorization)
33 {
34 qpalm_form_kkt(work);
35 work->solver->LD = ladel_factor_free(work->solver->LD);
36 ladel_factorize_advanced_with_diag(work->solver->kkt, d, work->solver->sym, work->settings->ordering, &work->solver->LD, work->solver->kkt_full, c);
38 }
39 else if (work->solver->reset_newton ||
40 (work->solver->nb_enter + work->solver->nb_leave) >
42 {
43 qpalm_reform_kkt(work);
44 ladel_factorize_with_prior_basis_with_diag(work->solver->kkt, d, work->solver->sym, work->solver->LD, c);
45 }
46 else
47 {
48 if(work->solver->nb_enter)
50
51 if (work->solver->nb_leave)
53 }
54
55 kkt_solve(work, c);
56
57 // /* Iterative refinement: compute r = b - Ax = -dphi - kkt*sol and add sol += A\r */
58 mat_vec(work->solver->kkt, work->solver->sol_kkt, work->solver->rhs_kkt, c);
59 if(work->settings->proximal) vec_mult_add_scaled(work->solver->rhs_kkt, work->solver->sol_kkt, 1, 1.0/work->gamma, work->data->n);
60 vec_self_mult_scalar(work->solver->rhs_kkt, -1, work->data->m + work->data->n);
61 c_float ref_norm = c_max(vec_norm_inf(work->solver->rhs_kkt, work->data->n + work->data->m), vec_norm_inf(work->dphi, work->data->n));
62 vec_mult_add_scaled(work->solver->rhs_kkt, work->dphi, 1, -1, work->data->n);
63
64 c_float first_res = vec_norm_inf(work->solver->rhs_kkt, work->data->n + work->data->m);
65 c_float res = first_res;
66 c_int k = 0;
67
68 // if(res > RELATIVE_REFINEMENT_TOLERANCE*ref_norm) ladel_print("ref_norm: %e\n", ref_norm);
69
70 while(k < MAX_REFINEMENT_ITERATIONS && res > c_max(RELATIVE_REFINEMENT_TOLERANCE*ref_norm, ABSOLUTE_REFINEMENT_TOLERANCE))
71 {
72 k++;
73 // ladel_print("Refinement because relative res = %e (ref_norm = %e)\n", vec_norm_inf(work->solver->rhs_kkt, work->data->n + work->data->m)/ref_norm, ref_norm);
74 prea_vec_copy(work->solver->sol_kkt, work->temp_n, work->data->n);
75 prea_vec_copy(work->solver->sol_kkt + work->data->n, work->temp_m, work->data->m);
76 ladel_dense_solve(work->solver->LD, work->solver->rhs_kkt, work->solver->sol_kkt, c);
77 vec_add_scaled(work->solver->sol_kkt, work->d, work->d, 1, work->data->n);
78
79 vec_mult_add_scaled(work->solver->sol_kkt, work->temp_n, 1, 1, work->data->n);
80 vec_mult_add_scaled(work->solver->sol_kkt + work->data->n, work->temp_m, 1, 1, work->data->m);
81 mat_vec(work->solver->kkt, work->solver->sol_kkt, work->solver->rhs_kkt, c);
82 if(work->settings->proximal) vec_mult_add_scaled(work->solver->rhs_kkt, work->solver->sol_kkt, 1, 1.0/work->gamma, work->data->n);
83 vec_self_mult_scalar(work->solver->rhs_kkt, -1, work->data->m + work->data->n);
84 vec_mult_add_scaled(work->solver->rhs_kkt, work->dphi, 1, -1, work->data->n);
85 res = vec_norm_inf(work->solver->rhs_kkt, work->data->n + work->data->m);
86 // if(res > RELATIVE_REFINEMENT_TOLERANCE*ref_norm)
87 // ladel_print("K = %d, Res = %e (first res = %e)\n", k, res/ref_norm, first_res/ref_norm);
88 // else
89 // ladel_print("FINAL K = %d, Res = %e (first res = %e)\n", k, res/ref_norm, first_res/ref_norm);
90 }
91
92 // if (k==MAX_REFINEMENT_ITERATIONS) ladel_print("ITREF FAILED, final res = %e (first res = %e)\n", res/ref_norm, first_res/ref_norm);
93
94
95 #endif
96 } else if (work->solver->factorization_method == FACTORIZE_SCHUR)
97 {
98 if ((work->solver->reset_newton && work->solver->nb_active_constraints) ||
99 (work->solver->nb_enter + work->solver->nb_leave) >
100 c_min(work->settings->max_rank_update_fraction*(work->data->n+work->data->m), work->settings->max_rank_update)) {
101 ldlcholQAtsigmaA(work, c);
102 } else if (work->solver->nb_active_constraints) {
103 if(work->solver->nb_enter) {
105 }
106 if(work->solver->nb_leave) {
108 }
109 } else {
110 ldlchol(work->data->Q, work, c);
111 }
112 ldlsolveLD_neg_dphi(work, c);
113 }
114
115 //Store old active set
117
118 work->solver->reset_newton = FALSE;
119
120}
121
123 work->solver->nb_active_constraints = 0;
124 for (size_t i = 0; i < work->data->m; i++) {
125 if ((work->Axys[i] <= work->data->bmin[i]) || ((work->Axys[i] >= work->data->bmax[i]))){
126 work->solver->active_constraints[i] = TRUE;
128 } else {
129 work->solver->active_constraints[i] = FALSE;
130 }
131 }
132}
133
135 int nb_enter = 0;
136 int nb_leave = 0;
137 for (size_t i = 0; i < work->data->m; i++) {
138 if (work->solver->active_constraints[i] && !work->solver->active_constraints_old[i]) {
139 work->solver->enter[nb_enter] = (c_int)i;
140 nb_enter++;
141 }
142 if (!work->solver->active_constraints[i] && work->solver->active_constraints_old[i]) {
143 work->solver->leave[nb_leave] = (c_int)i;
144 nb_leave++;
145 }
146 }
147 work->solver->nb_enter = nb_enter;
148 work->solver->nb_leave = nb_leave;
149}
150
151
152
153# ifdef __cplusplus
154}
155# endif // ifdef __cplusplus
#define RELATIVE_REFINEMENT_TOLERANCE
relative tolerance on the residual for linear systems solving
Definition constants.h:102
#define FACTORIZE_SCHUR
factorize the Schur complement
Definition constants.h:108
#define TRUE
Definition constants.h:18
#define FALSE
Definition constants.h:19
#define FACTORIZE_KKT
factorize the kkt system
Definition constants.h:107
#define ABSOLUTE_REFINEMENT_TOLERANCE
absolute tolerance on the residual for linear systems solving
Definition constants.h:103
ladel_int c_int
type for integer numbers
Definition global_opts.h:42
ladel_double c_float
type for floating point numbers
Definition global_opts.h:41
#define c_max(a, b)
maximum of two values
Definition global_opts.h:96
#define c_min(a, b)
minimum of two values
void vec_add_scaled(const c_float *a, const c_float *b, c_float *c, c_float sc, size_t n)
Scaled addition of one vector to another vector, .
Definition lin_alg.c:110
void vec_mult_add_scaled(c_float *a, const c_float *b, c_float sc1, c_float sc2, size_t n)
Scaled addition of one vector to another vector, both being scaled, .
Definition lin_alg.c:118
void vec_self_mult_scalar(c_float *a, c_float sc, size_t n)
Mulitply vector with a constant scale factor.
Definition lin_alg.c:56
void prea_vec_copy(const c_float *a, c_float *b, size_t n)
Copy vector a into preallocated vector b.
Definition lin_alg.c:24
c_float vec_norm_inf(const c_float *a, size_t n)
Infinity norm of a vector, .
Definition lin_alg.c:126
void prea_int_vec_copy(const c_int *a, c_int *b, size_t n)
Copy integer vector a into preallocated vector b.
Definition lin_alg.c:32
Linear algebra with vectors.
void set_entering_leaving_constraints(QPALMWorkspace *work)
Determines the entering and leaving constraints and stores them in work->solver->enter and work->solv...
Definition newton.c:134
void set_active_constraints(QPALMWorkspace *work)
Computes the set of active constraints and stores it in work->solver->active_constraints.
Definition newton.c:122
void newton_set_direction(QPALMWorkspace *work, solver_common *c)
Sets work->d to the direction calculated by the semismooth Newton method.
Definition newton.c:17
Functions to calculate the semismooth Newton direction.
void ldlsolveLD_neg_dphi(QPALMWorkspace *work, solver_common *c)
Solve the linear system .
void kkt_update_leaving_constraints(QPALMWorkspace *work, solver_common *c)
Perform a factorization update for the leaving constraints.
void qpalm_form_kkt(QPALMWorkspace *work)
Form the KKT system .
void mat_vec(solver_sparse *A, solver_dense *x, solver_dense *y, solver_common *c)
Matrix-vector multiplication.
void ldldowndate_leaving_constraints(QPALMWorkspace *work, solver_common *c)
Downdate the factorization given a set of leaving constraints.
void kkt_update_entering_constraints(QPALMWorkspace *work, solver_common *c)
Perform a factorization update for the entering constraints.
void ldlcholQAtsigmaA(QPALMWorkspace *work, solver_common *c)
Calculate factorization of , with and the set of active constraints.
void ldlchol(solver_sparse *M, QPALMWorkspace *work, solver_common *c)
Calculate factorization of a matrix .
void kkt_solve(QPALMWorkspace *work, solver_common *c)
Solve the KKT system .
void qpalm_reform_kkt(QPALMWorkspace *work)
Reform the KKT system (i.e.
void ldlupdate_entering_constraints(QPALMWorkspace *work, solver_common *c)
Update the factorization given a set of entering constraints.
size_t m
number of constraints m
Definition types.h:111
c_float * bmin
dense array for lower bounds (size m)
Definition types.h:116
size_t n
number of variables n
Definition types.h:110
c_float * bmax
dense array for upper bounds (size m)
Definition types.h:117
solver_sparse * Q
sparse quadratic part of the cost Q (size n x n)
Definition types.h:112
c_int proximal
boolean, use proximal method of multipliers or not
Definition types.h:138
c_int max_rank_update
maximum rank for the sparse factorization update
Definition types.h:153
c_float max_rank_update_fraction
maximum rank (relative to n+m) for the factorization update
Definition types.h:154
c_int ordering
ordering method for factorization
Definition types.h:151
c_int * active_constraints
index set of active constraints
Definition types.h:185
c_int reset_newton
boolean, after sigma is updated perform a new factorization
Definition types.h:184
c_int * leave
index set of leaving constraints
Definition types.h:190
solver_dense * rhs_kkt
[-dphi; zeros(m,1)]
Definition types.h:176
solver_factor * LD
LD factor (part of LDL' factorization)
Definition types.h:169
c_int factorization_method
factorize KKT or Schur complement
Definition types.h:163
c_int * enter
index set of entering constraints
Definition types.h:188
c_int * active_constraints_old
index set of active constraints in the previous iteration
Definition types.h:186
c_int first_factorization
boolean, indicate we have not factorized previously
Definition types.h:183
solver_dense * sol_kkt
sol_kkt = kkt \ rhs_kkt
Definition types.h:177
c_int nb_leave
number of leaving constraints
Definition types.h:191
c_int nb_active_constraints
number of active constraints
Definition types.h:187
solver_symbolics * sym
symbolics for kkt (only used in LADEL)
Definition types.h:170
solver_sparse * kkt_full
KKT matrix if all constraints would be active.
Definition types.h:165
solver_sparse * kkt
KKT matrix.
Definition types.h:164
c_int nb_enter
number of entering constraints
Definition types.h:189
QPALM Workspace.
Definition types.h:204
c_float * temp_m
placeholder for vector of size m
Definition types.h:224
c_float * Axys
Ax + y./sigma.
Definition types.h:232
QPALMSettings * settings
problem settings
Definition types.h:312
c_float gamma
proximal penalty factor
Definition types.h:230
c_float * dphi
gradient of the Lagrangian
Definition types.h:241
QPALMSolver * solver
linsys variables
Definition types.h:311
QPALMData * data
problem data to work on (possibly scaled)
Definition types.h:205
c_float * temp_n
placeholder for vector of size n
Definition types.h:225
c_float * d
primal update step
Definition types.h:244
ladel_work solver_common
Definition types.h:25