From 5da2875f6d05dc74d1d3ccedd75495aeea110aaa Mon Sep 17 00:00:00 2001 From: Brendan O'Donoghue Date: Fri, 5 Jun 2026 11:41:56 +0100 Subject: [PATCH 1/2] Expose acceleration_trust_factor in Python bindings Plumbs the new ScsSettings.acceleration_trust_factor field through the Cython kwargs interface. Defaults to math.inf (no cap, matches current SCS HEAD behavior); positive finite values activate the trust-region + adaptive-r mode from the underlying aa library. Bumps scs_source submodule to pick up the C-side change. Validation rejects NaN and non-positive values. Adds coverage tests for the default, finite/inf sweep, and rejection cases. --- scs/scsobject.h | 20 ++++++++++++++++---- scs_source | 2 +- test/test_scs_coverage.py | 26 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/scs/scsobject.h b/scs/scsobject.h index ba2a66c..725b35a 100644 --- a/scs/scsobject.h +++ b/scs/scsobject.h @@ -490,6 +490,7 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) { "acceleration_type_1", "acceleration_regularization", "acceleration_relaxation", + "acceleration_trust_factor", "write_data_filename", "log_csv_filename", NULL}; @@ -499,15 +500,15 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) { on Windows where sizeof(long) < sizeof(long long) (LLP64 model). */ #ifdef DLONG #ifdef SFLOAT - char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LfffffffLLLffzz"; + char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LfffffffLLLfffzz"; #else - char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LdddddddLLLddzz"; + char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LdddddddLLLdddzz"; #endif #else #ifdef SFLOAT - char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!ifffffffiiiffzz"; + char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!ifffffffiiifffzz"; #else - char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!idddddddiiiddzz"; + char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!idddddddiiidddzz"; #endif #endif @@ -547,6 +548,7 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) { &(stgs->acceleration_type_1), &(stgs->acceleration_regularization), &(stgs->acceleration_relaxation), + &(stgs->acceleration_trust_factor), &(stgs->write_data_filename), &(stgs->log_csv_filename))) { /* PyArg_ParseTupleAndKeywords already set an informative TypeError @@ -835,6 +837,16 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) { free_py_scs_data(d, k, stgs, &ps); return finish_with_error("acceleration_relaxation must be in [0, 2]"); } + /* acceleration_trust_factor: INFINITY (default) disables; positive + * finite values turn on the trust-region + adaptive-r mode in aa. + * NaN and non-positive values are rejected. */ + if (isnan((double)stgs->acceleration_trust_factor) || + stgs->acceleration_trust_factor <= 0) { + free_py_scs_data(d, k, stgs, &ps); + return finish_with_error( + "acceleration_trust_factor must be positive (math.inf for no cap, " + "the default)"); + } if (!isfinite((double)stgs->scale) || stgs->scale <= 0) { free_py_scs_data(d, k, stgs, &ps); return finish_with_error("scale must be a positive finite number"); diff --git a/scs_source b/scs_source index 0600ef3..f77786e 160000 --- a/scs_source +++ b/scs_source @@ -1 +1 @@ -Subproject commit 0600ef36307a2c038a790f3c9560b197fd3edc7a +Subproject commit f77786e1cdddd4c14c7e795951e1742dc2515963 diff --git a/test/test_scs_coverage.py b/test/test_scs_coverage.py index b14f3f0..d837a56 100644 --- a/test/test_scs_coverage.py +++ b/test/test_scs_coverage.py @@ -2779,6 +2779,32 @@ def test_acceleration_regularization_zero_allowed(): assert sol["info"]["status"] in ("solved", "solved_inaccurate") +def test_acceleration_trust_factor_default_inf(): + """Default acceleration_trust_factor is +inf (no cap, current behavior).""" + solver = scs.SCS(_make_data(), _CONE, verbose=False) + sol = solver.solve() + assert sol["info"]["status"] in ("solved", "solved_inaccurate") + + +@pytest.mark.parametrize("trust_factor", [0.5, 1.0, 2.0, 10.0, float("inf")]) +def test_acceleration_trust_factor_in_range(trust_factor): + """Positive finite values enable trust-region + adaptive r; inf disables.""" + solver = scs.SCS( + _make_data(), _CONE, + acceleration_trust_factor=trust_factor, + verbose=False, + ) + sol = solver.solve() + assert sol["info"]["status"] in ("solved", "solved_inaccurate") + + +@pytest.mark.parametrize("bad", [-1.0, 0.0, float("nan")]) +def test_acceleration_trust_factor_invalid_rejected(bad): + with pytest.raises(ValueError, match="acceleration_trust_factor"): + scs.SCS(_make_data(), _CONE, + acceleration_trust_factor=bad, verbose=False) + + # =========================================================================== # 73. Power cone with different exponents # =========================================================================== From 0fa6c92f586a4047b98782b9da320bcff77bdcb7 Mon Sep 17 00:00:00 2001 From: Brendan O'Donoghue Date: Fri, 5 Jun 2026 11:48:51 +0100 Subject: [PATCH 2/2] Bump scs_source to pick up rw.c fread warning fix Pulls in the cvxgrp/scs PR #396 fix that silences a gcc -Wunused-result warning on the EOF-tolerant fread for acceleration_trust_factor. --- scs_source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scs_source b/scs_source index f77786e..a8deb1b 160000 --- a/scs_source +++ b/scs_source @@ -1 +1 @@ -Subproject commit f77786e1cdddd4c14c7e795951e1742dc2515963 +Subproject commit a8deb1b13f0802ad623da70f5137e240dcc66cf2