Skip to content

Commit 5da2875

Browse files
committed
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.
1 parent 2c4cfc9 commit 5da2875

3 files changed

Lines changed: 43 additions & 5 deletions

File tree

scs/scsobject.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,7 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
490490
"acceleration_type_1",
491491
"acceleration_regularization",
492492
"acceleration_relaxation",
493+
"acceleration_trust_factor",
493494
"write_data_filename",
494495
"log_csv_filename",
495496
NULL};
@@ -499,15 +500,15 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
499500
on Windows where sizeof(long) < sizeof(long long) (LLP64 model). */
500501
#ifdef DLONG
501502
#ifdef SFLOAT
502-
char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LfffffffLLLffzz";
503+
char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LfffffffLLLfffzz";
503504
#else
504-
char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LdddddddLLLddzz";
505+
char *argparse_string = "(LL)O!O!O!OOOO!O!O!|O!O!O!LdddddddLLLdddzz";
505506
#endif
506507
#else
507508
#ifdef SFLOAT
508-
char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!ifffffffiiiffzz";
509+
char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!ifffffffiiifffzz";
509510
#else
510-
char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!idddddddiiiddzz";
511+
char *argparse_string = "(ii)O!O!O!OOOO!O!O!|O!O!O!idddddddiiidddzz";
511512
#endif
512513
#endif
513514

@@ -547,6 +548,7 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
547548
&(stgs->acceleration_type_1),
548549
&(stgs->acceleration_regularization),
549550
&(stgs->acceleration_relaxation),
551+
&(stgs->acceleration_trust_factor),
550552
&(stgs->write_data_filename),
551553
&(stgs->log_csv_filename))) {
552554
/* PyArg_ParseTupleAndKeywords already set an informative TypeError
@@ -835,6 +837,16 @@ static int SCS_init(SCS *self, PyObject *args, PyObject *kwargs) {
835837
free_py_scs_data(d, k, stgs, &ps);
836838
return finish_with_error("acceleration_relaxation must be in [0, 2]");
837839
}
840+
/* acceleration_trust_factor: INFINITY (default) disables; positive
841+
* finite values turn on the trust-region + adaptive-r mode in aa.
842+
* NaN and non-positive values are rejected. */
843+
if (isnan((double)stgs->acceleration_trust_factor) ||
844+
stgs->acceleration_trust_factor <= 0) {
845+
free_py_scs_data(d, k, stgs, &ps);
846+
return finish_with_error(
847+
"acceleration_trust_factor must be positive (math.inf for no cap, "
848+
"the default)");
849+
}
838850
if (!isfinite((double)stgs->scale) || stgs->scale <= 0) {
839851
free_py_scs_data(d, k, stgs, &ps);
840852
return finish_with_error("scale must be a positive finite number");

test/test_scs_coverage.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2779,6 +2779,32 @@ def test_acceleration_regularization_zero_allowed():
27792779
assert sol["info"]["status"] in ("solved", "solved_inaccurate")
27802780

27812781

2782+
def test_acceleration_trust_factor_default_inf():
2783+
"""Default acceleration_trust_factor is +inf (no cap, current behavior)."""
2784+
solver = scs.SCS(_make_data(), _CONE, verbose=False)
2785+
sol = solver.solve()
2786+
assert sol["info"]["status"] in ("solved", "solved_inaccurate")
2787+
2788+
2789+
@pytest.mark.parametrize("trust_factor", [0.5, 1.0, 2.0, 10.0, float("inf")])
2790+
def test_acceleration_trust_factor_in_range(trust_factor):
2791+
"""Positive finite values enable trust-region + adaptive r; inf disables."""
2792+
solver = scs.SCS(
2793+
_make_data(), _CONE,
2794+
acceleration_trust_factor=trust_factor,
2795+
verbose=False,
2796+
)
2797+
sol = solver.solve()
2798+
assert sol["info"]["status"] in ("solved", "solved_inaccurate")
2799+
2800+
2801+
@pytest.mark.parametrize("bad", [-1.0, 0.0, float("nan")])
2802+
def test_acceleration_trust_factor_invalid_rejected(bad):
2803+
with pytest.raises(ValueError, match="acceleration_trust_factor"):
2804+
scs.SCS(_make_data(), _CONE,
2805+
acceleration_trust_factor=bad, verbose=False)
2806+
2807+
27822808
# ===========================================================================
27832809
# 73. Power cone with different exponents
27842810
# ===========================================================================

0 commit comments

Comments
 (0)