예제 #1
0
    def test_primal_and_dual_infeasible_problem(self):

        self.n = 2
        self.m = 4
        self.P = sparse.csc_matrix((2, 2))
        self.q = np.array([-1., -1.])
        self.A = sparse.csc_matrix([[1., -1.], [-1., 1.], [1., 0.], [0., 1.]])
        self.l = np.array([1., 1., 0., 0.])
        self.u = np.inf * np.ones(self.m)

        self.model = osqp.OSQP()
        self.model.setup(P=self.P,
                         q=self.q,
                         A=self.A,
                         l=self.l,
                         u=self.u,
                         **self.opts)

        # Warm start to avoid infeasibility detection at first step
        x0 = 25. * np.ones(self.n)
        y0 = -2. * np.ones(self.m)
        self.model.warm_start(x=x0, y=y0)

        # Solve
        res = self.model.solve()

        # Assert close
        self.assertIn(res.info.status_val, [
            constant('OSQP_PRIMAL_INFEASIBLE'),
            constant('OSQP_DUAL_INFEASIBLE')
        ])
예제 #2
0
    def test_primal_and_dual_infeasible_problem(self):

        self.n = 2
        self.m = 4
        self.P = sparse.csc_matrix((2, 2))
        self.q = np.array([-1., -1.])
        self.A = sparse.csc_matrix([[1., -1.], [-1., 1.], [1., 0.], [0., 1.]])
        self.l = np.array([1., 1., 0., 0.])
        self.u = np.inf * np.ones(self.m)

        self.model = osqp.OSQP()
        self.model.setup(P=self.P,
                         q=self.q,
                         A=self.A,
                         l=self.l,
                         u=self.u,
                         **self.opts)

        res = self.model.solve()

        # Assert close
        self.assertIn(res.info.status_val, [
            constant('OSQP_PRIMAL_INFEASIBLE'),
            constant('OSQP_DUAL_INFEASIBLE')
        ])
예제 #3
0
파일: utils.py 프로젝트: yidong72/cuosqp
def linsys_solver_str_to_int(settings):
        linsys_solver_str = settings.pop('linsys_solver', '')
        if not isinstance(linsys_solver_str, str):
            raise TypeError("Setting linsys_solver " +
                            "is required to be a string.")
        linsys_solver_str = linsys_solver_str.lower()
        if linsys_solver_str == 'cuda pcg':
            settings['linsys_solver'] = _osqp.constant('CUDA_PCG_SOLVER')
        # Default solver: CUDA PCG
        elif linsys_solver_str == '':
            settings['linsys_solver'] = _osqp.constant('CUDA_PCG_SOLVER')
        else:   # default solver: CUDA PCG
            warn("Linear system solver not recognized. " +
                 "Using default solver CUDA PCG.")
            settings['linsys_solver'] = _osqp.constant('CUDA_PCG_SOLVER')
        return settings
예제 #4
0
  def test_primal_infeasible_problem(self):
    # Set random seed for reproducibility
    rg = Generator(PCG64(1))

    self.n = 50
    self.m = 500

    # Generate random Matrices
    Pt = sparse.random(self.n, self.n, random_state=rg)
    self.P = sparse.triu(Pt.T.dot(Pt), format='csc')
    self.q = rg.standard_normal(self.n)
    self.A = sparse.random(self.m, self.n, random_state=rg).tolil()  # Lil for efficiency
    self.u = 3 + rg.standard_normal(self.m)
    self.l = -3 + rg.standard_normal(self.m)

    # Make random problem primal infeasible
    self.A[int(self.n/2), :] = self.A[int(self.n/2)+1, :]
    self.l[int(self.n/2)] = self.u[int(self.n/2)+1] + 10 * rg.random()
    self.u[int(self.n/2)] = self.l[int(self.n/2)] + 0.5

    # Convert A to csc
    self.A = self.A.tocsc()

    self.model = osqp.OSQP()
    self.model.setup(self.P, self.q, self.A, self.l, self.u, **self.opts)

    # Solve problem with OSQP
    res = self.model.solve()

    # Assert close
    self.assertEqual(res.info.status_val, constant('OSQP_PRIMAL_INFEASIBLE'))
예제 #5
0
    def test_non_convex(self):
        # Setup workspace with new sigma
        opts = {'verbose': False, 'sigma': 5}
        self.model.setup(P=self.P, q=self.q, A=self.A, l=self.l, u=self.u, **opts)

        # Solve problem
        res = self.model.solve()

        # Assert close
        self.assertEqual(res.info.status_val, constant('OSQP_NON_CVX'))
        nptest.assert_approx_equal(res.info.obj_val, np.nan)
예제 #6
0
    def test_dual_infeasible_qp(self):

        # Dual infeasible example
        self.P = sparse.diags([4., 0.], format='csc')
        self.q = np.array([0, 2])
        self.A = sparse.csc_matrix([[1., 1.], [-1., 1.]])
        self.l = np.array([-np.inf, -np.inf])
        self.u = np.array([2., 3.])

        self.model = osqp.OSQP()
        self.model.setup(P=self.P,
                         q=self.q,
                         A=self.A,
                         l=self.l,
                         u=self.u,
                         **self.opts)

        # Solve problem with OSQP
        res = self.model.solve()

        # Assert close
        self.assertEqual(res.info.status_val, constant('OSQP_DUAL_INFEASIBLE'))
예제 #7
0
    def test_dual_infeasible_lp(self):

        # Dual infeasible example
        self.P = sparse.csc_matrix((2, 2))
        self.q = np.array([2, -1])
        self.A = sparse.eye(2, format='csc')
        self.l = np.array([0., 0.])
        self.u = np.array([np.inf, np.inf])

        self.model = osqp.OSQP()
        self.model.setup(P=self.P,
                         q=self.q,
                         A=self.A,
                         l=self.l,
                         u=self.u,
                         **self.opts)

        # Solve problem with OSQP
        res = self.model.solve()

        # Assert close
        self.assertEqual(res.info.status_val, constant('OSQP_DUAL_INFEASIBLE'))
예제 #8
0
    def test_primal_infeasible_problem(self):

        # Simple QP problem
        sp.random.seed(4)

        self.n = 50
        self.m = 500
        # Generate random Matrices
        Pt = sparse.random(self.n, self.n)
        self.P = sparse.triu(Pt.T.dot(Pt), format='csc')
        self.q = sp.randn(self.n)
        self.A = sparse.random(self.m, self.n).tolil()  # Lil for efficiency
        self.u = 3 + sp.randn(self.m)
        self.l = -3 + sp.randn(self.m)

        # Make random problem primal infeasible
        self.A[int(self.n / 2), :] = self.A[int(self.n / 2) + 1, :]
        self.l[int(self.n / 2)] = self.u[int(self.n / 2) + 1] + 10 * sp.rand()
        self.u[int(self.n / 2)] = self.l[int(self.n / 2)] + 0.5

        # Convert A to csc
        self.A = self.A.tocsc()

        self.model = osqp.OSQP()
        self.model.setup(P=self.P,
                         q=self.q,
                         A=self.A,
                         l=self.l,
                         u=self.u,
                         **self.opts)

        # Solve problem with OSQP
        res = self.model.solve()

        # Assert close
        self.assertEqual(res.info.status_val,
                         constant('OSQP_PRIMAL_INFEASIBLE'))
