Skip to content
Merged
20 changes: 14 additions & 6 deletions scs/scsobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ static void free_py_scs_data(ScsData *d, ScsCone *k, ScsSettings *stgs,
if (k->s) {
scs_free(k->s);
}
if (k->cs) {
scs_free(k->cs);
}
if (k->p) {
scs_free(k->p);
}
Expand Down Expand Up @@ -400,7 +403,8 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
d->A = A;

/* set P if passed in */
if ((void *)!Py_IsNone(Px) && (void *)!Py_IsNone(Pi) && (void *)!Py_IsNone(Pp)) {
if (!Py_IsNone((PyObject *)Px) && !Py_IsNone((PyObject *)Pi) &&
!Py_IsNone((PyObject *)Pp)) {
if (!PyArray_ISFLOAT(Px) || PyArray_NDIM(Px) != 1) {
free_py_scs_data(d, k, stgs, &ps);
return finish_with_error("Px must be a numpy array of floats");
Expand Down Expand Up @@ -497,6 +501,10 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
free_py_scs_data(d, k, stgs, &ps);
return finish_with_error("Failed to parse cone field s");
}
if (get_cone_arr_dim("cs", &(k->cs), &(k->cssize), cone) < 0) {
free_py_scs_data(d, k, stgs, &ps);
return finish_with_error("Failed to parse cone field cs");
}
if (get_cone_float_arr("p", &(k->p), &(k->psize), cone) < 0) {
free_py_scs_data(d, k, stgs, &ps);
return finish_with_error("failed to parse cone field p");
Expand Down Expand Up @@ -607,17 +615,17 @@ static PyObject *SCS_solve(SCS *self, PyObject *args) {

if (_warm_start) {
/* If any of these of missing, we use the values in sol */
if ((void *)!Py_IsNone(warm_x)) {
if (!Py_IsNone((PyObject *)warm_x)) {
if (get_warm_start(self->sol->x, self->n, warm_x) < 0) {
return none_with_error("Unable to parse x warm-start");
}
}
if ((void *)!Py_IsNone(warm_y)) {
if (!Py_IsNone((PyObject *)warm_y)) {
if (get_warm_start(self->sol->y, self->m, warm_y) < 0) {
return none_with_error("Unable to parse y warm-start");
}
}
if ((void *)!Py_IsNone(warm_s)) {
if (!Py_IsNone((PyObject *)warm_s)) {
if (get_warm_start(self->sol->s, self->m, warm_s) < 0) {
return none_with_error("Unable to parse s warm-start");
}
Expand Down Expand Up @@ -729,7 +737,7 @@ PyObject *SCS_update(SCS *self, PyObject *args) {
return none_with_error("Error parsing inputs");
}
/* set c */
if ((void *)!Py_IsNone(c_new)) {
if (!Py_IsNone((PyObject *)c_new)) {
if (!PyArray_ISFLOAT(c_new) || PyArray_NDIM(c_new) != 1) {
return none_with_error(
"c_new must be a dense numpy array with one dimension");
Expand All @@ -741,7 +749,7 @@ PyObject *SCS_update(SCS *self, PyObject *args) {
c = (scs_float *)PyArray_DATA(c_new);
}
/* set b */
if ((void *)!Py_IsNone(b_new)) {
if (!Py_IsNone((PyObject *)b_new)) {
if (!PyArray_ISFLOAT(b_new) || PyArray_NDIM(b_new) != 1) {
return none_with_error(
"b must be a dense numpy array with one dimension");
Expand Down
2 changes: 1 addition & 1 deletion scs_source
Submodule scs_source updated 2 files
+6 −0 include/glbopts.h
+1 −1 src/scs.c
4 changes: 2 additions & 2 deletions test/gen_random_cone_prob.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,14 @@ def project_exp_bisection(v):

x = np.copy(v)
ub, lb = get_rho_ub(v)
for iter in range(0, 100):
for iter in range(0, 200):
rho = (ub + lb) / 2
g, x = calc_grad(v, rho, x)
if g > 0:
lb = rho
else:
ub = rho
if ub - lb < 1e-6:
if ub - lb < 1e-9:
break
return x

Expand Down
25 changes: 25 additions & 0 deletions test/test_mix_sd_csd_cone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import numpy as np
import scs
import scipy
import pytest

def gen_feasible(m, n, p_scale = 0.1):
P = p_scale * scipy.sparse.eye(n, format="csc")
A = scipy.sparse.random(m, n, density=0.05, format="csc")
c = np.random.randn(n)
b = np.random.randn(m)

return (P, A, b, c)


@pytest.mark.parametrize("use_indirect", [False, True])
def test_mix_sd_csd_cones(use_indirect):
seed = 1234
np.random.seed(seed)
cone = dict(z=1, l=2, s=[3, 4], cs=[5, 4])
m = int(cone['z'] + cone['l'] + sum([j * (j+1) / 2 for j in cone['s']]) + sum([j * j for j in cone['cs']]))
n = m
(P, A, b, c) = gen_feasible(m, n)
probdata = dict(P=P, A=A, b=b, c=c)
sol = scs.solve(probdata, cone, use_indirect=use_indirect)
np.testing.assert_equal(sol['info']['status'], 'solved')
2 changes: 1 addition & 1 deletion test/test_solve_random_cone_prob.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def import_error(msg):
"p": [-0.25, 0.5, 0.75, -0.33],
}
m = tools.get_scs_cone_dims(K)
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}


@pytest.mark.parametrize("use_indirect,gpu", flags)
Expand Down
2 changes: 1 addition & 1 deletion test/test_solve_random_cone_prob_cudss.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def import_error(msg):
"p": [-0.25, 0.5, 0.75, -0.33],
}
m = tools.get_scs_cone_dims(K)
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}


try:
Expand Down
2 changes: 1 addition & 1 deletion test/test_solve_random_cone_prob_mkl.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def import_error(msg):
"p": [-0.25, 0.5, 0.75, -0.33],
}
m = tools.get_scs_cone_dims(K)
params = {"verbose": True, "eps_abs": 1e-5, "eps_rel": 1e-5, "eps_infeas": 1e-5}
params = {"verbose": True, "eps_abs": 1e-7, "eps_rel": 1e-7, "eps_infeas": 1e-7}


try:
Expand Down
Loading