MOSEK can solve quadratic and quadratically constrained problems, as long as they are convex. This class of problems can be formulated as follows:

(6.28)$\begin{split}\begin{array}{lrcccll} \mbox{minimize} & & & \half x^T Q^o x + c^T x + c^f & & & \\ \mbox{subject to} & l_k^c & \leq & \half x^T Q^k x + \sum_{j=0}^{n-1} a_{k,j} x_j & \leq & u_k^c, & k =0,\ldots ,m-1, \\ & l_j^x & \leq & x_j & \leq & u_j^x, & j=0,\ldots ,n-1. \end{array}\end{split}$

Without loss of generality it is assumed that $$Q^o$$ and $$Q^k$$ are all symmetric because

$x^T Q x = \half x^T(Q+Q^T)x.$

This implies that a non-symmetric $$Q$$ can be replaced by the symmetric matrix $$\half(Q+Q^T)$$.

The problem is required to be convex. More precisely, the matrix $$Q^o$$ must be positive semi-definite and the $$k$$th constraint must be of the form

(6.29)$l_k^c \leq \half x^T Q^k x + \sum_{j=0}^{n-1} a_{k,j} x_j$

with a negative semi-definite $$Q^k$$ or of the form

$\half x^T Q^k x + \sum_{j=0}^{n-1} a_{k,j} x_j \leq u_k^c.$

with a positive semi-definite $$Q^k$$. This implies that quadratic equalities are not allowed. Specifying a non-convex problem will result in an error when the optimizer is called.

A matrix is positive semidefinite if all the eigenvalues of $$Q$$ are nonnegative. An alternative statement of the positive semidefinite requirement is

$x^T Q x \geq 0, \quad \forall x.$

If the convexity (i.e. semidefiniteness) conditions are not met MOSEK will not produce reliable results or work at all.

We look at a small problem with linear constraints and quadratic objective:

(6.30)$\begin{split}\begin{array}{lll} \mbox{minimize} & & x_1^2 + 0.1 x_2^2 + x_3^2 - x_1 x_3 - x_2 \\ \mbox{subject to} & 1 \leq & x_1 + x_2 + x_3 \\ & 0 \leq & x. \end{array}\end{split}$

The matrix formulation of (6.30) has:

$\begin{split}Q^o = \left[ \begin{array}{ccc} 2 & 0 & -1\\ 0 & 0.2 & 0\\ -1 & 0 & 2 \end{array} \right], c = \left[ \begin{array}c 0\\ -1\\ 0 \end{array} \right], A = \left[ \begin{array} {ccc} 1 & 1 & 1 \end{array} \right],\end{split}$

with the bounds:

$\begin{split}l^c = 1, u^c = \infty , l^x = \left[ \begin{array}c 0 \\ 0 \\ 0 \end{array} \right] \mbox{ and } u^x = \left[ \begin{array} c \infty \\ \infty \\ \infty \end{array} \right]\end{split}$

Please note the explicit $$\half$$ in the objective function of (6.28) which implies that diagonal elements must be doubled in $$Q$$, i.e. $$Q_{11}=2$$ even though $$1$$ is the coefficient in front of $$x_1^2$$ in (6.30).

Setting up the linear part

The linear parts (constraints, variables, objective) are set up using exactly the same methods as for linear problems, and we refer to Sec. 6.1 (Linear Optimization) for all the details. The same applies to technical aspects such as defining an optimization task, retrieving the solution and so on.

The quadratic objective is specified in a list called qobj containing the numerical vectors i, j and v. These vectors specify the (row,column,value)-entries for the lower triangular part of the matrix $$Q^o$$ using an unordered sparse triplet format. In case of example (6.30) we get:

    prob$qobj$i <- c(1,  3,   2,  3)
prob$qobj$j <- c(1,  1,   2,  3)
prob$qobj$v <- c(2, -1, 0.2,  2)


• only non-zero elements are specified (any element not specified is 0 by definition),

• the order of the non-zero elements is insignificant, and

• only the lower triangular part should be specified.

Source code

Listing 6.15 Script implementing problem (6.30) Click here to download.
##
#
#  File :      qo1.R
#
#  Purpose :   To demonstrate how to solve a small quadratic
#              optimization problem using the Rmosek package.
##
library("Rmosek")

qo1 <- function()
{
# Specify the non-quadratic part of the problem.
prob <- list(sense="min")
prob$c <- c(0, -1, 0) prob$A <- Matrix(c(1, 1, 1), nrow=1, sparse=TRUE)
prob$bc <- rbind(blc=1, buc=Inf) prob$bx <- rbind(blx=rep(0,3),
bux=rep(Inf,3))

# Specify the quadratic objective matrix in triplet form.
prob$qobj$i <- c(1,  3,   2,  3)
prob$qobj$j <- c(1,  1,   2,  3)
prob$qobj$v <- c(2, -1, 0.2,  2)

# Solve the problem
r <- mosek(prob)

# Return the solution
stopifnot(identical(r$response$code, 0))
r\$sol
}

qo1()