What is the simplest method to solve an inequality-constrained convex quadratic program?

973 Views Asked by At

I am going to create a simple QP-solver in C programming language to solve the following inequality-constrained convex quadratic program

$$\text{minimize} \quad\frac{1}{2}x^TQx + c^Tx $$

subject to:

$$lb \leq x \leq ub$$

$$A_{lb} \leq Ax \leq A_{ub}$$

Or, if that is not possible, I could accept at least

$$lb \leq x \leq ub$$

$$Ax \leq b$$

What algorithm do you recommend for me?


Example: If I want to subject my objective function to $Ax = b$. Then I would choose this solution. Very simple solution that requires solving a linear system only.

Here $Q$, $A$, $c$ and $b$ are known and we want to find $x$ and we don't care about $\lambda$

enter image description here


Edit:

What do you think about solving the KKT equation with Conjugate Gradient Method? Example:

Let's say that our objective function is:

$$\text{min x} = \frac{1}{2}x^TQx + c^Tx $$

And it subject to: $$lb \leq x \leq ub$$ $$A_{lb} \leq Ax \leq A_{ub}$$

By solving the KKT equation by Conjugate gradient method

$$\begin{bmatrix} Q & A^T \\ A & 0 \end{bmatrix} \begin{bmatrix} x\\ \lambda \end{bmatrix} = \begin{bmatrix} -c\\ A_{ub} \end{bmatrix}$$

I can iterate the process by:

  • Step 1: Get initial $x$ vector
  • Step 2: Find $x$ by solving KKT-equation with one iteration.

    function x = conjgrad(A, b, x, Q, c)
    minx0 = 1/2*x'*Q*x + c'T*x;
    r = b - A * x;
    p = r;
    rsold = r' * r;
    
    for i = 1:length(b)
        Ap = A * p;
        alpha = rsold / (p' * Ap);
        x = x + alpha * p;
    
        // Implement constraints here for x vector
        for-loop and if-statements....for x
    
        // Implement the subjective function here
        minx = 1/2*x'*Q*x + c'T*x;
        if(minx < minx0)
            // Continue to minimize
            r = r - alpha * Ap;
            rsnew = r' * r;
            if sqrt(rsnew) < 1e-10
                 break;
            end
            p = r + (rsnew / rsold) * p;
            rsold = rsnew;
        end
    end
    end
    

What do you think about this?