Skip to content

Commit cad53ad

Browse files
authored
Plumb complex cone through (#166)
* plumb through complex cone
1 parent bfdece1 commit cad53ad

6 files changed

Lines changed: 37 additions & 5 deletions

scs/scsobject.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ static void free_py_scs_data(ScsData *d, ScsCone *k, ScsSettings *stgs,
235235
if (k->s) {
236236
scs_free(k->s);
237237
}
238+
if (k->cs) {
239+
scs_free(k->cs);
240+
}
238241
if (k->p) {
239242
scs_free(k->p);
240243
}
@@ -498,6 +501,10 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
498501
free_py_scs_data(d, k, stgs, &ps);
499502
return finish_with_error("Failed to parse cone field s");
500503
}
504+
if (get_cone_arr_dim("cs", &(k->cs), &(k->cssize), cone) < 0) {
505+
free_py_scs_data(d, k, stgs, &ps);
506+
return finish_with_error("Failed to parse cone field cs");
507+
}
501508
if (get_cone_float_arr("p", &(k->p), &(k->psize), cone) < 0) {
502509
free_py_scs_data(d, k, stgs, &ps);
503510
return finish_with_error("failed to parse cone field p");

test/gen_random_cone_prob.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,14 +250,14 @@ def project_exp_bisection(v):
250250

251251
x = np.copy(v)
252252
ub, lb = get_rho_ub(v)
253-
for iter in range(0, 100):
253+
for iter in range(0, 200):
254254
rho = (ub + lb) / 2
255255
g, x = calc_grad(v, rho, x)
256256
if g > 0:
257257
lb = rho
258258
else:
259259
ub = rho
260-
if ub - lb < 1e-6:
260+
if ub - lb < 1e-9:
261261
break
262262
return x
263263

test/test_mix_sd_csd_cone.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import numpy as np
2+
import scs
3+
import scipy
4+
import pytest
5+
6+
def gen_feasible(m, n, p_scale = 0.1):
7+
P = p_scale * scipy.sparse.eye(n, format="csc")
8+
A = scipy.sparse.random(m, n, density=0.05, format="csc")
9+
c = np.random.randn(n)
10+
b = np.random.randn(m)
11+
12+
return (P, A, b, c)
13+
14+
15+
@pytest.mark.parametrize("use_indirect", [False, True])
16+
def test_mix_sd_csd_cones(use_indirect):
17+
seed = 1234
18+
np.random.seed(seed)
19+
cone = dict(z=1, l=2, s=[3, 4], cs=[5, 4])
20+
m = int(cone['z'] + cone['l'] + sum([j * (j+1) / 2 for j in cone['s']]) + sum([j * j for j in cone['cs']]))
21+
n = m
22+
(P, A, b, c) = gen_feasible(m, n)
23+
probdata = dict(P=P, A=A, b=b, c=c)
24+
sol = scs.solve(probdata, cone, use_indirect=use_indirect)
25+
np.testing.assert_equal(sol['info']['status'], 'solved')

test/test_solve_random_cone_prob.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def import_error(msg):
4242
"p": [-0.25, 0.5, 0.75, -0.33],
4343
}
4444
m = tools.get_scs_cone_dims(K)
45-
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
45+
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}
4646

4747

4848
@pytest.mark.parametrize("use_indirect,gpu", flags)

test/test_solve_random_cone_prob_cudss.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def import_error(msg):
3434
"p": [-0.25, 0.5, 0.75, -0.33],
3535
}
3636
m = tools.get_scs_cone_dims(K)
37-
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
37+
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}
3838

3939

4040
try:

test/test_solve_random_cone_prob_mkl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def import_error(msg):
3434
"p": [-0.25, 0.5, 0.75, -0.33],
3535
}
3636
m = tools.get_scs_cone_dims(K)
37-
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
37+
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}
3838

3939

4040
try:

0 commit comments

Comments
 (0)