QPALM main
Proximal Augmented Lagrangian method for Quadratic Programs
Loading...
Searching...
No Matches
util.c
Go to the documentation of this file.
1/**
2 * @file util.c
3 * @author Ben Hermans
4 * @brief Utility functions.
5 * @details This file contains some utility functions, to copy the settings,
6 * to update the solver status, to print information and to time the algorithm.
7 */
8
9#include <qpalm/util.h>
10#include <qpalm/lin_alg.h>
11#include <qpalm/global_opts.h>
12#include <qpalm/types.h>
13#include <string.h>
14#include <stdio.h>
15/**********************
16* Utility Functions *
17**********************/
18
19void c_strcpy(char dest[], const char source[]) {
20 size_t i;
21 for(i = 0; (dest[i] = source[i]) != '\0'; i++);
22}
23
24
27
28 // Copy settings
29 new->max_iter = settings->max_iter;
30 new->inner_max_iter = settings->inner_max_iter;
31 new->eps_abs = settings->eps_abs;
32 new->eps_rel = settings->eps_rel;
33 new->eps_abs_in = settings->eps_abs_in;
34 new->eps_rel_in = settings->eps_rel_in;
35 new->rho = settings->rho;
36 new->eps_prim_inf = settings->eps_prim_inf;
37 new->eps_dual_inf = settings->eps_dual_inf;
38 new->theta = settings->theta;
39 new->delta = settings->delta;
40 new->sigma_max = settings->sigma_max;
41 new->sigma_init = settings->sigma_init;
42 new->proximal = settings->proximal;
43 new->gamma_init = settings->gamma_init;
44 new->gamma_upd = settings->gamma_upd;
45 new->gamma_max = settings->gamma_max;
46 new->scaling = settings->scaling;
47 new->nonconvex = settings->nonconvex;
48 new->verbose = settings->verbose;
49 new->print_iter = settings->print_iter;
50 new->warm_start = settings->warm_start;
51 new->reset_newton_iter = settings->reset_newton_iter;
52 new->enable_dual_termination = settings->enable_dual_termination;
53 new->dual_objective_limit = settings->dual_objective_limit;
54 new->time_limit = settings->time_limit;
55 new->ordering = settings->ordering;
56 new->factorization_method = settings->factorization_method;
57 new->max_rank_update = settings->max_rank_update;
58 new->max_rank_update_fraction = settings->max_rank_update_fraction;
59 return new;
60}
61
62void update_status(QPALMInfo *info, c_int status_val) {
63 // Update status value
64 info->status_val = status_val;
65
66 // Update status string depending on status val
67 switch (status_val)
68 {
69 case QPALM_SOLVED:
70 c_strcpy(info->status, "solved");
71 break;
73 c_strcpy(info->status, "dual terminated");
74 break;
76 c_strcpy(info->status, "primal infeasible");
77 break;
79 c_strcpy(info->status, "dual infeasible");
80 break;
82 c_strcpy(info->status, "time limit exceeded");
83 break;
85 c_strcpy(info->status, "cancelled by user");
86 break;
88 c_strcpy(info->status, "maximum iterations reached");
89 break;
90 case QPALM_UNSOLVED:
91 c_strcpy(info->status, "unsolved");
92 break;
93 case QPALM_ERROR:
94 c_strcpy(info->status, "error");
95 break;
96 default:
97 c_strcpy(info->status, "unrecognised status value");
98 #ifdef QPALM_PRINTING
99 qpalm_eprint("Unrecognised status value %" LADEL_PRIi, status_val);
100 #endif
101 break;
102 }
103}
104
105/**********************
106* Print Functions *
107**********************/
108
109#ifdef QPALM_PRINTING
110
111void print_header(void) {
112 qpalm_print("\n QPALM Version " QPALM_VERSION_STR " \n\n");
113 qpalm_print("Iter | P. res | D. res | Stepsize | Objective \n");
114 qpalm_print("==========================================================\n");
115}
116
118 qpalm_print("%4" LADEL_PRIi " | %.4e | %.4e | %.4e | %.4e \n", iter,
119 work->info->pri_res_norm,
120 work->info->dua_res_norm,
121 work->tau,
122 work->info->objective);
123}
124
126 qpalm_print("\n\n=============================================================\n");
127 size_t characters_box;
128 char buf[80];
129 switch (work->info->status_val) {
130 case QPALM_SOLVED:
131 snprintf(buf, 80, "| QPALM finished successfully. |\n");
132 characters_box = strlen(buf);
133 qpalm_print("%s", buf);
134 // characters_box = qpalm_print("| QPALM finished successfully. |\n");
135 qpalm_print("| primal residual: %5.4e, primal tolerance: %5.4e |\n", work->info->pri_res_norm, work->eps_pri);
136 qpalm_print("| dual residual : %5.4e, dual tolerance : %5.4e |\n", work->info->dua_res_norm, work->eps_dua);
137 qpalm_print("| objective value: %+-5.4e |\n", work->info->objective);
138 break;
140 snprintf(buf, 80,"| QPALM has terminated because the dual objective at the |\n");
141 characters_box = strlen(buf);
142 qpalm_print("%s", buf);
143 // characters_box = qpalm_print("| QPALM has terminated because the dual objective at the |\n");
144 qpalm_print("| current iterate is higher than the value specified in |\n");
145 qpalm_print("| dual_objective_limit. |\n");
146 qpalm_print("| dual objective : %+-4.3e, specified limit : %+-4.3e |\n", work->info->dual_objective, work->settings->dual_objective_limit);
147 break;
149 snprintf(buf, 80,"| QPALM detected a primal infeasible problem. You can check |\n");
150 characters_box = strlen(buf);
151 qpalm_print("%s", buf);
152 // characters_box = qpalm_print("| QPALM detected a primal infeasible problem. You can check |\n");
153 qpalm_print("| the certificate of this infeasiblity. If you think the |\n");
154 qpalm_print("| problem might not be infeasible, try lowering the |\n");
155 qpalm_print("| infeasiblity tolerance eps_prim_inf. |\n");
156 break;
158 snprintf(buf, 80,"| QPALM detected a dual infeasible problem. You can check |\n");
159 characters_box = strlen(buf);
160 qpalm_print("%s", buf);
161 // characters_box = qpalm_print("| QPALM detected a dual infeasible problem. You can check |\n");
162 qpalm_print("| the certificate of this infeasiblity. If you think the |\n");
163 qpalm_print("| problem might not be dual infeasible, try lowering the |\n");
164 qpalm_print("| infeasiblity tolerance eps_dual_inf. |\n");
165 break;
167 snprintf(buf, 80,"| QPALM hit the maximum number of iterations. |\n");
168 characters_box = strlen(buf);
169 qpalm_print("%s", buf);
170 // characters_box = qpalm_print("| QPALM hit the maximum number of iterations. |\n");
171 qpalm_print("| primal residual: %5.4e, primal tolerance: %5.4e |\n", work->info->pri_res_norm, work->eps_pri);
172 qpalm_print("| dual residual : %5.4e, dual tolerance : %5.4e |\n", work->info->dua_res_norm, work->eps_dua);
173 qpalm_print("| objective value: %+-5.4e |\n", work->info->objective);
174 break;
176 snprintf(buf, 80,"| QPALM has exceeded the specified time limit. |\n");
177 characters_box = strlen(buf);
178 qpalm_print("%s", buf);
179 // characters_box = qpalm_print("| QPALM has exceeded the specified time limit. |\n");
180 qpalm_print("| primal residual: %5.4e, primal tolerance: %5.4e |\n", work->info->pri_res_norm, work->eps_pri);
181 qpalm_print("| dual residual : %5.4e, dual tolerance : %5.4e |\n", work->info->dua_res_norm, work->eps_dua);
182 qpalm_print("| objective value: %+-5.4e |\n", work->info->objective);
183 break;
185 snprintf(buf, 80,"| QPALM was cancelled. |\n");
186 characters_box = strlen(buf);
187 qpalm_print("%s", buf);
188 // characters_box = qpalm_print("| QPALM was cancelled. |\n");
189 qpalm_print("| primal residual: %5.4e, primal tolerance: %5.4e |\n", work->info->pri_res_norm, work->eps_pri);
190 qpalm_print("| dual residual : %5.4e, dual tolerance : %5.4e |\n", work->info->dua_res_norm, work->eps_dua);
191 qpalm_print("| objective value: %+-5.4e |\n", work->info->objective);
192 break;
193 default:
194 c_strcpy(work->info->status, "unrecognised status value");
195 qpalm_eprint("Unrecognised final status value %" LADEL_PRIi, work->info->status_val);
196 return;
197 }
198 #ifdef QPALM_TIMING
199 size_t characters_runtime;
200 if (work->info->run_time > 1.0) {
201 snprintf(buf, 80,"| runtime: %4.2f seconds", work->info->run_time);
202 characters_runtime = strlen(buf);
203 qpalm_print("%s", buf);
204 // characters_runtime = qpalm_print("| runtime: %4.2f seconds", work->info->run_time);
205 } else {
206 snprintf(buf, 80,"| runtime: %4.2f milliseconds", work->info->run_time*1000);
207 characters_runtime = strlen(buf);
208 qpalm_print("%s", buf);
209 // characters_runtime = qpalm_print("| runtime: %4.2f milliseconds", work->info->run_time*1000);
210 }
211 for (; characters_runtime < characters_box-2; characters_runtime++) {
212 qpalm_print(" ");
213 }
214 qpalm_print("|\n");
215 #endif
216
217 qpalm_print("=============================================================\n");
218 qpalm_print("\n\n");
219}
220
221#endif //Printing
222
223/*******************
224* Timer Functions *
225*******************/
226
227#ifdef QPALM_TIMING
228
229// Windows
230# ifdef _WIN32
231
232void qpalm_tic(QPALMTimer *t)
233{
234 QueryPerformanceFrequency(&t->freq);
235 QueryPerformanceCounter(&t->tic);
236}
237
239{
240 QueryPerformanceCounter(&t->toc);
241 return (t->toc.QuadPart - t->tic.QuadPart) / (c_float)t->freq.QuadPart;
242}
243
244// Mac
245# elif defined __APPLE__
246
247void qpalm_tic(QPALMTimer *t)
248{
249 /* read current clock cycles */
250 t->tic = mach_absolute_time();
251}
252
254{
255 uint64_t duration; /* elapsed time in clock cycles*/
256
257 t->toc = mach_absolute_time();
258 duration = t->toc - t->tic;
259
260 /*conversion from clock cycles to nanoseconds*/
261 mach_timebase_info(&(t->tinfo));
262 duration *= t->tinfo.numer;
263 duration /= t->tinfo.denom;
264
265 return (c_float)duration / 1e9;
266}
267
268// Mac
269# elif defined __MACH__
270
271void qpalm_tic(QPALMTimer *t)
272{
273 /* read current clock cycles */
274 t->tic = mach_absolute_time();
275}
276
278{
279 uint64_t duration; /* elapsed time in clock cycles*/
280
281 t->toc = mach_absolute_time();
282 duration = t->toc - t->tic;
283
284 /*conversion from clock cycles to nanoseconds*/
285 mach_timebase_info(&(t->tinfo));
286 duration *= t->tinfo.numer;
287 duration /= t->tinfo.denom;
288
289 return (c_float)duration / 1e9;
290}
291
292// Linux
293# elif defined __linux__ /* ifdef _WIN32 */
294/* read current time */
295
296void qpalm_tic(QPALMTimer *t)
297{
298 clock_gettime(CLOCK_MONOTONIC, &t->tic);
299}
300
301/* return time passed since last call to tic on this timer */
303{
304 struct timespec temp;
305
306 clock_gettime(CLOCK_MONOTONIC, &t->toc);
307
308 if ((t->toc.tv_nsec - t->tic.tv_nsec) < 0) {
309 temp.tv_sec = t->toc.tv_sec - t->tic.tv_sec - 1;
310 temp.tv_nsec = 1000000000 + t->toc.tv_nsec - t->tic.tv_nsec;
311 } else {
312 temp.tv_sec = t->toc.tv_sec - t->tic.tv_sec;
313 temp.tv_nsec = t->toc.tv_nsec - t->tic.tv_nsec;
314 }
315 return (c_float)temp.tv_sec + (c_float)temp.tv_nsec / 1e9;
316}
317
318# endif /* ifdef IS_WINDOWS */
319
320#endif // If Profiling end
#define QPALM_MAX_ITER_REACHED
status to indicate termination due to reaching the maximum number of iterations
Definition constants.h:32
#define QPALM_USER_CANCELLATION
status to indicate the user has cancelled the solve
Definition constants.h:36
#define QPALM_ERROR
status to indicate an error has occured (this error should automatically be printed)
Definition constants.h:38
#define QPALM_DUAL_INFEASIBLE
status to indicate the problem is dual infeasible
Definition constants.h:34
#define QPALM_TIME_LIMIT_REACHED
status to indicate the problem's runtime has exceeded the specified time limit
Definition constants.h:35
#define QPALM_PRIMAL_INFEASIBLE
status to indicate the problem is primal infeasible
Definition constants.h:33
#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 QPALM_UNSOLVED
status to indicate the problem is unsolved.
Definition constants.h:37
void * qpalm_malloc(size_t size)
Definition global_opts.c:7
Custom memory allocation, print and utility functions, and data types for floats and ints.
ladel_int c_int
type for integer numbers
Definition global_opts.h:42
#define qpalm_print
Definition global_opts.h:75
ladel_double c_float
type for floating point numbers
Definition global_opts.h:41
#define qpalm_eprint(...)
Definition global_opts.h:81
Linear algebra with vectors.
Solver return information.
Definition types.h:81
c_float run_time
total time (seconds)
Definition types.h:97
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
char status[32]
status string, e.g. 'solved'
Definition types.h:84
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 dua_res_norm
norm of dual residual
Definition types.h:88
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
QPALM Workspace.
Definition types.h:204
c_float eps_pri
primal tolerance
Definition types.h:275
QPALMInfo * info
solver information
Definition types.h:315
c_float tau
stepsize
Definition types.h:252
c_float eps_dua
dual tolerance
Definition types.h:276
QPALMSettings * settings
problem settings
Definition types.h:312
Internal data structures used in QPALM.
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 c_strcpy(char dest[], const char source[])
Custom string copy to avoid string.h library.
Definition util.c:19
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.