When using the solver.update interface in the Python wrapper to modify the constraint vector b, providing np.inf (commonly used to represent inactive constraints) causes the solver to fail with a NumericalError. The solver log shows NaN values and an immediate termination.
The following code demonstrates that the initial solve works (using a large finite number 1e8), but updating the same constraint to np.inf triggers the error.
import clarabel
import numpy as np
from scipy import sparse
# Define problem data
P = sparse.csc_matrix([[6., 0.], [0., 4.]])
P = sparse.triu(P).tocsc()
q = np.array([-1., -4.])
A = sparse.csc_matrix(
[[1., -2.], # <-- LHS of equality constraint (lower bound)
[1., 0.], # <-- LHS of inequality constraint (upper bound)
[0., 1.], # <-- LHS of inequality constraint (upper bound)
[-1., 0.], # <-- LHS of inequality constraint (lower bound)
[0., -1.]]) # <-- LHS of inequality constraint (lower bound)
b = np.array([0., 1e8, 1., 1., 1.])
cones = [clarabel.ZeroConeT(1), clarabel.NonnegativeConeT(4)]
settings = clarabel.DefaultSettings()
settings.presolve_enable = False
solver = clarabel.DefaultSolver(P, q, A, b, cones, settings)
solver.solve()
# complete vector data overwrite
qnew = np.array([0., 0.])
bnew = np.array([0., np.inf, 1., 1., 1.]) # use np.inf for inactive constraints
# complete matrix data overwrite
Pnew = sparse.csc_matrix([[3., 0.], [0., 4.]]).tocsc()
# complete matrix data update (vector of nonzero values)
# NB: tuple of partial updates also works
Anew = A.data.copy()
Anew[1] = 2.
solver.update(q=qnew, P=Pnew, b=bnew, A=Anew)
solver.solve()
Running Results:
-------------------------------------------------------------
Clarabel.rs v0.11.1 - Clever Acronym
(c) Paul Goulart
University of Oxford, 2022
-------------------------------------------------------------
problem:
variables = 2
constraints = 5
nnz(P) = 2
nnz(A) = 6
cones (total) = 2
: Zero = 1, numel = 1
: Nonnegative = 1, numel = 4
settings:
linear algebra: direct / qdldl, precision: 64 bit (1 thread)
max iter = 200, time limit = Inf, max step = 0.990
tol_feas = 1.0e-8, tol_gap_abs = 1.0e-8, tol_gap_rel = 1.0e-8,
static reg : on, ϵ1 = 1.0e-8, ϵ2 = 4.9e-32
dynamic reg: on, ϵ = 1.0e-13, δ = 2.0e-7
iter refine: on, reltol = 1.0e-13, abstol = 1.0e-12,
max iter = 10, stop ratio = 5.0
equilibrate: on, min_scale = 1.0e-4, max_scale = 1.0e4
max iter = 10
iter pcost dcost gap pres dres k/t μ step
---------------------------------------------------------------------------------------------
0 +2.6906e+15 -2.9187e+15 2.08e+00 1.43e-01 7.64e-17 1.00e+00 2.23e+15 ------
1 +2.1705e+14 -3.0214e+15 1.49e+01 5.56e-02 1.29e-16 6.09e+14 1.13e+14 9.90e-01
2 +3.1665e+10 -3.1417e+14 9.92e+03 7.04e-04 6.28e-17 7.00e+13 1.62e+12 9.90e-01
3 +3.1748e+06 -3.1880e+12 1.00e+06 7.05e-06 3.64e-17 7.08e+11 1.63e+10 9.90e-01
4 +5.8479e+02 -4.4676e+10 7.64e+07 8.89e-08 5.70e-17 7.04e+09 2.06e+08 9.87e-01
5 +7.8385e+00 -8.0535e+09 1.03e+09 1.07e-08 2.88e-18 7.97e+07 3.51e+07 8.14e-01
6 -1.1486e+00 -8.3085e+08 7.23e+08 4.41e-09 1.44e-16 1.73e+08 3.98e+07 6.64e-01
7 -7.6736e-01 -2.7655e+07 2.77e+07 1.89e-09 1.44e-14 7.12e+06 1.25e+06 9.83e-01
8 +1.4360e+00 -1.0356e+06 7.21e+05 5.16e-11 3.20e-15 7.66e+04 3.32e+04 9.87e-01
9 +1.5151e+00 -1.0414e+04 6.87e+03 5.28e-13 2.53e-14 7.71e+02 3.33e+02 9.90e-01
10 +1.5028e+00 -1.1831e+02 7.97e+01 8.55e-14 2.37e-12 8.87e+00 3.83e+00 9.88e-01
11 +6.5558e-01 -1.1743e+01 1.24e+01 9.51e-15 1.34e-09 9.11e-01 3.95e-01 8.99e-01
12 -6.0976e-01 -2.7666e+00 2.16e+00 4.87e-16 7.36e-09 1.53e-01 5.57e-02 9.90e-01
13 -6.4281e-01 -7.1831e-01 7.55e-02 1.19e-17 1.34e-09 4.99e-03 1.85e-03 9.90e-01
14 -6.4286e-01 -6.4370e-01 8.41e-04 3.94e-19 6.44e-11 5.56e-05 2.05e-05 9.90e-01
15 -6.4286e-01 -6.4287e-01 8.42e-06 7.04e-21 1.22e-12 5.57e-07 2.06e-07 9.90e-01
16 -6.4286e-01 -6.4286e-01 8.42e-08 9.04e-17 1.92e-14 5.57e-09 2.06e-09 9.90e-01
17 -6.4286e-01 -6.4286e-01 8.42e-10 1.81e-16 1.06e-15 5.57e-11 2.06e-11 9.90e-01
---------------------------------------------------------------------------------------------
Terminated with status = Solved
solve time = 129.7µs
-------------------------------------------------------------
Clarabel.rs v0.11.1 - Clever Acronym
(c) Paul Goulart
University of Oxford, 2022
-------------------------------------------------------------
problem:
variables = 2
constraints = 5
nnz(P) = 2
nnz(A) = 6
cones (total) = 2
: Zero = 1, numel = 1
: Nonnegative = 1, numel = 4
settings:
linear algebra: direct / qdldl, precision: 64 bit (1 thread)
max iter = 200, time limit = Inf, max step = 0.990
tol_feas = 1.0e-8, tol_gap_abs = 1.0e-8, tol_gap_rel = 1.0e-8,
static reg : on, ϵ1 = 1.0e-8, ϵ2 = 4.9e-32
dynamic reg: on, ϵ = 1.0e-13, δ = 2.0e-7
iter refine: on, reltol = 1.0e-13, abstol = 1.0e-12,
max iter = 10, stop ratio = 5.0
equilibrate: on, min_scale = 1.0e-4, max_scale = 1.0e4
max iter = 10
iter pcost dcost gap pres dres k/t μ step
---------------------------------------------------------------------------------------------
0 +1.3410e-01 -inf inf NaN 7.92e-01 1.00e+00 1.00e+00 ------
1 +1.3410e-01 -inf inf NaN 7.92e-01 1.00e+00 1.00e+00 0.00e+00
---------------------------------------------------------------------------------------------
Terminated with status = NumericalError
solve time = 63.9µs
When using the solver.update interface in the Python wrapper to modify the constraint vector b, providing np.inf (commonly used to represent inactive constraints) causes the solver to fail with a NumericalError. The solver log shows NaN values and an immediate termination.
The following code demonstrates that the initial solve works (using a large finite number 1e8), but updating the same constraint to np.inf triggers the error.
Running Results: