Coverage for lpsolvers / proxqp_.py: 78%
23 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-20 15:19 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-20 15:19 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# SPDX-License-Identifier: LGPL-3.0-or-later
5# Copyright (C) 2016-2022 Stéphane Caron
6# Copyright (C) 2023 Inria
8"""Solver interface for `ProxQP`_.
10.. _ProxQP: https://github.com/Simple-Robotics/proxsuite#proxqp
12ProxQP is the QP solver from ProxSuite, a collection of open-source solvers
13rooted in revisited primal-dual proximal algorithms. If you use ProxQP in some
14academic work, consider citing the corresponding paper [Bambade2022]_.
15"""
17from typing import Optional
19import numpy as np
20from proxsuite import proxqp
23def __select_backend(backend: Optional[str], use_csc: bool):
24 """Select backend function for ProxQP.
26 Parameters
27 ----------
28 backend :
29 ProxQP backend to use in ``[None, "dense", "sparse"]``. If ``None``
30 (default), the backend is selected based on the type of ``P``.
31 use_csc :
32 If ``True``, use sparse matrices if the backend is not specified.
34 Returns
35 -------
36 :
37 Backend solve function.
39 Raises
40 ------
41 ParamError
42 If the required backend is not a valid ProxQP backend.
43 """
44 if backend is None:
45 return proxqp.sparse if use_csc else proxqp.dense
46 if backend == "dense":
47 return proxqp.dense
48 if backend == "sparse":
49 return proxqp.sparse
50 raise ValueError(f'Unknown ProxQP backend "{backend}')
53def proxqp_solve_lp(
54 c: np.ndarray,
55 G: np.ndarray,
56 h: np.ndarray,
57 A: Optional[np.ndarray] = None,
58 b: Optional[np.ndarray] = None,
59 verbose: bool = False,
60 backend: Optional[str] = None,
61 **kwargs,
62) -> np.ndarray:
63 """Solve a quadratic program using ProxQP.
65 Parameters
66 ----------
67 c :
68 Linear cost vector.
69 G :
70 Linear inequality constraint matrix.
71 h :
72 Linear inequality constraint vector.
73 A :
74 Linear equality constraint matrix.
75 b :
76 Linear equality constraint vector.
77 backend :
78 ProxQP backend to use in ``[None, "dense", "sparse"]``. If ``None``
79 (default), the backend is selected based on the type of ``P``.
80 verbose :
81 Set to `True` to print out extra information.
83 Returns
84 -------
85 :
86 Solution to the QP returned by the solver.
88 Notes
89 -----
90 All other keyword arguments are forwarded as solver settings to ProxQP. For
91 instance, you can call ``proxqp_solve_qp(P, q, G, h, eps_abs=1e-6)``. Check
92 out the `solver documentation
93 <https://simple-robotics.github.io/proxsuite/>`__ for details.
94 """
95 use_csc: bool = (G is not None and not isinstance(G, np.ndarray)) or (
96 A is not None and not isinstance(A, np.ndarray)
97 )
98 proxqp_backend = __select_backend(backend, use_csc)
99 problem = proxqp_backend.QP(
100 n=c.shape[0],
101 n_eq=b.shape[0] if b is not None else 0,
102 n_in=h.shape[0] if h is not None else 0,
103 hessian_type=proxqp_backend.HessianType.Zero,
104 )
105 for key, value in kwargs.items():
106 setattr(problem.settings, key, value)
107 problem.settings.verbose = verbose
108 problem.init(None, c, None, None, G, None, h)
109 problem.solve()
110 if problem.results.info.status != proxqp.PROXQP_SOLVED:
111 raise ValueError("Linear program is not feasible")
112 return problem.results.x