예제 #9
0
파일: utils.py 프로젝트: yidong72/cuosqp
def prepare_data(P=None, q=None, A=None, l=None, u=None, **settings):
        """
        Prepare problem data of the form

        minimize     1/2 x' * P * x + q' * x
        subject to   l <= A * x <= u

        solver settings can be specified as additional keyword arguments
        """

        #
        # Get problem dimensions
        #

        if P is None:
            if q is not None:
                n = len(q)
            elif A is not None:
                n = A.shape[1]
            else:
                raise ValueError("The problem does not have any variables")
        else:
            n = P.shape[0]
        if A is None:
            m = 0
        else:
            m = A.shape[0]

        #
        # Create parameters if they are None
        #

        if (A is None and (l is not None or u is not None)) or \
                (A is not None and (l is None and u is None)):
            raise ValueError("A must be supplied together " +
                             "with at least one bound l or u")

        # Add infinity bounds in case they are not specified
        if A is not None and l is None:
            l = -np.inf * np.ones(A.shape[0])
        if A is not None and u is None:
            u = np.inf * np.ones(A.shape[0])

        # Create elements if they are not specified
        if P is None:
            P = sparse.csc_matrix((np.zeros((0,), dtype=np.double),
                                   np.zeros((0,), dtype=np.int),
                                   np.zeros((n+1,), dtype=np.int)),
                                  shape=(n, n))
        if q is None:
            q = np.zeros(n)

        if A is None:
            A = sparse.csc_matrix((np.zeros((0,), dtype=np.double),
                                   np.zeros((0,), dtype=np.int),
                                   np.zeros((n+1,), dtype=np.int)),
                                  shape=(m, n))
            l = np.zeros(A.shape[0])
            u = np.zeros(A.shape[0])

        #
        # Check vector dimensions (not checked from C solver)
        #

        # Check if second dimension of A is correct
        # if A.shape[1] != n:
        #     raise ValueError("Dimension n in A and P does not match")
        if len(q) != n:
            raise ValueError("Incorrect dimension of q")
        if len(l) != m:
            raise ValueError("Incorrect dimension of l")
        if len(u) != m:
            raise ValueError("Incorrect dimension of u")

        #
        # Check or Sparsify Matrices
        #
        if not sparse.issparse(P) and isinstance(P, np.ndarray) and \
                len(P.shape) == 2:
            raise TypeError("P is required to be a sparse matrix")
        if not sparse.issparse(A) and isinstance(A, np.ndarray) and \
                len(A.shape) == 2:
            raise TypeError("A is required to be a sparse matrix")

        # If P is not triu, then convert it to triu
        if sparse.tril(P, -1).data.size > 0:
            P = sparse.triu(P, format='csc')

        # Convert matrices in CSC form and to individual pointers
        if not sparse.isspmatrix_csc(P):
            warn("Converting sparse P to a CSC " +
                 "(compressed sparse column) matrix. (It may take a while...)")
            P = P.tocsc()
        if not sparse.isspmatrix_csc(A):
            warn("Converting sparse A to a CSC " +
                 "(compressed sparse column) matrix. (It may take a while...)")
            A = A.tocsc()

        # Check if P an A have sorted indices
        if not P.has_sorted_indices:
            P.sort_indices()
        if not A.has_sorted_indices:
            A.sort_indices()

        # Convert infinity values to OSQP Infinity
        u = np.minimum(u, _osqp.constant('OSQP_INFTY'))
        l = np.maximum(l, -_osqp.constant('OSQP_INFTY'))

        # Convert linsys_solver string to integer
        settings = linsys_solver_str_to_int(settings)

        return ((n, m), P.data, P.indices, P.indptr, q,
                A.data, A.indices, A.indptr,
                l, u), settings
예제 #10
0
    def update(self,
               q=None,
               l=None,
               u=None,
               Px=None,
               Px_idx=np.array([]),
               Ax=None,
               Ax_idx=np.array([])):
        """
        Update OSQP problem arguments
        """

        # get problem dimensions
        (n, m) = self._model.dimensions()

        # check consistency of the input arguments
        if q is not None and len(q) != n:
            raise ValueError("q must have length n")
        if l is not None:
            if not isinstance(l, np.ndarray):
                raise TypeError("l must be numpy.ndarray, not %s" %
                                type(l).__name__)
            elif len(l) != m:
                raise ValueError("l must have length m")
            # Convert values to -OSQP_INFTY
            l = np.maximum(l, -_osqp.constant('OSQP_INFTY'))
        if u is not None:
            if not isinstance(u, np.ndarray):
                raise TypeError("u must be numpy.ndarray, not %s" %
                                type(u).__name__)
            elif len(u) != m:
                raise ValueError("u must have length m")
            # Convert values to OSQP_INFTY
            u = np.minimum(u, _osqp.constant('OSQP_INFTY'))
        if Ax is None:
            if len(Ax_idx) > 0:
                raise ValueError("Vector Ax has not been specified")
        else:
            if len(Ax_idx) > 0 and len(Ax) != len(Ax_idx):
                raise ValueError("Ax and Ax_idx must have the same lengths")
        if Px is None:
            if len(Px_idx) > 0:
                raise ValueError("Vector Px has not been specified")
        else:
            if len(Px_idx) > 0 and len(Px) != len(Px_idx):
                raise ValueError("Px and Px_idx must have the same lengths")
        if q is None and l is None and u is None and Px is None and Ax is None:
            raise ValueError("No updatable data has been specified")

        # update linear cost
        if q is not None:
            self._model.update_lin_cost(q)

        # update lower bound
        if l is not None and u is None:
            self._model.update_bounds(l, np.array([]))

        # update upper bound
        if u is not None and l is None:
            self._model.update_bounds(np.array([]), u)

        # update bounds
        if l is not None and u is not None:
            self._model.update_bounds(l, u)

        # update matrix P
        if Px is not None and Ax is None:
            self._model.update_P(Px, Px_idx, len(Px))

        # update matrix A
        if Ax is not None and Px is None:
            self._model.update_A(Ax, Ax_idx, len(Ax))

        # update matrices P and A
        if Px is not None and Ax is not None:
            self._model.update_P_A(Px, Px_idx, len(Px), Ax, Ax_idx, len(Ax))