QPALM 1.2.5
Proximal Augmented Lagrangian method for Quadratic Programs
Loading...
Searching...
No Matches
qpalm.c
Go to the documentation of this file.
1/**
2 * @file qpalm.c
3 * @author Ben Hermans
4 * @brief QPALM main solver API.
5 * @details This file contains the main functions that can be called by the user.
6 * The user can load the default settings, setup the workspace with data and settings,
7 * run the solver, and cleanup the workspace afterwards.
8 */
9# ifdef __cplusplus
10extern "C" {
11# endif // ifdef __cplusplus
12
13#include <qpalm.h>
14#include <qpalm/global_opts.h>
15#include <qpalm/constants.h>
16#include <qpalm/validate.h>
17#include <qpalm/lin_alg.h>
18#include <qpalm/util.h>
19#include <qpalm/scaling.h>
20#include <qpalm/linesearch.h>
21#include <qpalm/termination.h>
23#include <qpalm/newton.h>
24#include <qpalm/nonconvex.h>
25#include <qpalm/iteration.h>
26
27#include <ladel.h>
28
29/**********************
30* Main API Functions *
31**********************/
32
34{
35 settings->max_iter = MAX_ITER; /* maximum iterations */
36 settings->inner_max_iter = INNER_MAX_ITER; /* maximum iterations per subproblem */
37 settings->eps_abs = (c_float)EPS_ABS; /* absolute convergence tolerance */
38 settings->eps_rel = (c_float)EPS_REL; /* relative convergence tolerance */
39 settings->eps_abs_in = (c_float)EPS_ABS_IN; /* intermediate absolute convergence tolerance */
40 settings->eps_rel_in = (c_float)EPS_REL_IN; /* intermediate relative convergence tolerance */
41 settings->rho = (c_float)RHO; /* tolerance scaling factor */
42 settings->eps_prim_inf = (c_float)EPS_PRIM_INF; /* primal infeasibility tolerance */
43 settings->eps_dual_inf = (c_float)EPS_DUAL_INF; /* dual infeasibility tolerance */
44 settings->theta = (c_float)THETA; /* penalty update criterion parameter */
45 settings->delta = (c_float)DELTA; /* penalty update factor */
46 settings->sigma_max = (c_float)SIGMA_MAX; /* penalty parameter cap */
47 settings->sigma_init = (c_float)SIGMA_INIT; /* initial penalty parameter (guideline) */
48 settings->proximal = PROXIMAL; /* boolean, proximal method of multipliers*/
49 settings->gamma_init = (c_float)GAMMA_INIT; /* proximal penalty parameter */
50 settings->gamma_upd = (c_float)GAMMA_UPD; /* proximal penalty update factor*/
51 settings->gamma_max = (c_float)GAMMA_MAX; /* proximal penalty parameter cap*/
52 settings->scaling = SCALING; /* boolean, scaling */
53 settings->nonconvex = NONCONVEX; /* boolean, nonconvex */
54 settings->warm_start = WARM_START; /* boolean, warm start solver */
55 settings->verbose = VERBOSE; /* boolean, write out progress */
56 settings->print_iter = PRINT_ITER; /* frequency of printing */
57 settings->reset_newton_iter = RESET_NEWTON_ITER; /* frequency of performing a full Cholesky factorization */
58 settings->enable_dual_termination = ENABLE_DUAL_TERMINATION; /* allow for dual termination (useful in branch and bound) */
59 settings->dual_objective_limit = (c_float)DUAL_OBJECTIVE_LIMIT; /* termination value for the dual objective (useful in branch and bound) */
60 settings->time_limit = (c_float)TIME_LIMIT; /* time limit */
61 settings->ordering = ORDERING; /* ordering */
62 settings->factorization_method = FACTORIZATION_METHOD; /* factorization method (kkt or schur) */
63 settings->max_rank_update = MAX_RANK_UPDATE; /* maximum rank of the update */
64 settings->max_rank_update_fraction = (c_float)MAX_RANK_UPDATE_FRACTION; /* maximum rank (relative to n+m) of the update */
65}
66
67
68QPALMWorkspace* qpalm_setup(const QPALMData *data, const QPALMSettings *settings)
69{
70 QPALMWorkspace *work; // Workspace
71
72 // Validate data
73 if (!validate_data(data))
74 {
75 # ifdef QPALM_PRINTING
76 qpalm_eprint("Data validation returned failure");
77 # endif /* ifdef QPALM_PRINTING */
78 return QPALM_NULL;
79 }
80
81 // Validate settings
82 if (!validate_settings(settings))
83 {
84 # ifdef QPALM_PRINTING
85 qpalm_eprint("Settings validation returned failure");
86 # endif /* ifdef QPALM_PRINTING */
87 return QPALM_NULL;
88 }
89
90 // Allocate empty workspace
91 work = qpalm_calloc(1, sizeof(QPALMWorkspace));
92
93 if (!work)
94 {
95 # ifdef QPALM_PRINTING
96 qpalm_eprint("allocating work failure");
97 # endif /* ifdef QPALM_PRINTING */
98 return QPALM_NULL;
99 }
100
101 // Start and allocate directly timer
102 # ifdef QPALM_TIMING
103 work->timer = qpalm_malloc(sizeof(QPALMTimer));
104 qpalm_tic(work->timer);
105 # endif /* ifdef QPALM_TIMING */
106
107 // Copy settings
108 work->settings = copy_settings(settings);
109 work->sqrt_delta = c_sqrt(work->settings->delta);
110 work->gamma = work->settings->gamma_init;
111
112 size_t n = data->n;
113 size_t m = data->m;
114
115 //Initialize the solver for the linear system
116 work->solver = qpalm_calloc(1, sizeof(QPALMSolver));
117 solver_common common, *c;
118 c = &common;
119
120 // Copy problem data into workspace
121 work->data = qpalm_calloc(1, sizeof(QPALMData));
122 work->data->n = data->n;
123 work->data->m = data->m;
124 work->data->bmin = vec_copy(data->bmin, m);
125 work->data->bmax = vec_copy(data->bmax, m);
126 work->data->q = vec_copy(data->q, n);
127 work->data->c = data->c;
128
129 work->data->A = ladel_sparse_allocate_and_copy(data->A);
130 work->data->Q = ladel_sparse_allocate_and_copy(data->Q);
131 ladel_to_upper_diag(work->data->Q);
132
133 // Allocate internal solver variables
134 work->x = qpalm_calloc(n, sizeof(c_float));
135 work->y = qpalm_calloc(m, sizeof(c_float));
136 work->Ax = qpalm_calloc(m, sizeof(c_float));
137 work->Qx = qpalm_calloc(n, sizeof(c_float));
138 work->x_prev = qpalm_calloc(n, sizeof(c_float));
139 work->Aty = qpalm_calloc(n, sizeof(c_float));
140
141 work->x0 = qpalm_calloc(n, sizeof(c_float));
142
143 work->initialized = FALSE;
144
145 // Workspace variables
146 work->temp_m = qpalm_calloc(m, sizeof(c_float));
147 work->temp_n = qpalm_calloc(n, sizeof(c_float));
148 work->sigma = qpalm_calloc(m, sizeof(c_float));
149 work->sigma_inv = qpalm_calloc(m, sizeof(c_float));
150 work->nb_sigma_changed = 0;
151
152 work->z = qpalm_calloc(m, sizeof(c_float));
153 work->Axys = qpalm_calloc(m, sizeof(c_float));
154 work->pri_res = qpalm_calloc(m, sizeof(c_float));
155 work->pri_res_in = qpalm_calloc(m, sizeof(c_float));
156 work->df = qpalm_calloc(n, sizeof(c_float));
157
158 work->xx0 = qpalm_calloc(n, sizeof(c_float));
159 work->dphi = qpalm_calloc(n, sizeof(c_float));
160 work->dphi_prev = qpalm_calloc(n, sizeof(c_float));
161
162 // Linesearch variables
163 work->sqrt_sigma = qpalm_calloc(m, sizeof(c_float));
164 work->delta = qpalm_calloc(m*2, sizeof(c_float));
165 work->alpha = qpalm_calloc(m*2, sizeof(c_float));
166 work->delta2 = qpalm_calloc(m*2, sizeof(c_float));
167 work->delta_alpha = qpalm_calloc(m*2, sizeof(c_float));
168 work->temp_2m = qpalm_calloc(m*2, sizeof(c_float));
169 work->s = qpalm_calloc(m*2, sizeof(array_element));
170 work->index_L = qpalm_calloc(m*2, sizeof(c_int));
171 work->index_P = qpalm_calloc(m*2, sizeof(c_int));
172 work->index_J = qpalm_calloc(m*2, sizeof(c_int));
173
174 // Primal infeasibility variables
175 work->delta_y = qpalm_calloc(m, sizeof(c_float));
176 work->Atdelta_y = qpalm_calloc(n, sizeof(c_float));
177
178 // Dual infeasibility variables
179 work->delta_x = qpalm_calloc(n, sizeof(c_float));
180 work->Qdelta_x = qpalm_calloc(n, sizeof(c_float));
181 work->Adelta_x = qpalm_calloc(m, sizeof(c_float));
182
184 // c = &common;
185
186 // Allocate scaling structure
187 work->scaling = qpalm_malloc(sizeof(QPALMScaling));
188 work->scaling->D = qpalm_calloc(n, sizeof(c_float));
189 work->scaling->Dinv = qpalm_calloc(n, sizeof(c_float));
190 work->scaling->E = qpalm_calloc(m, sizeof(c_float));
191 work->scaling->Einv = qpalm_calloc(m, sizeof(c_float));
192
193 work->solver->E_temp = qpalm_calloc(m, sizeof(c_float));
194 work->E_temp = work->solver->E_temp;
195 work->solver->D_temp = qpalm_calloc(n, sizeof(c_float));
196 work->D_temp = work->solver->D_temp;
197
198 // Solver variables
199 work->solver->active_constraints = qpalm_calloc(m, sizeof(c_int));
200 work->solver->active_constraints_old = qpalm_calloc(m, sizeof(c_int));
202 work->solver->reset_newton = TRUE;
203 work->solver->enter = qpalm_calloc(m, sizeof(c_int));
204 work->solver->leave = qpalm_calloc(m, sizeof(c_int));
205
207 {
208 work->solver->rhs_kkt = qpalm_malloc((n+m)*sizeof(c_float));
209 work->solver->sol_kkt = qpalm_malloc((n+m)*sizeof(c_float));
210 c_int kkt_nzmax = work->data->Q->nzmax + work->data->A->nzmax + m;
211 work->solver->kkt_full = ladel_sparse_alloc(n+m, n+m, kkt_nzmax, UPPER, TRUE, FALSE);
212 work->solver->kkt = ladel_sparse_alloc(n+m, n+m, kkt_nzmax, UPPER, TRUE, TRUE);
213 work->solver->first_row_A = qpalm_malloc(m*sizeof(c_int));
214 work->solver->first_elem_A = qpalm_malloc(m*sizeof(c_float));
215 work->solver->sym = ladel_symbolics_alloc(m+n);
216 }
218 {
219 work->solver->sym = ladel_symbolics_alloc(n);
220 }
221
222 work->solver->neg_dphi = qpalm_calloc(n, sizeof(c_float));
223 work->neg_dphi = work->solver->neg_dphi;
224 work->solver->d = qpalm_calloc(n, sizeof(c_float));
225 work->d = work->solver->d;
226 work->solver->Qd = qpalm_calloc(n, sizeof(c_float));
227 work->Qd = work->solver->Qd;
228 work->solver->Ad = qpalm_calloc(m, sizeof(c_float));
229 work->Ad = work->solver->Ad;
230 work->solver->yh = qpalm_calloc(m, sizeof(c_float));
231 work->yh = work->solver->yh;
232 work->solver->Atyh = qpalm_calloc(n, sizeof(c_float));
233 work->Atyh = work->solver->Atyh;
234 work->solver->At_scale = qpalm_calloc(m, sizeof(c_float));
235
237
239 work->solver->sym_Q = ladel_symbolics_alloc(n);
240
241 // Allocate solution
242 work->solution = qpalm_calloc(1, sizeof(QPALMSolution));
243 work->solution->x = qpalm_calloc(1, n * sizeof(c_float));
244 work->solution->y = qpalm_calloc(1, m * sizeof(c_float));
245
246 // Allocate and initialize information
247 work->info = qpalm_calloc(1, sizeof(QPALMInfo));
249 # ifdef QPALM_TIMING
250 work->info->solve_time = 0.0; // Solve time to zero
251 work->info->run_time = 0.0; // Total run time to zero
252 work->info->setup_time = qpalm_toc(work->timer); // Update timer information
253 # endif /* ifdef QPALM_TIMING */
254 atomic_init(&work->cancel, 0);
255
256 return work;
257}
258
259
260void qpalm_warm_start(QPALMWorkspace *work, const c_float *x_warm_start, const c_float *y_warm_start)
261{
262 atomic_store(&work->cancel, 0);
263
264 // If we have previously solved the problem, then reset the setup time
265 if (work->info->status_val != QPALM_UNSOLVED)
266 {
267 #ifdef QPALM_TIMING
268 work->info->setup_time = 0;
269 #endif /* ifdef QPALM_TIMING */
271 }
272 #ifdef QPALM_TIMING
273 qpalm_tic(work->timer);
274 #endif
275
276 size_t n = work->data->n;
277 size_t m = work->data->m;
278
279 if (x_warm_start != NULL)
280 {
281 prea_vec_copy(x_warm_start, work->x, n);
282 }
283 else
284 {
285 qpalm_free(work->x);
286 work->x = NULL;
287 }
288
289 if (y_warm_start != NULL)
290 {
291 prea_vec_copy(y_warm_start, work->y, m);
292 }
293 else
294 {
295 qpalm_free(work->y);
296 work->y = NULL;
297 }
298
299 work->initialized = TRUE;
300
301 #ifdef QPALM_TIMING
302 work->info->setup_time += qpalm_toc(work->timer); // Start timer
303 #endif /* ifdef QPALM_TIMING */
304
305}
306
307static void qpalm_initialize(QPALMWorkspace *work, solver_common **common1, solver_common **common2)
308{
309 // If we have previously solved the problem, then reset the setup time
310 if (work->info->status_val != QPALM_UNSOLVED)
311 {
312 #ifdef QPALM_TIMING
313 work->info->setup_time = 0;
314 #endif /* ifdef QPALM_TIMING */
316 }
317 #ifdef QPALM_TIMING
318 qpalm_tic(work->timer);
319 #endif
320
321 // Print header
322 #ifdef QPALM_PRINTING
323 if (work->settings->verbose)
324 {
325 print_header();
326 }
327 #endif
328
329 size_t n = work->data->n;
330 size_t m = work->data->m;
331 *common1 = ladel_workspace_allocate(n+m);
332 if (work->settings->enable_dual_termination) *common2 = ladel_workspace_allocate(n);
333 else *common2 = *common1;
334 solver_common *c = *common1, *c2 = *common2;
335
336 if (!work->initialized)
337 {
338 qpalm_warm_start(work, NULL, NULL);
339 }
340
341 work->eps_abs_in = work->settings->eps_abs_in;
342 work->eps_rel_in = work->settings->eps_rel_in;
344 work->solver->reset_newton = TRUE;
345 work->gamma = work->settings->gamma_init;
346 work->gamma_maxed = FALSE;
348
349 if (work->x == NULL)
350 {
351 work->x = qpalm_calloc(n, sizeof(c_float));
352 vec_set_scalar(work->x, 0., n);
353 vec_set_scalar(work->x_prev, 0., n);
354 vec_set_scalar(work->x0, 0., n);
355 vec_set_scalar(work->Qx, 0., n);
356 vec_set_scalar(work->Ax, 0., m);
357 work->info->objective = work->data->c;
358 }
359 else
360 {
361 mat_vec(work->data->Q, work->x, work->Qx, c);
362 mat_vec(work->data->A, work->x, work->Ax, c);
363 }
364
365 if (work->y == NULL)
366 {
367 work->y = qpalm_calloc(m, sizeof(c_float));
368 vec_set_scalar(work->y, 0., m);
369 }
370
371 for (size_t i = 0; i < work->data->m; i++)
372 {
373 if (work->data->bmax[i] > QPALM_INFTY) work->data->bmax[i] = QPALM_INFTY;
374 if (work->data->bmin[i] < -QPALM_INFTY) work->data->bmin[i] = -QPALM_INFTY;
375 }
376
377 if (work->settings->scaling)
378 {
379 scale_data(work);
380 }
381
382 //Actions to perform after scaling
383 prea_vec_copy(work->x, work->x0, n);
384 prea_vec_copy(work->x, work->x_prev, n);
385
387 {
388 if (work->solver->At) ladel_sparse_free(work->solver->At);
389 work->solver->At = ladel_transpose(work->data->A, TRUE, c);
390 }
391
392 if (work->settings->nonconvex)
393 {
394 set_settings_nonconvex(work, c);
395 }
396 if (work->settings->proximal)
397 {
398 vec_add_scaled(work->Qx, work->x, work->Qx, 1/work->gamma, n);
399 }
400
401 work->info->objective = compute_objective(work);
402
403 initialize_sigma(work, c);
404
405 //Provide LD factor of Q in case dual_termination is enabled
406 //NB assume Q is positive definite
408 {
409 if (work->solver->LD_Q) ladel_factor_free(work->solver->LD_Q);
410 ladel_factorize(work->data->Q, work->solver->sym_Q, work->settings->ordering, &work->solver->LD_Q, c2);
411 work->info->dual_objective = compute_dual_objective(work, c2);
412 } else
413 {
415 }
416
417 #ifdef QPALM_TIMING
418 work->info->setup_time += qpalm_toc(work->timer); // Start timer
419 #endif /* ifdef QPALM_TIMING */
420}
421
422static void qpalm_termination(QPALMWorkspace *work, solver_common* c, solver_common *c2, c_int iter, c_int iter_out)
423{
424 if (work->info->status_val == QPALM_SOLVED ||
428 {
429 store_solution(work);
430 }
431 else if (work->info->status_val == QPALM_PRIMAL_INFEASIBLE)
432 {
433 if (work->settings->scaling)
434 {
435 vec_self_mult_scalar(work->delta_y, work->scaling->cinv, work->data->m);
436 vec_ew_prod(work->scaling->E, work->delta_y, work->delta_y, work->data->m);
437 }
438 }
439 else if (work->info->status_val == QPALM_DUAL_INFEASIBLE)
440 {
441 if (work->settings->scaling)
442 {
443 vec_ew_prod(work->scaling->D, work->delta_x, work->delta_x, work->data->n);
444 }
445 }
446
447 unscale_data(work);
448
449 work->initialized = FALSE;
450 work->info->iter = iter;
451 work->info->iter_out = iter_out;
452
453 /* Update solve time and run time */
454 #ifdef QPALM_TIMING
455 work->info->solve_time = qpalm_toc(work->timer);
456 work->info->run_time = work->info->setup_time +
457 work->info->solve_time;
458 #endif /* ifdef QPALM_TIMING */
459
460 c = ladel_workspace_free(c);
462 c2 = ladel_workspace_free(c2);
463
464 #ifdef QPALM_PRINTING
465 if (work->settings->verbose)
466 {
467 print_iteration(iter, work);
469 }
470 #endif
471}
472
473static void qpalm_terminate_on_status(QPALMWorkspace *work, solver_common *c, solver_common *c2, c_int iter, c_int iter_out, c_int status_val)
474{
475 update_status(work->info, status_val);
476 qpalm_termination(work, c, c2, iter, iter_out);
477}
478
480 atomic_store(&work->cancel, 1);
481}
482
484{
485 #if defined(QPALM_PRINTING) && defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1900
486 unsigned int print_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT);
487 #endif
488
489 //Initialize ladel workspace, qpalm variables and perform scaling (timing added to setup)
490 solver_common *c, *c2;
491 qpalm_initialize(work, &c, &c2);
492
493 // Start the timer for the solve routine
494 #ifdef QPALM_TIMING
495 qpalm_tic(work->timer);
496 c_float current_time;
497 #endif /* ifdef QPALM_TIMING */
498
499 size_t m = work->data->m;
500 c_int iter;
501 c_int iter_out = 0;
502 c_int prev_iter = 0; /* iteration number at which the previous subproblem finished*/
503 c_float eps_k_abs = work->settings->eps_abs_in;
504 c_float eps_k_rel = work->settings->eps_rel_in;
505 c_int no_change_in_active_constraints = 0;
506
507 for (iter = 0; iter < work->settings->max_iter; iter++)
508 {
509 /* Check whether we passed the time limit */
510 #ifdef QPALM_TIMING
511 current_time = work->info->setup_time + qpalm_toc(work->timer); // Start timer
512 if (current_time > work->settings->time_limit)
513 {
514 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_TIME_LIMIT_REACHED);
515 return;
516 }
517 #endif /* ifdef QPALM_TIMING */
518 if (atomic_load(&work->cancel))
519 {
520 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_USER_CANCELLATION);
521 return;
522 }
523
524 /*Perform the iteration */
525 compute_residuals(work, c);
527
528 if (is_solved(work))
529 {
530 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_SOLVED);
531 return;
532 }
533 else if (is_primal_infeasible(work))
534 {
535 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_PRIMAL_INFEASIBLE);
536 return;
537 }
538 else if (is_dual_infeasible(work))
539 {
540 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_DUAL_INFEASIBLE);
541 return;
542 }
543 else if (check_subproblem_termination(work) || (no_change_in_active_constraints == 3))
544 {
545 update_dual_iterate_and_parameters(work, c, iter_out, &eps_k_abs, &eps_k_rel);
546
548 {
551 {
552 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_DUAL_TERMINATED);
553 return;
554 }
555 }
556
557 no_change_in_active_constraints = 0;
558 iter_out++;
559 prev_iter = iter;
560
561 #ifdef QPALM_PRINTING
562 if (work->settings->verbose && mod(iter, work->settings->print_iter) == 0)
563 {
564 qpalm_print("%4" LADEL_PRIi " | ---------------------------------------------------\n", iter);
565 }
566 #endif
567 }
568 else if (iter == prev_iter + work->settings->inner_max_iter) /*subproblem is hanging so try updating params*/
569 {
570 if (iter_out > 0 && work->info->pri_res_norm > work->eps_pri)
571 {
572 update_sigma(work, c);
573 }
574
575 if(work->settings->proximal)
576 {
577 update_gamma(work);
578 if (!work->settings->nonconvex) prea_vec_copy(work->x, work->x0, work->data->n);
579 }
580
581 prea_vec_copy(work->pri_res, work->pri_res_in, m);
582
583 no_change_in_active_constraints = 0;
584 iter_out++;
585 prev_iter = iter;
586 }
587 else /*primal update*/
588 {
589 if (work->solver->nb_enter + work->solver->nb_leave) no_change_in_active_constraints = 0;
590 else no_change_in_active_constraints++;
591
592 if (mod(iter, work->settings->reset_newton_iter) == 0) work->solver->reset_newton = TRUE;
593 update_primal_iterate(work, c);
594
595 #ifdef QPALM_PRINTING
596 if (work->settings->verbose && mod(iter, work->settings->print_iter) == 0)
597 {
598 work->info->objective = compute_objective(work);
599 print_iteration(iter, work);
600 }
601 #endif
602 }
603 }
604
605 /* If we get here, qpalm has unfortunately hit the maximum number of iterations */
606 qpalm_terminate_on_status(work, c, c2, iter, iter_out, QPALM_MAX_ITER_REACHED);
607 return;
608}
609
611{
612 // If we have previously solved the problem, then reset the setup time
613 if (work->info->status_val != QPALM_UNSOLVED)
614 {
615 #ifdef QPALM_TIMING
616 work->info->setup_time = 0;
617 #endif /* ifdef QPALM_TIMING */
619 }
620 #ifdef QPALM_TIMING
621 qpalm_tic(work->timer); // Start timer
622 #endif /* ifdef QPALM_TIMING */
623
624 // Validate settings
625 if (!validate_settings(settings))
626 {
627 # ifdef QPALM_PRINTING
628 qpalm_eprint("Settings validation returned failure");
629 # endif /* ifdef QPALM_PRINTING */
631 return;
632 }
633
634 // Copy settings
635 qpalm_free(work->settings);
636 work->settings = copy_settings(settings);
637 work->sqrt_delta = c_sqrt(work->settings->delta);
638 # ifdef QPALM_TIMING
639 work->info->setup_time += qpalm_toc(work->timer);
640 # endif /* ifdef QPALM_TIMING */
641}
642
643void qpalm_update_bounds(QPALMWorkspace *work, const c_float *bmin, const c_float *bmax)
644{
645 // If we have previously solved the problem, then reset the setup time
646 if (work->info->status_val != QPALM_UNSOLVED)
647 {
648 #ifdef QPALM_TIMING
649 work->info->setup_time = 0;
650 #endif /* ifdef QPALM_TIMING */
652 }
653 #ifdef QPALM_TIMING
654 qpalm_tic(work->timer); // Start timer
655 #endif /* ifdef QPALM_TIMING */
656
657 // Validate bounds
658 size_t j;
659 size_t m = work->data->m;
660 if (bmin != NULL && bmax != NULL)
661 {
662 for (j = 0; j < m; j++)
663 {
664 if (bmin[j] > bmax[j])
665 {
666 # ifdef QPALM_PRINTING
667 qpalm_eprint("Lower bound at index %d is greater than upper bound: %.4e > %.4e",
668 (int)j, work->data->bmin[j], work->data->bmax[j]);
669 # endif /* ifdef QPALM_PRINTING */
671 return;
672 }
673 }
674 }
675
676 if (bmin != NULL)
677 {
678 prea_vec_copy(bmin, work->data->bmin, m);
679 }
680 if (bmax != NULL)
681 {
682 prea_vec_copy(bmax, work->data->bmax, m);
683 }
684
685 # ifdef QPALM_TIMING
686 work->info->setup_time += qpalm_toc(work->timer);
687 # endif /* ifdef QPALM_TIMING */
688}
689
691{
692 // If we have previously solved the problem, then reset the setup time
693 if (work->info->status_val != QPALM_UNSOLVED)
694 {
695 #ifdef QPALM_TIMING
696 work->info->setup_time = 0;
697 #endif /* ifdef QPALM_TIMING */
699 }
700 #ifdef QPALM_TIMING
701 qpalm_tic(work->timer); // Start timer
702 #endif /* ifdef QPALM_TIMING */
703
704 size_t n = work->data->n;
705 prea_vec_copy(q, work->data->q, n);
706 # ifdef QPALM_TIMING
707 work->info->setup_time += qpalm_toc(work->timer);
708 # endif /* ifdef QPALM_TIMING */
709}
710
711void qpalm_update_Q_A(QPALMWorkspace *work, const c_float *Qx, const c_float *Ax)
712{
714 // If we have previously solved the problem, then reset the setup time
715 if (work->info->status_val != QPALM_UNSOLVED)
716 {
717 #ifdef QPALM_TIMING
718 work->info->setup_time = 0;
719 #endif /* ifdef QPALM_TIMING */
721 }
722 #ifdef QPALM_TIMING
723 qpalm_tic(work->timer); // Start timer
724 #endif /* ifdef QPALM_TIMING */
725
726 ladel_sparse_matrix *Q = work->data->Q, *A = work->data->A;
727 prea_vec_copy(Qx, Q->x, Q->nzmax);
728 prea_vec_copy(Ax, A->x, A->nzmax);
729
730 # ifdef QPALM_TIMING
731 work->info->setup_time += qpalm_toc(work->timer);
732 # endif /* ifdef QPALM_TIMING */
733}
734
736{
737 if (work)
738 {
739 // Free Data
740 if (work->data)
741 {
742 work->data->Q = ladel_sparse_free(work->data->Q);
743
744 work->data->A = ladel_sparse_free(work->data->A);
745
746 if (work->data->q) qpalm_free(work->data->q);
747
748 if (work->data->bmin) qpalm_free(work->data->bmin);
749
750 if (work->data->bmax) qpalm_free(work->data->bmax);
751 qpalm_free(work->data);
752 }
753
754 // Free scaling
755 if (work->scaling->D) qpalm_free(work->scaling->D);
756
757 if (work->scaling->Dinv) qpalm_free(work->scaling->Dinv);
758
759 if (work->scaling->E) qpalm_free(work->scaling->E);
760
761 if (work->scaling->Einv) qpalm_free(work->scaling->Einv);
762
763 qpalm_free(work->scaling);
764
765 // Free other Variables
766 if (work->x) qpalm_free(work->x);
767
768 if (work->y) qpalm_free(work->y);
769
770 if (work->Ax) qpalm_free(work->Ax);
771
772 if (work->Qx) qpalm_free(work->Qx);
773
774 if (work->x_prev) qpalm_free(work->x_prev);
775
776 if (work->Aty) qpalm_free(work->Aty);
777
778 if (work->temp_m) qpalm_free(work->temp_m);
779
780 if (work->temp_n) qpalm_free(work->temp_n);
781
782 if (work->sigma) qpalm_free(work->sigma);
783
784 if (work->sigma_inv) qpalm_free(work->sigma_inv);
785
786 if (work->z) qpalm_free(work->z);
787
788 if (work->Axys) qpalm_free(work->Axys);
789
790 if (work->pri_res) qpalm_free(work->pri_res);
791
792 if (work->pri_res_in) qpalm_free(work->pri_res_in);
793
794 if (work->df) qpalm_free(work->df);
795
796 if (work->x0) qpalm_free(work->x0);
797
798 if (work->xx0) qpalm_free(work->xx0);
799
800 if (work->dphi) qpalm_free(work->dphi);
801
802 if (work->dphi_prev) qpalm_free(work->dphi_prev);
803
804 if (work->sqrt_sigma) qpalm_free(work->sqrt_sigma);
805
806 if (work->delta) qpalm_free(work->delta);
807
808 if (work->alpha) qpalm_free(work->alpha);
809
810 if (work->delta2) qpalm_free(work->delta2);
811
812 if (work->delta_alpha) qpalm_free(work->delta_alpha);
813
814 if (work->temp_2m) qpalm_free(work->temp_2m);
815
816 if (work->s) qpalm_free(work->s);
817
818 if (work->index_L) qpalm_free(work->index_L);
819
820 if (work->index_P) qpalm_free(work->index_P);
821
822 if (work->index_J) qpalm_free(work->index_J);
823
824 if (work->delta_y) qpalm_free(work->delta_y);
825
826 if (work->Atdelta_y) qpalm_free(work->Atdelta_y);
827
828 if (work->delta_x) qpalm_free(work->delta_x);
829
830 if (work->Qdelta_x) qpalm_free(work->Qdelta_x);
831
832 if (work->Adelta_x) qpalm_free(work->Adelta_x);
833
834 // Free Settings
835 if (work->settings) qpalm_free(work->settings);
836
837 //Free chol struct
838 if (work->solver)
839 {
841
843
844 if (work->solver->enter) qpalm_free(work->solver->enter);
845
846 if (work->solver->leave) qpalm_free(work->solver->leave);
847
848
849 work->solver->sol_kkt = ladel_free(work->solver->sol_kkt);
850
851 work->solver->rhs_kkt = ladel_free(work->solver->rhs_kkt);
852
853 work->solver->D_temp = ladel_free(work->solver->D_temp);
854
855 work->solver->E_temp = ladel_free(work->solver->E_temp);
856
857 work->solver->neg_dphi = ladel_free(work->solver->neg_dphi);
858
859 work->solver->d = ladel_free(work->solver->d);
860
861 work->solver->Qd = ladel_free(work->solver->Qd);
862
863 work->solver->Ad = ladel_free(work->solver->Ad);
864
865 work->solver->yh = ladel_free(work->solver->yh);
866
867 work->solver->Atyh = ladel_free(work->solver->Atyh);
868
869 work->solver->LD = ladel_factor_free(work->solver->LD);
870
871 work->solver->LD_Q = ladel_factor_free(work->solver->LD_Q);
872
873 work->solver->sym = ladel_symbolics_free(work->solver->sym);
874
875 work->solver->sym_Q = ladel_symbolics_free(work->solver->sym_Q);
876
877 work->solver->At_scale = ladel_free(work->solver->At_scale);
878
879 work->solver->At_sqrt_sigma = ladel_sparse_free(work->solver->At_sqrt_sigma);
880
881 work->solver->At = ladel_sparse_free(work->solver->At);
882
883 work->solver->kkt = ladel_sparse_free(work->solver->kkt);
884
885 work->solver->kkt_full = ladel_sparse_free(work->solver->kkt_full);
886
887 work->solver->first_row_A = ladel_free(work->solver->first_row_A);
888
889 work->solver->first_elem_A = ladel_free(work->solver->first_elem_A);
890
891
892 qpalm_free(work->solver);
893 }
894
895 // Free solution
896 if (work->solution)
897 {
898 if (work->solution->x) qpalm_free(work->solution->x);
899
900 if (work->solution->y) qpalm_free(work->solution->y);
901 qpalm_free(work->solution);
902 }
903
904 // Free timer
905 # ifdef QPALM_TIMING
906 if (work->timer) qpalm_free(work->timer);
907 # endif /* ifdef QPALM_TIMING */
908
909 // Free information
910 if (work->info) qpalm_free(work->info);
911
912 // Free work
913 qpalm_free(work);
914 }
915
916}
917
918
919# ifdef __cplusplus
920}
921# endif // ifdef __cplusplus
Constants used in QPALM.
#define ORDERING
ordering in the factorization
Definition constants.h:114
#define EPS_REL_IN
default intermediate relative convergence tolerance
Definition constants.h:71
#define SCALING
default number of scaling iterations
Definition constants.h:84
#define NONCONVEX
default use of nonconvex adjustments
Definition constants.h:88
#define QPALM_MAX_ITER_REACHED
status to indicate termination due to reaching the maximum number of iterations
Definition constants.h:32
#define WARM_START
default warm start setting
Definition constants.h:89
#define QPALM_USER_CANCELLATION
status to indicate the user has cancelled the solve
Definition constants.h:36
#define GAMMA_UPD
default proximal penalty update factor
Definition constants.h:81
#define PRINT_ITER
default frequency of printing
Definition constants.h:91
#define EPS_ABS
default absolute convergence tolerance
Definition constants.h:68
#define QPALM_ERROR
status to indicate an error has occured (this error should automatically be printed)
Definition constants.h:38
#define FACTORIZE_SCHUR
factorize the Schur complement
Definition constants.h:108
#define RHO
default tolerance scaling factor
Definition constants.h:72
#define DELTA
default penalty update factor
Definition constants.h:76
#define VERBOSE
default write out progress setting
Definition constants.h:90
#define INNER_MAX_ITER
default maximum number of iterations per subproblem
Definition constants.h:67
#define QPALM_DUAL_INFEASIBLE
status to indicate the problem is dual infeasible
Definition constants.h:34
#define RESET_NEWTON_ITER
default frequency of performing a full Cholesky factorization
Definition constants.h:93
#define GAMMA_INIT
default initial proximal penalty parameter
Definition constants.h:80
#define SIGMA_INIT
default initial penalty parameter (guideline)
Definition constants.h:78
#define EPS_REL
default relative convergence tolerance
Definition constants.h:69
#define MAX_RANK_UPDATE
maximum rank for the sparse factorization update
Definition constants.h:99
#define PROXIMAL
default use of proximal method of multipliers
Definition constants.h:79
#define QPALM_TIME_LIMIT_REACHED
status to indicate the problem's runtime has exceeded the specified time limit
Definition constants.h:35
#define ENABLE_DUAL_TERMINATION
enable termination after dual objective > something (useful in branch and bound)
Definition constants.h:95
#define FACTORIZATION_METHOD
default method for solving the linear system
Definition constants.h:111
#define QPALM_PRIMAL_INFEASIBLE
status to indicate the problem is primal infeasible
Definition constants.h:33
#define MAX_RANK_UPDATE_FRACTION
maximum rank (relative to n+m) for the factorization update
Definition constants.h:100
#define QPALM_SOLVED
status to indicate the problem is solved to optimality given the specified tolerances
Definition constants.h:30
#define QPALM_DUAL_TERMINATED
status to indicate the problem has a dual objective that is higher than the specified bound
Definition constants.h:31
#define TRUE
Definition constants.h:18
#define FALSE
Definition constants.h:19
#define THETA
default penalty update criterion parameter
Definition constants.h:75
#define QPALM_NULL
NULL, if something goes wrong during setup, the workspace pointer is set to this.
Definition constants.h:54
#define SIGMA_MAX
default penalty cap
Definition constants.h:77
#define FACTORIZE_KKT
factorize the kkt system
Definition constants.h:107
#define TIME_LIMIT
time limit after which the solver aborts
Definition constants.h:97
#define QPALM_UNSOLVED
status to indicate the problem is unsolved.
Definition constants.h:37
#define GAMMA_MAX
default proximal penalty cap
Definition constants.h:82
#define MAX_ITER
default maximum number of iterations
Definition constants.h:66
#define EPS_PRIM_INF
default primal infeasibility tolerance
Definition constants.h:73
#define EPS_ABS_IN
default intermediate absolute convergence tolerance
Definition constants.h:70
#define QPALM_INFTY
infinity, used to indicate one-sided constraints
Definition constants.h:62
#define DUAL_OBJECTIVE_LIMIT
termination value for the dual objective (useful in branch and bound)
Definition constants.h:96
#define EPS_DUAL_INF
default dual infeasibility tolerance
Definition constants.h:74
void qpalm_free(void *ptr)
Definition global_opts.c:16
void * qpalm_malloc(size_t size)
Definition global_opts.c:7
void * qpalm_calloc(size_t num, size_t size)
Definition global_opts.c:3
Custom memory allocation, print and utility functions, and data types for floats and ints.
#define c_sqrt
square root
ladel_int c_int
type for integer numbers
Definition global_opts.h:42
#define qpalm_print
Definition global_opts.h:75
#define mod(a, b)
modulo operation (positive result for all values)
ladel_double c_float
type for floating point numbers
Definition global_opts.h:41
#define qpalm_eprint(...)
Definition global_opts.h:81
void qpalm_solve(QPALMWorkspace *work)
Solve the quadratic program.
Definition qpalm.c:483
QPALMWorkspace * qpalm_setup(const QPALMData *data, const QPALMSettings *settings)
Initialize QPALM solver allocating memory.
Definition qpalm.c:68
void qpalm_update_settings(QPALMWorkspace *work, const QPALMSettings *settings)
Update the settings to the new settings.
Definition qpalm.c:610
void qpalm_set_default_settings(QPALMSettings *settings)
Set default settings from constants.h file.
Definition qpalm.c:33
void qpalm_update_bounds(QPALMWorkspace *work, const c_float *bmin, const c_float *bmax)
Update the lower and upper bounds.
Definition qpalm.c:643
void qpalm_update_Q_A(QPALMWorkspace *work, const c_float *Qx, const c_float *Ax)
Update the matrix entries of Q and A.
Definition qpalm.c:711
void qpalm_warm_start(QPALMWorkspace *work, const c_float *x_warm_start, const c_float *y_warm_start)
Warm start workspace variables x, x_0, x_prev, Ax, Qx, y and sigma.
Definition qpalm.c:260
void qpalm_cleanup(QPALMWorkspace *work)
Cleanup the workspace by deallocating memory.
Definition qpalm.c:735
void qpalm_cancel(QPALMWorkspace *work)
Cancel the ongoing call to qpalm_solve.
Definition qpalm.c:479
void qpalm_update_q(QPALMWorkspace *work, const c_float *q)
Update the linear part of the cost.
Definition qpalm.c:690
void initialize_sigma(QPALMWorkspace *work, solver_common *c)
Initialize penalty factors from initial x.
Definition iteration.c:48
c_float compute_dual_objective(QPALMWorkspace *work, solver_common *c)
Compute the (unscaled) dual objective value at the current iterate.
Definition iteration.c:328
void update_dual_iterate_and_parameters(QPALMWorkspace *work, solver_common *c, c_int iter_out, c_float *eps_k_abs, c_float *eps_k_rel)
Definition iteration.c:249
void update_gamma(QPALMWorkspace *work)
Update the proximal penalty.
Definition iteration.c:126
void update_sigma(QPALMWorkspace *work, solver_common *c)
Update the penalty factors.
Definition iteration.c:73
void update_primal_iterate(QPALMWorkspace *work, solver_common *c)
Update the primal iterate.
Definition iteration.c:269
c_float compute_objective(QPALMWorkspace *work)
Compute the (unscaled) primal objective value at the current iterate.
Definition iteration.c:287
void compute_residuals(QPALMWorkspace *work, solver_common *c)
Compute the residuals (in vector form)
Definition iteration.c:22
QPALM main solver routines.
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
c_float * vec_copy(const c_float *a, size_t n)
Copy vector a into output.
Definition lin_alg.c:11
void vec_set_scalar(c_float *a, c_float sc, size_t n)
Fill float vector with a scalar value.
Definition lin_alg.c:40
void vec_set_scalar_int(c_int *a, c_int sc, size_t n)
Fill int vector with a scalar value.
Definition lin_alg.c:48
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 vec_ew_prod(const c_float *a, const c_float *b, c_float *c, size_t n)
Elementwise product, .
Definition lin_alg.c:92
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
Linear algebra with vectors.
Routines to perform exact linesearch.
Functions to calculate the semismooth Newton direction.
void set_settings_nonconvex(QPALMWorkspace *work, solver_common *c)
Set the proximal parameters for nonconvex QPs.
Definition nonconvex.c:331
Routines to deal with nonconvex QPs.
QPALM main solver API.
void scale_data(QPALMWorkspace *work)
Scale problem matrices.
Definition scaling.c:31
void unscale_data(QPALMWorkspace *work)
Unscale the problem data.
Definition scaling.c:99
Problem data scaling during setup.
void mat_vec(solver_sparse *A, solver_dense *x, solver_dense *y, solver_common *c)
Matrix-vector multiplication.
void qpalm_set_factorization_method(QPALMWorkspace *work, solver_common *c)
Choose the linear systems solver method based on the problem data sizes.
Interface and wrapper to matrix/factorization (ladel) functions.
Data structure.
Definition types.h:109
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
c_float c
constant part of cost
Definition types.h:115
size_t n
number of variables n
Definition types.h:110
c_float * q
dense array for linear part of cost function (size n)
Definition types.h:114
solver_sparse * A
sparse linear constraints matrix A (size m x n)
Definition types.h:113
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
Solver return information.
Definition types.h:81
c_float run_time
total time (seconds)
Definition types.h:97
c_int iter_out
number of outer iterations (i.e. dual updates)
Definition types.h:83
c_float pri_res_norm
norm of primal residual
Definition types.h:87
c_float dual_objective
dual objective function value (= NaN if enable_dual_termination is false)
Definition types.h:92
c_int iter
number of iterations taken
Definition types.h:82
c_float solve_time
time taken for solve phase (seconds)
Definition types.h:96
c_float objective
objective function value
Definition types.h:91
c_int status_val
status as c_int, defined in constants.h
Definition types.h:85
c_float setup_time
time taken for setup phase (seconds)
Definition types.h:95
Problem scaling matrices stored as vectors.
Definition types.h:68
c_float * Dinv
primal variable rescaling
Definition types.h:70
c_float * E
dual variable scaling
Definition types.h:71
c_float * Einv
dual variable rescaling
Definition types.h:72
c_float cinv
objective rescaling
Definition types.h:74
c_float * D
primal variable scaling
Definition types.h:69
Settings struct.
Definition types.h:124
c_float gamma_upd
proximal penalty update factor
Definition types.h:140
c_float sigma_max
penalty factor cap
Definition types.h:136
c_float eps_abs_in
intermediate absolute convergence tolerance
Definition types.h:129
c_float gamma_max
proximal penalty parameter cap
Definition types.h:141
c_int proximal
boolean, use proximal method of multipliers or not
Definition types.h:138
c_float delta
penalty update factor
Definition types.h:135
c_int warm_start
boolean, warm start
Definition types.h:146
c_float sigma_init
initial penalty parameter (guideline)
Definition types.h:137
c_float eps_dual_inf
dual infeasibility tolerance
Definition types.h:133
c_int reset_newton_iter
frequency of performing a complete Cholesky factorization
Definition types.h:147
c_float dual_objective_limit
termination value for the dual objective (useful in branch and bound)
Definition types.h:149
c_float eps_rel_in
intermediate relative convergence tolerance
Definition types.h:130
c_float rho
tolerance scaling factor
Definition types.h:131
c_float time_limit
time limit
Definition types.h:150
c_float theta
penalty update criterion parameter
Definition types.h:134
c_int max_rank_update
maximum rank for the sparse factorization update
Definition types.h:153
c_int enable_dual_termination
boolean, enable termination based on dual objective (useful in branch and bound)
Definition types.h:148
c_float max_rank_update_fraction
maximum rank (relative to n+m) for the factorization update
Definition types.h:154
c_float gamma_init
initial proximal penalty parameter
Definition types.h:139
c_float eps_prim_inf
primal infeasibility tolerance
Definition types.h:132
c_int inner_max_iter
maximum number of iterations per subproblem
Definition types.h:126
c_float eps_rel
relative convergence tolerance
Definition types.h:128
c_int verbose
boolean, write out progress
Definition types.h:144
c_int max_iter
maximum number of iterations
Definition types.h:125
c_int scaling
scaling iterations, if 0 then scaling is disabled
Definition types.h:142
c_int nonconvex
boolean, indicates whether the QP is nonconvex
Definition types.h:143
c_float eps_abs
absolute convergence tolerance
Definition types.h:127
c_int ordering
ordering method for factorization
Definition types.h:151
c_int factorization_method
factorize KKT or Schur complement
Definition types.h:152
c_int print_iter
frequency of printing
Definition types.h:145
Solution structure.
Definition types.h:50
c_float * y
dual solution
Definition types.h:52
c_float * x
primal solution
Definition types.h:51
Variables for linear system solving.
Definition types.h:162
solver_dense * E_temp
temporary constraints scaling vectors
Definition types.h:173
solver_dense * neg_dphi
-gradient of the Lagrangian
Definition types.h:175
solver_dense * D_temp
temporary primal variable scaling vectors
Definition types.h:174
solver_dense * Ad
A * d.
Definition types.h:179
solver_sparse * At_sqrt_sigma
A' * sqrt(sigma)
Definition types.h:193
c_int * first_row_A
row index of the first element in each column of A'
Definition types.h:167
c_int * active_constraints
index set of active constraints
Definition types.h:185
solver_dense * yh
candidate dual update
Definition types.h:181
c_int reset_newton
boolean, after sigma is updated perform a new factorization
Definition types.h:184
solver_dense * d
primal update step
Definition types.h:178
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
solver_sparse * At
A'.
Definition types.h:166
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 * At_scale
running vector of sqrt(sigma), used to scale At_sqrt_sigma
Definition types.h:192
solver_dense * Atyh
A' * yh.
Definition types.h:182
solver_dense * Qd
Q * d.
Definition types.h:180
solver_dense * sol_kkt
sol_kkt = kkt \ rhs_kkt
Definition types.h:177
solver_factor * LD_Q
LD factor of Q (useful in computing dual objective)
Definition types.h:171
c_float * first_elem_A
value of the first element in each column of A'
Definition types.h:168
c_int nb_leave
number of leaving constraints
Definition types.h:191
solver_symbolics * sym_Q
symbolics for Q (only used in LADEL)
Definition types.h:172
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 * delta_y
difference of consecutive dual iterates
Definition types.h:286
c_float * x
primal iterate
Definition types.h:211
c_float * y
dual iterate
Definition types.h:212
c_float * yh
candidate dual update
Definition types.h:236
QPALMScaling * scaling
scaling vectors
Definition types.h:313
c_float * delta
linesearch parameter
Definition types.h:259
c_int nb_sigma_changed
number of sigma-components that changed in an outer iteration (relevant for factorization update)
Definition types.h:229
c_int initialized
flag whether the iterates were initialized or not
Definition types.h:217
c_float * D_temp
temporary primal variable scaling vectors
Definition types.h:306
c_float * delta2
delta .* delta
Definition types.h:262
c_float eps_pri
primal tolerance
Definition types.h:275
c_float * Ax
scaled A * x
Definition types.h:213
QPALMInfo * info
solver information
Definition types.h:315
c_float * z
projection of Axys onto the constraint set [bmin, bmax]
Definition types.h:233
c_float * pri_res_in
intermediate primal residual
Definition types.h:235
c_int * index_J
index set J (L xor P)
Definition types.h:267
c_float * temp_m
placeholder for vector of size m
Definition types.h:224
QPALMSolution * solution
problem solution
Definition types.h:314
c_int * index_P
index set P (where delta>0)
Definition types.h:266
c_float * pri_res
primal residual
Definition types.h:234
c_float * sqrt_sigma
elementwise sqrt(sigma)
Definition types.h:255
c_float * sigma
penalty vector
Definition types.h:226
array_element * s
alpha ./ delta
Definition types.h:264
c_float * delta_alpha
delta .* alpha
Definition types.h:263
c_float * x_prev
previous primal iterate
Definition types.h:216
c_float * Adelta_x
A * delta_x.
Definition types.h:297
c_float * neg_dphi
-dphi, required as the rhs in SCHUR
Definition types.h:242
c_float * Axys
Ax + y./sigma.
Definition types.h:232
c_float * Qdelta_x
Q * delta_x.
Definition types.h:296
c_int gamma_maxed
flag to indicate whether gamma has been maximized when the primal residual was low
Definition types.h:231
c_float * delta_x
difference of consecutive primal iterates
Definition types.h:295
QPALMTimer * timer
timer object
Definition types.h:318
c_float * Qx
scaled Q * x
Definition types.h:214
c_float * dphi_prev
previous gradient of the Lagrangian
Definition types.h:243
c_float eps_rel_in
intermediate relative tolerance
Definition types.h:279
QPALMSettings * settings
problem settings
Definition types.h:312
c_float * x0
record of the primal iterate during the last dual update
Definition types.h:239
c_float * sigma_inv
1./sigma
Definition types.h:227
c_float gamma
proximal penalty factor
Definition types.h:230
c_float * dphi
gradient of the Lagrangian
Definition types.h:241
c_float * E_temp
temporary constraints scaling vectors
Definition types.h:307
c_float * df
gradient of the primal objective (+proximal term)
Definition types.h:238
atomic_bool cancel
Cancel the solver (from other thread or signal)
Definition types.h:321
c_float * alpha
linesearch parameter
Definition types.h:260
QPALMSolver * solver
linsys variables
Definition types.h:311
c_float sqrt_delta
sqrt(penalty update factor)
Definition types.h:256
c_float * xx0
x - x0
Definition types.h:240
c_float * Atdelta_y
A' * delta_y.
Definition types.h:287
c_float * temp_2m
placeholder for vector of size 2m
Definition types.h:261
c_float * Ad
A * d.
Definition types.h:254
c_float * Aty
A' * y (useful for saving one mat_tpose_vec)
Definition types.h:215
c_float eps_abs_in
intermediate absolute tolerance
Definition types.h:278
QPALMData * data
problem data to work on (possibly scaled)
Definition types.h:205
c_int * index_L
index set L (where s>0)
Definition types.h:265
c_float * Qd
Q * d.
Definition types.h:253
c_float * temp_n
placeholder for vector of size n
Definition types.h:225
c_float * d
primal update step
Definition types.h:244
c_float * Atyh
A' * yh.
Definition types.h:237
Array to sort in linesearch.
Definition types.h:34
c_int is_primal_infeasible(QPALMWorkspace *work)
Check whether the problem is primal infeasible.
void calculate_residual_norms_and_tolerances(QPALMWorkspace *work)
Calls the routines that compute the norm of the residuals and the tolerances.
Definition termination.c:19
void store_solution(QPALMWorkspace *work)
Helper function to store the (unscaled) solution in the solution struct.
c_int is_solved(QPALMWorkspace *work)
Check whether the primal and dual residual norms are smaller than the primal and dual tolerances.
c_int is_dual_infeasible(QPALMWorkspace *work)
Check whether the problem is dual infeasible.
c_int check_subproblem_termination(QPALMWorkspace *work)
Check whether the subproblem is solved.
Routines to check the termination and infeasibility criteria.
ladel_work solver_common
Definition types.h:25
struct QPALM_TIMER QPALMTimer
QPALM Timer for statistics.
Definition types.h:60
QPALMSettings * copy_settings(const QPALMSettings *settings)
Copy settings creating a new settings structure.
Definition util.c:25
void update_status(QPALMInfo *info, c_int status_val)
Update solver status (value and string).
Definition util.c:62
void print_iteration(c_int iter, QPALMWorkspace *work)
Print information about the current iteration.
Definition util.c:117
void print_header(void)
Print the header with QPALM version number and fields.
Definition util.c:111
void print_final_message(QPALMWorkspace *work)
Print final message as a box with info.
Definition util.c:125
Utility functions.
c_float qpalm_toc(QPALMTimer *t)
Report time in seconds since last call to qpalm_tic.
void qpalm_tic(QPALMTimer *t)
Start timer.
c_int validate_data(const QPALMData *data)
Validate problem data.
Definition validate.c:18
c_int validate_settings(const QPALMSettings *settings)
Validate problem settings.
Definition validate.c:43
Validation of the user provided settings and data.