scs 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/LICENSE.txt +1 -1
- data/lib/scs/version.rb +1 -1
- data/vendor/scs/CITATION.cff +1 -1
- data/vendor/scs/CMakeLists.txt +1 -1
- data/vendor/scs/README.md +1 -2
- data/vendor/scs/include/cones.h +2 -2
- data/vendor/scs/include/glbopts.h +9 -15
- data/vendor/scs/include/util.h +1 -0
- data/vendor/scs/scs.mk +1 -1
- data/vendor/scs/src/cones.c +566 -773
- data/vendor/scs/src/exp_cone.c +105 -83
- data/vendor/scs/src/linalg.c +6 -0
- data/vendor/scs/src/scs.c +1 -1
- metadata +2 -2
data/vendor/scs/src/exp_cone.c
CHANGED
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
#define EXP_CONE_INFINITY_VALUE (1E15)
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
|
-
* Exponential cone projection routines,
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* by Henrik A. Friberg, 2021.
|
|
13
|
-
*
|
|
9
|
+
* Exponential cone projection routines, based on:
|
|
10
|
+
* "Projection onto the exponential cone: a univariate root-finding problem"
|
|
11
|
+
* by Henrik A. Friberg, 2021.
|
|
14
12
|
*/
|
|
15
13
|
|
|
16
14
|
static inline scs_int _isfinite(scs_float x) {
|
|
@@ -21,16 +19,24 @@ static inline scs_float _clip(scs_float x, scs_float l, scs_float u) {
|
|
|
21
19
|
return MAX(l, MIN(u, x));
|
|
22
20
|
}
|
|
23
21
|
|
|
22
|
+
static inline void _copy(scs_float *dest, const scs_float *src) {
|
|
23
|
+
dest[0] = src[0];
|
|
24
|
+
dest[1] = src[1];
|
|
25
|
+
dest[2] = src[2];
|
|
26
|
+
}
|
|
27
|
+
|
|
24
28
|
/* As defined in Friberg, 2021 (multiplied by positive polynomial) */
|
|
25
29
|
static void hfun(const scs_float *v0, scs_float rho, scs_float *f,
|
|
26
30
|
scs_float *df) {
|
|
27
31
|
scs_float t0 = v0[2], s0 = v0[1], r0 = v0[0];
|
|
28
|
-
scs_float exprho =
|
|
29
|
-
scs_float expnegrho =
|
|
30
|
-
|
|
32
|
+
scs_float exprho = EXPF(rho);
|
|
33
|
+
scs_float expnegrho = EXPF(-rho);
|
|
34
|
+
|
|
35
|
+
/* Function value at v0 */
|
|
31
36
|
*f = ((rho - 1) * r0 + s0) * exprho - (r0 - rho * s0) * expnegrho -
|
|
32
37
|
(rho * (rho - 1) + 1) * t0;
|
|
33
|
-
|
|
38
|
+
|
|
39
|
+
/* Gradient of function at v0 */
|
|
34
40
|
*df = (rho * r0 + s0) * exprho + (r0 - (rho - 1) * s0) * expnegrho -
|
|
35
41
|
(2 * rho - 1) * t0;
|
|
36
42
|
}
|
|
@@ -38,23 +44,28 @@ static void hfun(const scs_float *v0, scs_float rho, scs_float *f,
|
|
|
38
44
|
/* Binary search for the root of the hfun function */
|
|
39
45
|
static scs_float root_search_binary(const scs_float *v0, scs_float xl,
|
|
40
46
|
scs_float xu, scs_float x) {
|
|
41
|
-
|
|
42
|
-
scs_printf("Exp cone: Newton method failed, resorting to binary search.\n");
|
|
43
|
-
#endif
|
|
44
|
-
const scs_float EPS = 1e-12; /* expensive so loosen tol */
|
|
47
|
+
const scs_float EPS = 1e-12; /* looser tolerance for binary search */
|
|
45
48
|
const scs_int MAXITER = 40;
|
|
46
49
|
scs_int i;
|
|
47
50
|
scs_float x_plus = x, f, df;
|
|
51
|
+
|
|
52
|
+
#if VERBOSITY > 0
|
|
53
|
+
scs_printf("Exp cone: Newton method failed, resorting to binary search.\n");
|
|
54
|
+
#endif
|
|
55
|
+
|
|
48
56
|
for (i = 0; i < MAXITER; i++) {
|
|
49
57
|
hfun(v0, x, &f, &df);
|
|
58
|
+
|
|
50
59
|
if (f < 0.0) {
|
|
51
60
|
xl = x;
|
|
52
61
|
} else {
|
|
53
62
|
xu = x;
|
|
54
63
|
}
|
|
55
|
-
|
|
64
|
+
|
|
65
|
+
/* Binary search step */
|
|
56
66
|
x_plus = 0.5 * (xl + xu);
|
|
57
|
-
|
|
67
|
+
|
|
68
|
+
if (ABS(x_plus - x) <= EPS * MAX(1.0, ABS(x_plus)) || (x_plus == xl) ||
|
|
58
69
|
(x_plus == xu)) {
|
|
59
70
|
break;
|
|
60
71
|
}
|
|
@@ -63,10 +74,10 @@ static scs_float root_search_binary(const scs_float *v0, scs_float xl,
|
|
|
63
74
|
return x_plus;
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
/* Use damped Newton's to find the root of the hfun function */
|
|
77
|
+
/* Use damped Newton's method to find the root of the hfun function */
|
|
67
78
|
static scs_float root_search_newton(const scs_float *v0, scs_float xl,
|
|
68
79
|
scs_float xu, scs_float x) {
|
|
69
|
-
/*
|
|
80
|
+
/* Paraameters taken from Friberg code. */
|
|
70
81
|
const scs_float EPS = 1e-15;
|
|
71
82
|
const scs_float DFTOL = 1e-13; /* pow(EPS, 6.0 / 7.0) */
|
|
72
83
|
const scs_int MAXITER = 20;
|
|
@@ -83,18 +94,21 @@ static scs_float root_search_newton(const scs_float *v0, scs_float xl,
|
|
|
83
94
|
break;
|
|
84
95
|
}
|
|
85
96
|
|
|
97
|
+
/* Update bounds */
|
|
86
98
|
if (f < 0.0) {
|
|
87
99
|
xl = x;
|
|
88
100
|
} else {
|
|
89
101
|
xu = x;
|
|
90
102
|
}
|
|
91
103
|
|
|
104
|
+
/* If bracket collapsed */
|
|
92
105
|
if (xu <= xl) {
|
|
93
106
|
xu = 0.5 * (xu + xl);
|
|
94
107
|
xl = xu;
|
|
95
108
|
break;
|
|
96
109
|
}
|
|
97
110
|
|
|
111
|
+
/* Check for flat gradient or infinity */
|
|
98
112
|
if (!_isfinite(f) || df < DFTOL) {
|
|
99
113
|
break;
|
|
100
114
|
}
|
|
@@ -102,10 +116,11 @@ static scs_float root_search_newton(const scs_float *v0, scs_float xl,
|
|
|
102
116
|
/* Newton step */
|
|
103
117
|
x_plus = x - f / df;
|
|
104
118
|
|
|
105
|
-
if (ABS(x_plus - x) <= EPS * MAX(1
|
|
119
|
+
if (ABS(x_plus - x) <= EPS * MAX(1.0, ABS(x_plus))) {
|
|
106
120
|
break;
|
|
107
121
|
}
|
|
108
122
|
|
|
123
|
+
/* Damped update with projection onto bounds */
|
|
109
124
|
if (x_plus >= xu) {
|
|
110
125
|
x = MIN(LODAMP * x + HIDAMP * xu, xu);
|
|
111
126
|
} else if (x_plus <= xl) {
|
|
@@ -114,30 +129,33 @@ static scs_float root_search_newton(const scs_float *v0, scs_float xl,
|
|
|
114
129
|
x = x_plus;
|
|
115
130
|
}
|
|
116
131
|
}
|
|
132
|
+
|
|
117
133
|
if (i < MAXITER) { /* Newton's method converged */
|
|
118
134
|
#if VERBOSITY > 0
|
|
119
135
|
scs_printf("Exp cone: Newton iters:%i, f:%.4e, df:%.4e\n", (int)i, f, df);
|
|
120
136
|
#endif
|
|
121
137
|
return _clip(x, xl, xu);
|
|
122
138
|
}
|
|
139
|
+
|
|
123
140
|
/* Fall back to binary search if Newton failed */
|
|
124
141
|
return root_search_binary(v0, xl, xu, x);
|
|
125
142
|
}
|
|
126
143
|
|
|
127
|
-
/*
|
|
144
|
+
/* Try heuristic (cheap) projection for primal cone */
|
|
128
145
|
static scs_float proj_primal_exp_cone_heuristic(const scs_float *v0,
|
|
129
146
|
scs_float *vp) {
|
|
130
147
|
scs_float t0 = v0[2], s0 = v0[1], r0 = v0[0];
|
|
131
148
|
scs_float dist, tp, newdist;
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
|
|
150
|
+
/* Perspective boundary */
|
|
151
|
+
vp[2] = MAX(t0, 0.0);
|
|
134
152
|
vp[1] = 0.0;
|
|
135
|
-
vp[0] = MIN(r0, 0);
|
|
153
|
+
vp[0] = MIN(r0, 0.0);
|
|
136
154
|
dist = SCS(norm_diff)(v0, vp, 3);
|
|
137
155
|
|
|
138
|
-
/*
|
|
156
|
+
/* Perspective interior */
|
|
139
157
|
if (s0 > 0.0) {
|
|
140
|
-
tp = MAX(t0, s0 *
|
|
158
|
+
tp = MAX(t0, s0 * EXPF(r0 / s0));
|
|
141
159
|
newdist = tp - t0;
|
|
142
160
|
if (newdist < dist) {
|
|
143
161
|
vp[2] = tp;
|
|
@@ -149,20 +167,21 @@ static scs_float proj_primal_exp_cone_heuristic(const scs_float *v0,
|
|
|
149
167
|
return dist;
|
|
150
168
|
}
|
|
151
169
|
|
|
152
|
-
/*
|
|
170
|
+
/* Try heuristic (cheap) projection for polar cone */
|
|
153
171
|
static scs_float proj_polar_exp_cone_heuristic(const scs_float *v0,
|
|
154
172
|
scs_float *vd) {
|
|
155
173
|
scs_float t0 = v0[2], s0 = v0[1], r0 = v0[0];
|
|
156
174
|
scs_float dist, td, newdist;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
vd[
|
|
175
|
+
|
|
176
|
+
/* Perspective boundary */
|
|
177
|
+
vd[2] = MIN(t0, 0.0);
|
|
178
|
+
vd[1] = MIN(s0, 0.0);
|
|
160
179
|
vd[0] = 0.0;
|
|
161
180
|
dist = SCS(norm_diff)(v0, vd, 3);
|
|
162
181
|
|
|
163
|
-
/*
|
|
182
|
+
/* Perspective interior */
|
|
164
183
|
if (r0 > 0.0) {
|
|
165
|
-
td = MIN(t0, -r0 *
|
|
184
|
+
td = MIN(t0, -r0 * EXPF(s0 / r0 - 1.0));
|
|
166
185
|
newdist = t0 - td;
|
|
167
186
|
if (newdist < dist) {
|
|
168
187
|
vd[2] = td;
|
|
@@ -179,21 +198,20 @@ static scs_float ppsi(const scs_float *v0) {
|
|
|
179
198
|
scs_float psi;
|
|
180
199
|
|
|
181
200
|
if (r0 > s0) {
|
|
182
|
-
psi = (r0 - s0 +
|
|
201
|
+
psi = (r0 - s0 + SQRTF(r0 * r0 + s0 * s0 - r0 * s0)) / r0;
|
|
183
202
|
} else {
|
|
184
|
-
psi = -s0 / (r0 - s0 -
|
|
203
|
+
psi = -s0 / (r0 - s0 - SQRTF(r0 * r0 + s0 * s0 - r0 * s0));
|
|
185
204
|
}
|
|
186
205
|
|
|
187
|
-
return ((psi - 1) * r0 + s0) / (psi * (psi - 1) + 1);
|
|
206
|
+
return ((psi - 1.0) * r0 + s0) / (psi * (psi - 1.0) + 1.0);
|
|
188
207
|
}
|
|
189
208
|
|
|
190
209
|
static scs_float pomega(scs_float rho) {
|
|
191
|
-
scs_float val =
|
|
210
|
+
scs_float val = EXPF(rho) / (rho * (rho - 1.0) + 1.0);
|
|
192
211
|
|
|
193
212
|
if (rho < 2.0) {
|
|
194
|
-
val = MIN(val,
|
|
213
|
+
val = MIN(val, EXPF(2.0) / 3.0);
|
|
195
214
|
}
|
|
196
|
-
|
|
197
215
|
return val;
|
|
198
216
|
}
|
|
199
217
|
|
|
@@ -202,21 +220,20 @@ static scs_float dpsi(const scs_float *v0) {
|
|
|
202
220
|
scs_float psi;
|
|
203
221
|
|
|
204
222
|
if (s0 > r0) {
|
|
205
|
-
psi = (r0 -
|
|
223
|
+
psi = (r0 - SQRTF(r0 * r0 + s0 * s0 - r0 * s0)) / s0;
|
|
206
224
|
} else {
|
|
207
|
-
psi = (r0 - s0) / (r0 +
|
|
225
|
+
psi = (r0 - s0) / (r0 + SQRTF(r0 * r0 + s0 * s0 - r0 * s0));
|
|
208
226
|
}
|
|
209
227
|
|
|
210
|
-
return (r0 - psi * s0) / (psi * (psi - 1) + 1);
|
|
228
|
+
return (r0 - psi * s0) / (psi * (psi - 1.0) + 1.0);
|
|
211
229
|
}
|
|
212
230
|
|
|
213
231
|
static scs_float domega(scs_float rho) {
|
|
214
|
-
scs_float val = -
|
|
232
|
+
scs_float val = -EXPF(-rho) / (rho * (rho - 1.0) + 1.0);
|
|
215
233
|
|
|
216
234
|
if (rho > -1.0) {
|
|
217
|
-
val = MAX(val, -
|
|
235
|
+
val = MAX(val, -EXPF(1.0) / 3.0);
|
|
218
236
|
}
|
|
219
|
-
|
|
220
237
|
return val;
|
|
221
238
|
}
|
|
222
239
|
|
|
@@ -225,41 +242,46 @@ static void exp_search_bracket(const scs_float *v0, scs_float pdist,
|
|
|
225
242
|
scs_float ddist, scs_float *low_out,
|
|
226
243
|
scs_float *upr_out) {
|
|
227
244
|
scs_float t0 = v0[2], s0 = v0[1], r0 = v0[0];
|
|
228
|
-
scs_float baselow = -EXP_CONE_INFINITY_VALUE
|
|
229
|
-
|
|
230
|
-
scs_float low = -EXP_CONE_INFINITY_VALUE
|
|
231
|
-
|
|
232
|
-
scs_float Dp
|
|
233
|
-
scs_float Dd = SQRTF(ddist * ddist - MIN(r0, 0) * MIN(r0, 0));
|
|
245
|
+
scs_float baselow = -EXP_CONE_INFINITY_VALUE;
|
|
246
|
+
scs_float baseupr = EXP_CONE_INFINITY_VALUE;
|
|
247
|
+
scs_float low = -EXP_CONE_INFINITY_VALUE;
|
|
248
|
+
scs_float upr = EXP_CONE_INFINITY_VALUE;
|
|
249
|
+
scs_float Dp, Dd, curbnd, fl, fu, df, tpu, tdl, sgn, val;
|
|
234
250
|
|
|
235
|
-
|
|
251
|
+
Dp = SQRTF(pdist * pdist - MIN(s0, 0.0) * MIN(s0, 0.0));
|
|
252
|
+
Dd = SQRTF(ddist * ddist - MIN(r0, 0.0) * MIN(r0, 0.0));
|
|
236
253
|
|
|
237
|
-
if (t0 > 0) {
|
|
238
|
-
curbnd =
|
|
254
|
+
if (t0 > 0.0) {
|
|
255
|
+
curbnd = LOGF(t0 / ppsi(v0));
|
|
239
256
|
low = MAX(low, curbnd);
|
|
240
|
-
} else if (t0 < 0) {
|
|
241
|
-
curbnd = -
|
|
257
|
+
} else if (t0 < 0.0) {
|
|
258
|
+
curbnd = -LOGF(-t0 / dpsi(v0));
|
|
242
259
|
upr = MIN(upr, curbnd);
|
|
243
260
|
}
|
|
244
261
|
|
|
245
|
-
if (r0 > 0) {
|
|
246
|
-
baselow = 1 - s0 / r0;
|
|
262
|
+
if (r0 > 0.0) {
|
|
263
|
+
baselow = 1.0 - s0 / r0;
|
|
247
264
|
low = MAX(low, baselow);
|
|
248
265
|
tpu = MAX(1e-12, MIN(Dd, Dp + t0));
|
|
249
|
-
|
|
266
|
+
val = r0 * pomega(low);
|
|
267
|
+
sgn = val < 0 ? -1 : 1;
|
|
268
|
+
curbnd = MAX(low, baselow + SAFEDIV_POS(tpu, ABS(val)) * sgn);
|
|
250
269
|
upr = MIN(upr, curbnd);
|
|
251
270
|
}
|
|
252
271
|
|
|
253
|
-
if (s0 > 0) {
|
|
272
|
+
if (s0 > 0.0) {
|
|
254
273
|
baseupr = r0 / s0;
|
|
255
274
|
upr = MIN(upr, baseupr);
|
|
256
275
|
tdl = -MAX(1e-12, MIN(Dp, Dd - t0));
|
|
257
|
-
|
|
276
|
+
val = s0 * domega(upr);
|
|
277
|
+
sgn = val < 0 ? -1 : 1;
|
|
278
|
+
curbnd = MIN(upr, baseupr - SAFEDIV_POS(tdl, ABS(val)) * sgn);
|
|
258
279
|
low = MAX(low, curbnd);
|
|
259
280
|
}
|
|
260
281
|
|
|
261
|
-
/* Guarantee valid bracket
|
|
262
|
-
|
|
282
|
+
/* Guarantee valid bracket. Floating point errors can push bounds
|
|
283
|
+
* slightly outside base interval or flip low/upr.
|
|
284
|
+
*/
|
|
263
285
|
low = _clip(MIN(low, upr), baselow, baseupr);
|
|
264
286
|
upr = _clip(MAX(low, upr), baselow, baseupr);
|
|
265
287
|
|
|
@@ -267,7 +289,7 @@ static void exp_search_bracket(const scs_float *v0, scs_float pdist,
|
|
|
267
289
|
hfun(v0, low, &fl, &df);
|
|
268
290
|
hfun(v0, upr, &fu, &df);
|
|
269
291
|
|
|
270
|
-
if (fl * fu > 0) {
|
|
292
|
+
if (fl * fu > 0.0) {
|
|
271
293
|
if (ABS(fl) < ABS(fu)) {
|
|
272
294
|
upr = low;
|
|
273
295
|
} else {
|
|
@@ -283,11 +305,12 @@ static void exp_search_bracket(const scs_float *v0, scs_float pdist,
|
|
|
283
305
|
/* convert from rho to primal projection */
|
|
284
306
|
static scs_float proj_sol_primal_exp_cone(const scs_float *v0, scs_float rho,
|
|
285
307
|
scs_float *vp) {
|
|
286
|
-
scs_float linrho = (rho - 1) * v0[0] + v0[1];
|
|
287
|
-
scs_float exprho =
|
|
308
|
+
scs_float linrho = (rho - 1.0) * v0[0] + v0[1];
|
|
309
|
+
scs_float exprho = EXPF(rho);
|
|
288
310
|
scs_float quadrho, dist;
|
|
289
|
-
|
|
290
|
-
|
|
311
|
+
|
|
312
|
+
if (linrho > 0.0 && _isfinite(exprho)) {
|
|
313
|
+
quadrho = rho * (rho - 1.0) + 1.0;
|
|
291
314
|
vp[2] = exprho * linrho / quadrho;
|
|
292
315
|
vp[1] = linrho / quadrho;
|
|
293
316
|
vp[0] = rho * linrho / quadrho;
|
|
@@ -305,12 +328,13 @@ static scs_float proj_sol_primal_exp_cone(const scs_float *v0, scs_float rho,
|
|
|
305
328
|
static scs_float proj_sol_polar_exp_cone(const scs_float *v0, scs_float rho,
|
|
306
329
|
scs_float *vd) {
|
|
307
330
|
scs_float linrho = v0[0] - rho * v0[1];
|
|
308
|
-
scs_float exprho =
|
|
331
|
+
scs_float exprho = EXPF(-rho);
|
|
309
332
|
scs_float quadrho, dist;
|
|
310
|
-
|
|
311
|
-
|
|
333
|
+
|
|
334
|
+
if (linrho > 0.0 && _isfinite(exprho)) {
|
|
335
|
+
quadrho = rho * (rho - 1.0) + 1.0;
|
|
312
336
|
vd[2] = -exprho * linrho / quadrho;
|
|
313
|
-
vd[1] = (1 - rho) * linrho / quadrho;
|
|
337
|
+
vd[1] = (1.0 - rho) * linrho / quadrho;
|
|
314
338
|
vd[0] = linrho / quadrho;
|
|
315
339
|
dist = SCS(norm_diff)(v0, vd, 3);
|
|
316
340
|
} else {
|
|
@@ -322,12 +346,6 @@ static scs_float proj_sol_polar_exp_cone(const scs_float *v0, scs_float rho,
|
|
|
322
346
|
return dist;
|
|
323
347
|
}
|
|
324
348
|
|
|
325
|
-
static inline void _copy(scs_float *dest, scs_float *src) {
|
|
326
|
-
dest[0] = src[0];
|
|
327
|
-
dest[1] = src[1];
|
|
328
|
-
dest[2] = src[2];
|
|
329
|
-
}
|
|
330
|
-
|
|
331
349
|
/* Project onto primal or dual exponential cone, performed in-place.
|
|
332
350
|
* If `primal=0` then project on the dual cone, otherwise project
|
|
333
351
|
* onto primal. Taken from algorithm in Friberg, 2021.
|
|
@@ -337,14 +355,15 @@ scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal) {
|
|
|
337
355
|
scs_float xl, xh, pdist, ddist, err, rho, dist_hat;
|
|
338
356
|
scs_float vp[3], vd[3], v_hat[3];
|
|
339
357
|
scs_int opt;
|
|
358
|
+
|
|
340
359
|
if (!primal) {
|
|
341
360
|
/* This routine actually projects onto primal and polar cones
|
|
342
361
|
* simultaneously. So to make it project onto dual, use this:
|
|
343
362
|
* Pi_{C^*}(v0) = -Pi_{C^polar}(-v0)
|
|
344
363
|
*/
|
|
345
|
-
v0[0] *= -1
|
|
346
|
-
v0[1] *= -1
|
|
347
|
-
v0[2] *= -1
|
|
364
|
+
v0[0] *= -1.0;
|
|
365
|
+
v0[1] *= -1.0;
|
|
366
|
+
v0[2] *= -1.0;
|
|
348
367
|
}
|
|
349
368
|
|
|
350
369
|
pdist = proj_primal_exp_cone_heuristic(v0, vp);
|
|
@@ -357,15 +376,16 @@ scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal) {
|
|
|
357
376
|
/* Skip root search if presolve rules apply
|
|
358
377
|
* or optimality conditions are satisfied
|
|
359
378
|
*/
|
|
360
|
-
opt = (v0[1] <= 0 && v0[0] <= 0);
|
|
379
|
+
opt = (v0[1] <= 0.0 && v0[0] <= 0.0);
|
|
361
380
|
opt |= (MIN(pdist, ddist) <= TOL);
|
|
362
381
|
opt |= (err <= TOL && SCS(dot)(vp, vd, 3) <= TOL);
|
|
382
|
+
|
|
363
383
|
if (opt) {
|
|
364
384
|
if (primal) {
|
|
365
385
|
_copy(v0, vp);
|
|
366
386
|
return pdist;
|
|
367
387
|
}
|
|
368
|
-
/*
|
|
388
|
+
/* Polar cone -> dual cone. */
|
|
369
389
|
v0[0] = -vd[0];
|
|
370
390
|
v0[1] = -vd[1];
|
|
371
391
|
v0[2] = -vd[2];
|
|
@@ -376,7 +396,7 @@ scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal) {
|
|
|
376
396
|
rho = root_search_newton(v0, xl, xh, 0.5 * (xl + xh));
|
|
377
397
|
|
|
378
398
|
if (primal) {
|
|
379
|
-
/*
|
|
399
|
+
/* Primal cone projection. */
|
|
380
400
|
dist_hat = proj_sol_primal_exp_cone(v0, rho, v_hat);
|
|
381
401
|
if (dist_hat <= pdist) {
|
|
382
402
|
_copy(vp, v_hat);
|
|
@@ -385,13 +405,15 @@ scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal) {
|
|
|
385
405
|
_copy(v0, vp);
|
|
386
406
|
return pdist;
|
|
387
407
|
}
|
|
388
|
-
|
|
408
|
+
|
|
409
|
+
/* Polar cone projection. */
|
|
389
410
|
dist_hat = proj_sol_polar_exp_cone(v0, rho, v_hat);
|
|
390
411
|
if (dist_hat <= ddist) {
|
|
391
412
|
_copy(vd, v_hat);
|
|
392
413
|
ddist = dist_hat;
|
|
393
414
|
}
|
|
394
|
-
|
|
415
|
+
|
|
416
|
+
/* Polar cone -> dual cone. */
|
|
395
417
|
v0[0] = -vd[0];
|
|
396
418
|
v0[1] = -vd[1];
|
|
397
419
|
v0[2] = -vd[2];
|
data/vendor/scs/src/linalg.c
CHANGED
|
@@ -86,6 +86,9 @@ void SCS(add_scaled_array)(scs_float *a, const scs_float *b, scs_int n,
|
|
|
86
86
|
scs_float SCS(mean)(const scs_float *x, scs_int n) {
|
|
87
87
|
scs_int i;
|
|
88
88
|
scs_float mean = 0.;
|
|
89
|
+
if (n == 0) {
|
|
90
|
+
return 0.;
|
|
91
|
+
}
|
|
89
92
|
for (i = 0; i < n; ++i) {
|
|
90
93
|
mean += x[i];
|
|
91
94
|
}
|
|
@@ -178,6 +181,9 @@ scs_float SCS(mean)(const scs_float *x, scs_int n) {
|
|
|
178
181
|
blas_int bzero = 0;
|
|
179
182
|
blas_int blen = (blas_int)n;
|
|
180
183
|
scs_float y = 1.0;
|
|
184
|
+
if (n == 0) {
|
|
185
|
+
return 0.;
|
|
186
|
+
}
|
|
181
187
|
return BLAS(dot)(&blen, x, &bone, &y, &bzero) / n;
|
|
182
188
|
}
|
|
183
189
|
|
data/vendor/scs/src/scs.c
CHANGED
|
@@ -900,7 +900,7 @@ static ScsWork *init_work(const ScsData *d, const ScsCone *k,
|
|
|
900
900
|
}
|
|
901
901
|
if (w->stgs->acceleration_lookback) {
|
|
902
902
|
/* TODO(HACK!) negative acceleration_lookback interpreted as type-II */
|
|
903
|
-
if (!(w->accel = aa_init(l,
|
|
903
|
+
if (!(w->accel = aa_init(l, abs(w->stgs->acceleration_lookback),
|
|
904
904
|
w->stgs->acceleration_lookback > 0,
|
|
905
905
|
w->stgs->acceleration_lookback > 0
|
|
906
906
|
? AA_REGULARIZATION_TYPE_1
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
@@ -169,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
169
169
|
- !ruby/object:Gem::Version
|
|
170
170
|
version: '0'
|
|
171
171
|
requirements: []
|
|
172
|
-
rubygems_version:
|
|
172
|
+
rubygems_version: 4.0.3
|
|
173
173
|
specification_version: 4
|
|
174
174
|
summary: SCS - the splitting conic solver - for Ruby
|
|
175
175
|
test_files: []
|