[Python] Using Clarabel as a backend of CVXPY

Discussão em 'Python' iniciado por Stack, Setembro 26, 2024.

  1. Stack

    Stack Membro Participativo

    Is this a bug, or is there something fundamental I'm missing with how to use cvxpy?

    Consider this code for a least squares optimisation for a 3 variable vector with 3 measurements:

    import scipy
    import numpy as np
    import cvxpy as cvx
    import clarabel

    A = np.array([[-43.83695965, 0.34990409, -1.32935518],
    [-48.86811152, 0.57411847, -1.38219424],
    [-49.25621142, 0.75738835, -1.2979702 ]])

    b = np.array([ 53897.91898074, -159390.11128713, -62013.59835614])

    bounds_arr = np.array([[-1., -1., -1.],
    [ 1., 1., 1.]])

    #------- Using CLARABEL as cvxpy backend---------------
    x = cvx.Variable(A.shape[1])
    cost = cvx.sum_squares(A @ x - b)

    constraints = []
    constraints += [xv >= bnd for (xv, bnd) in zip(x, bounds_arr[0])]
    constraints += [xv <= bnd for (xv, bnd) in zip(x, bounds_arr[1])]
    constraints += [x[0] + x[1] + x[2] >= -np.sqrt(3)]
    # constraints += [cvx.sum(x) >= -np.sqrt(3)] # This form doesn't work either

    prob = cvx.Problem(cvx.Minimize(cost), constraints)
    prob.solve(solver="CLARABEL", verbose=True) # Says 'PrimalInfeasible'
    print("x: ", x.value)

    #------- Using CLARABEL directly---------------
    P = A.T @ A
    P = scipy.sparse.triu(P).tocsc()
    q = -b.T @ A
    # Note constant term is ignored in this case because it is irrelevant to the solution of the optimisation problem.

    Ac = scipy.sparse.vstack([-scipy.sparse.identity(A.shape[1]),
    scipy.sparse.identity(A.shape[1]),
    np.array([[-1.0, -1.0, -1.0]])]).tocsc()

    bc = np.concat([-bounds_arr[0], bounds_arr[1], [np.sqrt(3)]], axis=0)

    cones = [clarabel.NonnegativeConeT(A.shape[1]), clarabel.NonnegativeConeT(A.shape[1]), clarabel.NonnegativeConeT(1)]
    settings = clarabel.DefaultSettings()
    solver = clarabel.DefaultSolver(P, q, Ac, bc, cones, settings) #, A, b, cones, settings
    solution = solver.solve() # WORKS
    print("x: ", solution.x)


    Most likely, I'm missing something fundamental with cvxpy - that is, why doesn't both approaches work?

    If not, is this a bug in cvxpy?

    Continue reading...

Compartilhe esta Página