QPALM main
Proximal Augmented Lagrangian method for Quadratic Programs
Loading...
Searching...
No Matches
linesearch.c
Go to the documentation of this file.
1/**
2 * @file linesearch.c
3 * @author Ben Hermans
4 * @brief Routines to perform exact or backtracking linesearch.
5 * @details Once the direction is found using the semismooth Newton method, the functions in this file can
6 * be called to calculate a stepsize, either using exact linesearch or a backtracking linesearch to
7 * satisfy the armijo condition.
8 */
9
10#include <qpalm/linesearch.h>
11#include <qpalm/lin_alg.h>
12#include <stdlib.h> //for sorting
13
15 size_t n = work->data->n;
16 size_t m = work->data->m;
17 //Qd
18 mat_vec(work->data->Q, work->solver->d, work->solver->Qd, c);
19 if (work->settings->proximal) {
20 vec_add_scaled(work->Qd, work->d, work->Qd, 1/work->gamma, n);
21 }
22 //Ad
23 mat_vec(work->data->A, work->solver->d, work->solver->Ad, c);
24 //eta = d'*Qd
25 work->eta = vec_prod(work->d, work->Qd, n);
26 //beta = d'*df
27 work->beta = vec_prod(work->d, work->df, n);
28
29 //delta = [-sqrt(sigma).*Ad; sqrt(sigma).*Ad]
30 vec_ew_prod(work->sqrt_sigma, work->Ad, work->temp_m, m);
31 prea_vec_copy(work->temp_m, work->delta + m, m); //shifted copy
32 vec_self_mult_scalar(work->temp_m, -1, m);
33 prea_vec_copy(work->temp_m, work->delta, m);
34 //alpha = [(y+sigma.*(Ax-bmin))./sigma_sqrt; (-y+sigma.*(bmax-Ax))./sigma_sqrt]
35 vec_add_scaled(work->Ax, work->data->bmin, work->temp_m, -1, m);
36 vec_ew_prod(work->sigma, work->temp_m, work->temp_m, m);
37 vec_add_scaled(work->y, work->temp_m, work->temp_m, 1, m);
38 vec_ew_div(work->temp_m, work->sqrt_sigma, work->temp_m, m);
39 prea_vec_copy(work->temp_m, work->alpha, m);
40 vec_add_scaled(work->data->bmax, work->Ax, work->temp_m, -1, m);
41 vec_ew_prod(work->sigma, work->temp_m, work->temp_m, m);
42 vec_add_scaled(work->temp_m, work->y, work->temp_m, -1, m);
43 vec_ew_div(work->temp_m, work->sqrt_sigma, work->temp_m, m);
44 prea_vec_copy(work->temp_m, work->alpha + m, m); //shifted copy
45 // s = alpha./delta
46 vec_ew_div(work->alpha, work->delta, work->temp_2m, m*2);
47 vec_array_copy(work->temp_2m, work->s, m*2);
48 // index_L = s>0
49 size_t nL = 0;
50 size_t i;
51 for (i = 0; i<m*2; i++){
52 if (work->temp_2m[i] > 0) {
53 work->index_L[i] = TRUE;
54 nL++;
55 } else {
56 work->index_L[i] = FALSE;
57 }
58 };
59
60 //s = s(indL)
61 select_subsequence(work->s, work->s, work->index_L, m*2);
62
63 // index_P = delta > 0
64 for (i = 0; i<m*2; i++){
65 if (work->delta[i] > 0) {
66 work->index_P[i] = TRUE;
67 } else {
68 work->index_P[i] = FALSE;
69 }
70 };
71 // index_J = (P&~L)|(~P&L);
72 for (i = 0; i<m*2; i++){
73 if ((work->index_P[i] + work->index_L[i]) == 1) {
74 work->index_J[i] = TRUE;
75 } else {
76 work->index_J[i] = FALSE;
77 }
78 };
79
80 // a = eta+delta(J)'*delta(J);
81 // b = beta-delta(J)'*alpha(J);
82 c_float a, b;
83 a = work->eta + vec_prod_ind(work->delta, work->delta, work->index_J, m*2);
84 b = work->beta - vec_prod_ind(work->delta, work->alpha, work->index_J, m*2);
85 // return 0;
86 //s = sort(s)
87 // qsort(work->s, m*2, sizeof(array_element), compare);
88 qsort(work->s, nL, sizeof(array_element), compare);
89
90 if (nL == 0 || a*work->s[0].x+b > 0) {
91 return -b/a;
92 }
93
94 i = 0;
95 size_t iz;
96 while (i < nL-1) {
97 iz = work->s[i].i;
98 if (work->index_P[iz]) {
99 a = a + work->delta[iz]*work->delta[iz];
100 b = b - work->delta[iz]*work->alpha[iz];
101 } else {
102 a = a - work->delta[iz]*work->delta[iz];
103 b = b + work->delta[iz]*work->alpha[iz];
104 }
105 i++;
106 if (a*work->s[i].x+b > 0) {
107 return -b/a;
108 }
109 }
110 iz = work->s[i].i;
111 if (work->index_P[iz]) {
112 a = a + work->delta[iz]*work->delta[iz];
113 b = b - work->delta[iz]*work->alpha[iz];
114 } else {
115 a = a - work->delta[iz]*work->delta[iz];
116 b = b + work->delta[iz]*work->alpha[iz];
117 }
118 return -b/a;
119
120}
121
122void vec_array_copy(c_float *a, array_element* b, size_t n) {
123 size_t i;
124 array_element ae;
125
126 for (i = 0; i < n; i++) {
127 ae.x = a[i];
128 ae.i = i;
129 b[i] = ae;
130 }
131
132}
133
134void select_subsequence(const array_element *a, array_element *b, const c_int *L, size_t n) {
135 size_t i;
136 size_t nb_elements = 0;
137 for (i = 0; i < n; i++) {
138 if (L[i]) {
139 b[nb_elements] = a[i];
140 nb_elements++;
141 }
142 }
143}
144
145c_float vec_prod_ind(const c_float *a, const c_float *b, const c_int *L, size_t n) {
146 c_float prod = 0.0;
147 size_t i;
148
149 for (i = 0; i < n; i++) {
150 if (L[i]) {
151 prod += a[i] * b[i];
152 }
153 }
154
155 return prod;
156}
157
158int compare (const void * a, const void * b)
159{
160 c_float f = ((struct array_element*)a)->x;
161 c_float s = ((struct array_element*)b)->x;
162 if (f > s) return 1;
163 if (f < s) return -1;
164 return 0;
165
166}
#define TRUE
Definition constants.h:18
#define FALSE
Definition constants.h:19
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
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_ew_div(const c_float *a, const c_float *b, c_float *c, size_t n)
Elementwise division, .
Definition lin_alg.c:101
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
c_float vec_prod(const c_float *a, const c_float *b, size_t n)
Inner product between two vectors, .
Definition lin_alg.c:72
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.
void vec_array_copy(c_float *a, array_element *b, size_t n)
Helper function to copy vector a in array b (with indices)
Definition linesearch.c:122
void select_subsequence(const array_element *a, array_element *b, const c_int *L, size_t n)
Select subsequence based on a set of indices, .
Definition linesearch.c:134
c_float exact_linesearch(QPALMWorkspace *work, solver_common *c)
Execute exact linesearch (using qsort)
Definition linesearch.c:14
c_float vec_prod_ind(const c_float *a, const c_float *b, const c_int *L, size_t n)
Inner product over index set, .
Definition linesearch.c:145
int compare(const void *a, const void *b)
Helper function for qsort.
Definition linesearch.c:158
Routines to perform exact linesearch.
void mat_vec(solver_sparse *A, solver_dense *x, solver_dense *y, solver_common *c)
Matrix-vector multiplication.
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
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
c_int proximal
boolean, use proximal method of multipliers or not
Definition types.h:138
solver_dense * Ad
A * d.
Definition types.h:179
solver_dense * d
primal update step
Definition types.h:178
solver_dense * Qd
Q * d.
Definition types.h:180
QPALM Workspace.
Definition types.h:204
c_float eta
linesearch parameter
Definition types.h:257
c_float * y
dual iterate
Definition types.h:212
c_float * delta
linesearch parameter
Definition types.h:259
c_float * Ax
scaled A * x
Definition types.h:213
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
c_int * index_P
index set P (where delta>0)
Definition types.h:266
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 beta
linesearch parameter
Definition types.h:258
QPALMSettings * settings
problem settings
Definition types.h:312
c_float gamma
proximal penalty factor
Definition types.h:230
c_float * df
gradient of the primal objective (+proximal term)
Definition types.h:238
c_float * alpha
linesearch parameter
Definition types.h:260
QPALMSolver * solver
linsys variables
Definition types.h:311
c_float * temp_2m
placeholder for vector of size 2m
Definition types.h:261
c_float * Ad
A * d.
Definition types.h:254
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 * d
primal update step
Definition types.h:244
Array to sort in linesearch.
Definition types.h:34
size_t i
index
Definition types.h:36
c_float x
value of the element
Definition types.h:35
ladel_work solver_common
Definition types.h:25